* auto root span creation
proof of concept for automatically creating a root span on startup.
the obvious deficiencies are:
- no idea of response values (status code etc)
- does not capture exceptions
* deptrac
* adding LocalRootSpan class
this is based on Java's implementation, https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/v2.3.0/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/LocalRootSpan.java
and adds the ability to identify and locate the "local root span" in a trace. The local root span is the top-level active span which has either
an invalid or remote parent.
It's tracked automatically as part of making a span active, either via `Span::activate()` or `Span::storeInContext()`, and can be retrieved in
a couple of ways, but most easily via `LocalRootSpan::current()`.
* remove redundant local root span check
* move context key to api
* internal
* adding example
* mark LocalRootSpan as experimental
* adding an example of local root span usage
* style, fix broken build
* [WIP] Add instrumentation configuration
* add autoloading for auto-instrumentations using SPI
* allow autoloading and non-autoloading to work
* fix attribute
* experimental config file
* fixing invalid dependencies
- deptrac was rightly complaining that API (indirectly) depended on SDK through config/sdk. For now,
remove usage of Config\SDK\Configuration\Context
- update deptrac config to allow some new dependencies
* dont register hook manager globally or in sdk
* remove unused function, psalm ignore missing extension function
* possibly fixing type-hint
psalm doesn't complain now, so that should be good
* load config files relative to cwd
* fixing hook manager enable/disable + psalm complaints
* fixing 8.1 psalm error
* use context to pass providers to instrumentations
- make "register global" a function of Sdk, but keep the sdk builder's interface intact
- invent an API instrumentation context, similar to the one in config/sdk, to pass providers
to instrumentations
- add an initial test of autoloading from a config file
* adding tests for sdk::registerGlobal
in passing, remove some dead code for handling invalid booleans - config already handles this correctly
* linting
* test coverage for globals
* add opentelemetry extension to developer image and actions
* always register instrumentations via SPI
* register globals initializer for file-config sdk
allow SDK created from config file to coexist with components using globals initializer
* linting
* remove globals init function
* fix phan warning
* simplify hook manager
- drop storage from hook manager: can't guarantee that something else, eg swoole, won't modify storage
- drop context from hook manager: we must lazy-load globals via initializers, because not all instrumentations use SPI (although that may change in future)
- default hook manager to enabled
* add todo to deprecate Registry in future
* autoload instrumentations without config
if no config provided, still try to load them. wrap registration in a try/catch/log
* fixing phan ref, update doc
* remove phan suppress
* fix example
* bump SPI to 0.2.1
* adding late-binding tracer+provider
per review from Nevay, this will allow instrumentations to get things from Globals as late as possible
* adding late binding logger and meter providers
* more late binding test coverage
* tidy
* dont use CoversMethod yet
not available in phpunit 10, so comment out and leave a todo
* kitchen sink, remove unused var
* instrumentation config as a map, per config file spec
* adding general config
* move general config into sdk
* test config caching
* move general instrumentation config to api
* avoid bad version of sebastian/exporter
* bump config yaml files to 0.3
* fix tests
* disable hook manager during file-based init
* cleanup
* support multiple config files in autoloader
* move hook manager enable/disable out of extension hook manager
The most obvious place to do this is in a class named HookManager, which _was_ an
interface for hook managers. Rename existing HookManager to HookManagerInterface,
then re-purpose HookManager for globally enabling/disabling hook managers as well
as determining the disabled status.
* update spi config
---------
Co-authored-by: Tobias Bachert <git@b-privat.de>
note that `messaging.client_id` was renamed to `messaging.client.id`, which causes a conflict in const name.
The recommendation from semconv maintainers is to replace the old value, `messaging.client_id`.
The SDK should log a warning once if there are any dropped span attributes, links, link attributes, events or event attributes.
The SDK should log a warning once if there are any dropped LogRecord attributes.
* run unit tests in random order
running in random order highlights some interference between tests (mostly logging being enabled), and is a requirement for
mutation testing (ie, all tests must pass when executed in a random order).
* adding infection mutation testing
this adds the ability to run infection. It generates a lot of output, which is an exercise for another PR...
* replace assertwell/phpunit-global-state
the package was not compatible with phpunit 11. create out own test Trait, which handles
env vars, as well as general cleanup of the usual suspects of state that our tests mess up
* remove redundant tearDown functions
there's an after annotation on the trait to handle this
* use rector to upgrade tests for phpunit 11
* fixing CoversFunction for namespaced functions
* use FQNs in test attributes
* migrate Clock classes to API
- move Clock* + Util into API
- add a deprecated wrapper for ClockFactory and Util
- remove unused StopWatch* classes
* review feedback
* replace ClockFactory with Clock
It's not really a factory, and really only provides access to a system clock. Create a
Clock class which is more clear in its purpose.
* remove time Util class
per review feedback, it's only used in Zipkin. Removed some unused consts from ClockInterface
* Apply suggestions from code review
Co-authored-by: Tobias Bachert <git@b-privat.de>
---------
Co-authored-by: Tobias Bachert <git@b-privat.de>
A couple of warnings have popped up recently:
- docker compose 'version' is deprecated
- BSD host id test was running a command that doesn't exist, which was visible in test output (removed test case)
- synchronous metric stream test was triggering a warnings which was visible in test output (changed to use LogsMessagesTrait)
- resource merging with different schema URLs was triggering a warnings from Config test (updated yaml schema_url and documented)
* Improve fiber bound context storage
Now works properly in fibers once initial context is attached.
* Change `Context::storage()` return type to `ContextStorageInterface`
`ExecutionContextAwareInterface` should not be relevant for end-users / it was mainly exposed for the FFI fiber handler; calling any of its method with enabled fiber handler would have broken the storage.
Swoole context storage README creates a new storage instead of wrapping `Context::storage()`: `Context::setStorage(new SwooleContextStorage(new ContextStorage()));`.
* Add BC layer for execution context aware fiber storage
* Fix BC layer inactive execution context detection for {main}
* bump php to 8.1, apply rector
* readonly and typehints
* suppress a dodgy readonly property conversion
* remove some redundant readonly phpdocs
* dont run workflows against 8.0
* more readonly and typehints
* phpdoc reformat
* typehints
* remove php81 polyfill
* revert a rector BC breaking change, and disable that rector for ParentBased
* drop php 7.4 support
update composer.json minimums, and run rector over the code to update what it can. changed some static analysis
config to fix some rector-induced failures.
* adding union typehints
* reformat constructor property promotions
* updating/removing phpdoc
* suppress protobuf extension complaint
submitted a PR upstream to fix phan stubs
* don't validate packages against 7.4
* remove php8 polyfill
* fix readonly comments
* apply trailing commas to multiline fixer
upgrade php-cs-fixer, and apply a new rule for multiline comments
* remove unreachable default match arms for protobuf serializer
* adding more union types to vars
* use weakmap directly
* remove handling for not-supported WeakMap
* spacing
* Add support for multi-instrument callbacks
https://opentelemetry.io/docs/specs/otel/metrics/api/#multiple-instrument-callbacks
* Fix undefined offset on detach of batch callback with repeated instrument
* Unify BatchObservableCallback and ObservableCallback
* Add missing typehint
* Do not bump API dependency
Not required, SDK will continue to work with lower API versions, only `::batchObserve()` won't be usable.
fixing static analysis complaints, most of which were from psalm
when run with --show-info
remove deprecated httplug discovery
static data providers (phpunit10 requirement)
Introduce spec-compliant ResourceInfo::merge, and deprecate our current implementation.
When merging resources, later (updating) keys should override existing keys, per spec.
Reorganise detectors so that environment has highest priority (per spec, OTEL_SERVICE_NAME should be the highest priority built-in way of setting service name)
Adding the experimental telemetry.auto.version attribute, if the auto-instrumentation extension is installed.
* initial work on logs signal
* supressing psalm error
* "fixing" 7.4 segfault
through trial and error, I found that it was consistently segfaulting in the sdk autoloader
tests, but by running them in a different order, the failures went away.
* adding logs tests
* rename example per feedback
* move log context injection into processors, per spec
* correctly set context on logs
* update logger name per feedback
* adding variables, map psr3 to otel severity, fix timestamp
* psr-3 loggers
* tests, psr3 v3 fix
* remove LogRecordDate and refactor SDK log record classes
* tests, tidy, improvements
* remove todos
* documentation
* check for valid span context
* removing psr-3 compatibility, per spec and feedback
* use InstrumentationScopeFactoryInterface
* apply attribute limits on readablelogrecord creation
per feedback, this should be more memory efficient for the processors
* group log record by resource/scope
* remove psr3 references from readme
* ignoring psalm error
* add trace context in Logger rather than processors
per feedback, and following the example in java and python SIGs, we
can add trace context to logs once, in the logger, rather than having
processors do it. The Context passed to processors is no longer used,
but retained for spec compliance.
* fixing some sdk/default resource values
- default service name should contain runtime name if available; java just appends ":java" so I did the same
Co-authored-by: Tobias Bachert <git@b-privat.de>
* adding exporter + transport registry
to remove the hidden dependency between SDK and contrib, move all of the exporter knowledge out of
exporter factory, and invent a registry to hold those values. The registry can be added to by contrib
modules as part of composer autoloading.
This also allows users to override things like transports (eg, provide their own grpc transport).
Remove exporter's fromConnectionString as it's not in spec, and I couldn't get it to work nicely with the
registry idea.
* fixing up examples
* allow callables to be registered as factories
adding an example of replacing a registered transport factory with another implementation
* Registry to FactoryRegistry
* new relic exporter factory, tests
* review suggestions
* tidy
* change fromEnvironment() to create() in factories
* removing event dispatcher
discussed in SIG to remove this unused code. It was going to be infrastructure for emitting metrics from other parts of the code, but that's been done in a better way now.
* remove EventContextIntegrationTest
* Otel-php:632 Move stack trace formatting out of Span class
* added function usages
* fix linting errors
* Added documentation for adding Span Attributes
* removing TracingUtl class
* Refactor TraceState's __toString method
* Added path with @covers to remove warnings
* Added @coversDefaultClass annotation
* fix to check if iterable is empty
* fixed for faling test case
* unit test
* Resolved review Comments
* reverting changes
* removing check for empty iterable span list
* review changes for SpanProcessor incorrect calls to SpanExporter::forceFlush()
* updated test case
* resolved review comments
* reverted changes for batch span processors
* reverting changes for batch span proccessor
* merge upstream and changes
* updating changes
* Refactoring SpanContext
* updating changes
* updated test cases
* updated changes suggested after review
* Revert "Reverting back to previous commit"
This reverts commit 941f368da3.
* updating changes after review
* unused use statement
* added unit test and resolved review comments
* Removed Double underscores from constant variables
* Removed constants from SpanContext.php to remove duplicacy
* updated failing test
* Moving Factory Methods back into SpanContext.php
* modified constructor of SpanContext
* updated SpanContext
* Modified use of additional if statement
* corrected parsing error
* Add metrics implementation
* Apply cs-fixer
* Downgrade to php 7.4
* [TODO] Suppress phan for now
* Add basic example
* [TODO] Remove outdated prometheus example for now
* Add otlp metric converter
* Add metric stream tests
* Downgrade to php 7.4 - fix asynchronous counter instrument type
* Add missing psalm-suppress annotations
* Add `ext-gmp` to composer suggest
* Fix `Sdk` -> `SDK`
* Remove `_bridge.php`
* Add array typehints
* Add `Interface` suffix to interfaces
* Add aggregation / attribute processor / staleness handler tests
* Apply rector
* Simplify filtered attribute processor
* Move instrument deduplication to meter
Allows removing view registry dependency from `MetricFactory`.
Should ideally turn of staleness handling for asynchronous instruments with permanently registered callbacks (drop all `::onStale()` callbacks and prevent addition of new callbacks).
* Allow injecting metric factory
* Release `::onStale()` callbacks if permanent observer callback registered
* Add `MultiObserver` tests
* Add php-doc for exporter temporality
* Resolve phan issues
* Add note about forward compatibility
* Add exemplar tests
* Remove special handling for callbacks being registered multiple times
Was mainly a side-effect of using `spl_object_id()`; lead to inconsistent behavior between providing same and identical callbacks; reverting back to incrementing index, keyspace is large enough.
* Add basic `Meter` / `MeterProvider` tests
* Add view `SelectionCriteria` tests
* Allow `MetricReader`s to configure default aggregation
- move default aggregation handling to metric reader / metric exporter
- move view registration to meter provider constructor
- move exemplar reservoir creation to aggregation to support user implementations
- remove `AttributeProcessor` from view as baggage access was dropped from spec
- deduplicate metric streams
* Add support for weakening `$this` reference of asynchronous callbacks
* Minor improvements
- add missing `Interface` suffix
- move callback destructors to metric observer to not detach if meter and meter provider are out of scope
- simplify `::viewRegistrationRequests()` by readding fallback view
* Add OTLP metric exporter
* Log export failure
* Minor improvements
- rename `MetricObserver::weakMap()` to `::destructors()` to better reflect usage`
- move `ReferenceCounter::acquire()` call to corresponding `MetricObserver::observe()` call for consistency
- cache instrumentation scope id in `Meter` to avoid repeated calls to `serialize()`
- remove obsolete instrument type check from `ViewProjection`, leftover from supporting aggregation per type
* Suppress `PhanAccessMethodInternal` due to being too strict for our usecase
* Add workaround for observer segfault if destruct is initiated by `WeakMap` key going out of scope
* Mark internal classes as internal
* Add in-memory and stream exporter
* Add metric converter test
* Add metric observer tests
* Add view registry tests
* Add metric reader tests
* Improve stream test coverage
* Improve meter test coverage
* Apply rector
* Add delayed staleness handler
* Make `SpanProcessor::onStart()` `$parentContext` non-nullable
* Make `Sampler::shouldSample()` `$attributes` non-nullable
* Don't reset `SpanBuilder::$links` on `::startSpan()`
Not needed / resetting is inconsistent with other span builder values.
* store root dispatcher in a static var
This seems to be the safest way to store the main dispatcher. Using context to store the main event dispatcher causes a scope to be created: activating the newly-created context which stores dispatcher causes a new scope, and that can break things.
I also looked at storing dispatcher in the root context, but that can't work because contexts are immutable.
* remove useless test
* linting
* return no-op span builder after shutdown
this completes a todo in code comments: when tracer shared state has shutdown, getting a span builder should return a no-op implementation
* adding unit test for post-shared-state-shutdown
* adding tests for tracer provider behaviour
a recent bug highlighted that if there is no reference to a tracer provider, then the shared state will shutdown, even if that shared state is being used by active tracers. Adding a phpdoc comment explaining this behavior, and some tests to demonstrate it
* moving tests into integration
* removing accidental covers annotation
* Add attributes to instrumentation scope
* Remove `::getDefaultTracer()`
Instrumentation should use dedicated tracers.
* Remove SDK `::getTracer()` default name
Instrumentation should use API `TracerProvider` which requires providing a name.
* Cleanup `AttributesInterface`
- remove not required methods
- rename `::hasAttribute()` to `::has()` for consistency with `::get()`
* Remove public usage of `new Attributes()`
* Split `Attributes` into immutable attributes and mutable builder
* Remove `AttributesLimits`
* Remove `::incrementDroppedAttributesCount()` for now
Mainly useful for metrics sdk that has to rebuild filtered attributes.
* Remove obsolete cloning of attributes
* Update covers annotation
* Revert optional changes that might be controversial
* Remove `Context::withValue()`
Creates a hidden `Scope` when called without `$parent`.
* Remove `Context::detach(Scope)`
* Remove static `Context::attach()`
* Add missing typehints
* Use loop instead of recursion
* Fix `MultiTextMapPropagator::extract()` clearing context
* Fix `TextMapPropagator::composite()` for named arguments
* Make `Context` constructor non-public
* Make `Context` and `ContextKey` final
* Fix `ArrayAccessGetterSetter`
Resolves inconsistencies in case-insensitive handling.
* Fix psalm
* Fix cannot mock final class `Context`
Revert after introducing ContextInterface?
* Apply feedback and remove obsolete parentheses
* Use psalm-suppress instead of assert
* Remove implicit root scope
* Provide access to active scope and context of scope
* Add local storage to scope
* Trigger fiber error only when crossing fiber boundaries
* Split ContextStorage into two interfaces
* Add swoole context storage
Implementation currently incompatible with fibers.
* Fix cs
* Make default context storage execution context aware
* Add scope bound callable and promise for async user implementations
* Resolve/suppress phan/psalm/phpstan issues
* Improve ContextStorage test coverage
Adds tests for newly added features and fixes covers annotations.
* Apply feedback
- move Swoole context storage to Contrib/Context/Swoole
- use self instead of classname
* updating proto generation
switching over to using opentelemetry-proto's own mechanism for generating protobuf interfaces, and
updating interfaces to latest version
* downgrade protobuf interfaces to 0.14.0
this is the latest version that seems to work with out grpc exporter, further
investigation required for 0.15.0+
* tidy up script
* renaming InstrumentationLibrary to InstrumentationScope and bumping protobuf
InstrumentationLibrary is now deprecated in favour of InstrumentationScope. Making this change
resolves issues with grpc+protobuf exports being ignored by the otel collector, so we now
can update the proto interfaces to latest.
* rename collector docker-compose file