Make the scope id in error messages consistent between the detached-with-error and not-detached cases,
by using spl_object_id($this) in the latter to match the former.
Align with how the spec advises SemConv should be organised, and break unstable
semconvs out into their own directory.
I played around with generating values as enums, but I could only get this to work
if the output was in the same file as the attributes (which would not work well with
composer autoloading), so I've used <attribute>_VALUE_<name>, similar to what we have
now except all in the same file.
* fix linting, broken values containing '.'
* fix incubating namespace
* update semconv readme
* restore ResourceAttributeValues
* adding DNS semconv
* adding db metrics
* fixing psalm complaints
use rector (and psalm) to add Override attributes, and add symfony polyfill to
provide Override in earlier php versions
* fixing more psalm complaints
* more fixes
* adding stubs for deptrac
there are some things in our code that deptrac doesn't understand or are missing
for some php versions. stub them to quieten all those violation warnings
* why not cache invalid :(
* display tools versions
* fix tools cache key
* changing cache key
* dont complain about unused psalm suppressions
* suppress invalid attribute
* quieten phpstan php8.5 complaints
* revert previous commit...now other php versions complain about an unused ignore :(
* revert typecasting in metrics aggregators
* Update src/Contrib/Otlp/ProtobufSerializer.php
Co-authored-by: Chris Lightfoot-Wild <github-clw@wild.me.uk>
* remove override stub and use the polyfill from deptrac
---------
Co-authored-by: Chris Lightfoot-Wild <github-clw@wild.me.uk>
* Move `ComponentProvider` and related classes to API
* Use API `ComponentProvider`
* Use API `ComponentProvider` in tests
* Add `EnvComponentLoader` API
* Add `EnvComponentLoader` example
* Ignore deptrac violations
* Remove namespace from `ComponentProvider` BC layer
* Add API requirement to config package
* Fix/suppress unrelated phpstan errors caused by `google/protobuf` `^4.31`
verified that the bug we experience still exists in xdebug 3.4.4 so lets assume
it will be live for some more releases, and un-skip the test in the future
- update Logger.isEnabled signature to include context and severity number, per spec
- accept event_name on a LogRecord
- add event name to otlp logs payload
- update or remove some comments that were based on the old logs-bridge specification
* implement getAll function in TextMap Extract
* refactor propagation interfaces to introduce ExtendedPropagationGetterInterface
* Refactor getAll method in SanitizeCombinedHeadersPropagationGetter to streamline conditional logic for getter instance check
PR https://github.com/open-telemetry/opentelemetry-specification/pull/4461 clarifies that some
attributes (service.name, telemetry.*) are mandatory. It also reserves a couple of well-known
detectors names (container, host, process, service) and the attributes they should populate.
Consolidate some of our resource detectors into the built-in ones:
- process-runtime into process, and deprecate
- os into host, and deprecate
- sdk-provided into sdk, and deprecate
- service.name attribute from environment into service detector
Add "mandatory attributes", which is currently service.name, and initially set this to "unknown_service:php"
similar to Java's implementation. Ensure that the composite detector starts with mandatory attributes.
Ensure that "sdk" and "service" detectors are always included from ResourceInfoFactory.
The deprecated detectors are still available, but do not do anything.
Introduced `InMemoryStorageManager` to centralize storage management for spans, metrics, and logs. Updated InMemory exporters and their factory classes to utilize this shared storage.
* Add integration test for InMemoryExporter
- add integration test that shows that storage contains metrics
- because of src/SDK/Metrics/MetricReader/ExportingReader.php:148 I had to add `PushMetricExporterInterface` to InMemoryExporter class
* Add integration test for InMemoryExporter
* chore: build images dynamically
* fix: only push on main
* chore: build on PR with path change
* chore: align casing
* fix: add missing 8.0 alias
* fix: declare arg before all others
* generate semconv 1.30
NB that v1.29 contained a bug, and the recommendation was to skip this version
* reduce minimum php version to 8.0
we still have a bunch of auto-instrumentations that work with 8.0
* if no observers are registered for a meter's instruments, some tests were emitting php warnings:
- foreach() argument must be of type array|object, null given
- Undefined array key XXX
null coalesce to an empty array to make the test happy.
* handle empty writers
* add support for env: prefix in yaml config
* align test to example in spec
* do not recursively replace env vars
- fix env substitution normalization so that it doesn't apply 2 replacement normalizers for string nodes
upstream config now splits otlp exporters into otlp_http and otlp_grpc
* use const, remove insecure from otlp_http config
* Apply suggestions from code review
Co-authored-by: Tobias Bachert <git@b-privat.de>
* set default endpoints, fix review feedback
* move endpoint out of yaml anchor
* convert timeouts from millis to seconds
---------
Co-authored-by: Tobias Bachert <git@b-privat.de>
This brings declarative config support up to 0.3 plus some of the unreleased 0.4 features:
* porting code from Nevay/otel-sdk-configuration
* support 0.4 metric reader config
* allow empty keys
since https://github.com/open-telemetry/opentelemetry-specification/pull/4269 empty keys are allows, and NULL is no longer equivalent to unset
* update config example to remove empty objects
* remove moved component providers from composer.json
* add ComponentProviderRegistry::componentMap for instrumentation configuration
the spec has added in-development otlp file/stdout exporter. We already supported this programmatically, so
add some factories and sdk config to allow configuration from environment (only for stdout, per spec)
if open_basedir is configured such that files that it tries to open are denied with a php warning, and
a custom error handler is installed which converts warnings to exceptions, an unhandled exception occurs.
add a test for this, suppress error handling around the code that can trigger this.
- headers and attributes are now arrays with `key` and `value` elements
- headers can optionally contain a `headers_list` element which supports a lower-priority CSV of key/value entries
- attributes can optionally contain an `attributes_list` element which supports a lower-priority CSV of key/value/data-type entries
update semconv generation to use the new tooling. This is fairly close to a 1:1 of what we have now,
although I noted a couple of TODOs which we might consider in future to align with what Java is
doing: split attribute up into file-per-type, and split stable/unstable.
* 8.4: fixing some implicit nullable params
* fix withspan handler nullable + example (#1377)
- class is nullable for pre hooks
- add phpt tests for withspan and its interaction with auto root span
* fix: update references to logging exporter (#1383)
This exporter has been replaced by the debug exporter and will be removed soon. Related to https://github.com/open-telemetry/opentelemetry-collector/pull/11037
Signed-off-by: Alex Boten <223565+codeboten@users.noreply.github.com>
* fix: Update collector tag in example to latest (#1384)
Follow-up from #1383. Debug exporter isn't available until v0.86.0, so this new configuration throws an error when trying to run the collector. `Error: cannot unmarshal the configuration: unknown exporters type "debug" for "debug"` Instead of setting to v0.86.0, I noticed the other docker files omitted the tag (so latest is pulled). I just updated this to match.
* Remove `MeterInterface::isEnabled()` and fix meter config re-enabling (#1387)
* Update SPI dependency to v1. (#1388)
* Fix README badges. (#1389)
* add phpDocumentor instructions to Makefile (#1385)
* add phpDocumentor instructions to Makefile
Signed-off-by: svrnm <neumanns@cisco.com>
* update DEVELOPMENT.md
Signed-off-by: svrnm <neumanns@cisco.com>
---------
Signed-off-by: svrnm <neumanns@cisco.com>
* Update README.md (#1344)
* Fix `IncompatibleReturnValueException` in `MessageFactoryTest` (#1392)
PSR7 `RequestInterface::getUri()` must return `UriInterface`, not `string`; explicit typehint was added in `2.0`.
* more implicit nulls
---------
Signed-off-by: Alex Boten <223565+codeboten@users.noreply.github.com>
Signed-off-by: svrnm <neumanns@cisco.com>
Co-authored-by: Alex Boten <223565+codeboten@users.noreply.github.com>
Co-authored-by: Jamie Danielson <jamieedanielson@gmail.com>
Co-authored-by: Tobias Bachert <git@b-privat.de>
Co-authored-by: Chris Lightfoot-Wild <github-clw@wild.me.uk>
Co-authored-by: Severin Neumann <neumanns@cisco.com>
Co-authored-by: Oleg <142805497+devactivity-team@users.noreply.github.com>
Follow-up from #1383. Debug exporter isn't available until v0.86.0, so this new configuration throws an error when trying to run the collector. `Error: cannot unmarshal the configuration: unknown exporters type "debug" for "debug"` Instead of setting to v0.86.0, I noticed the other docker files omitted the tag (so latest is pulled). I just updated this to match.
adding WithSpan and SpanAttribute attributes to the API. These attributes
are used by an upcoming feature in auto-instrumentation which allows users
to add attributes to their code to enable auto-instrumentation.
implement recent additions to the otel spec re: config provider. Config provider should return a
ConfigProperties, but we were already returning a ConfigurationRegistry. Added a ConfigProperties
interface for ConfigurationRegistry to implement, which gets us pretty close to spec.
We don't make ConfigProvider globally available, instead passing the ConfigurationRegistry in to
each instrumentation as we register it. The spec allows for this.
* 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.
at least one otel backend product sends an empty response with a gzip encoding, which we fail to decode (because
an empty string is not valid). Work around this by not trying to decode an empty value.
* 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
* 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...
* infection max threads
* implement events v1.32
implement the events api + sdk per spec v1.32:
- event logger is now only retrievable via an event logger provider
- domain attribute for events is removed
- events accept a subset of logrecord params, rather than an entire logrecord
* convert severity to a backed enum
* lint
* remove instead of deprecating logEvent, mark Logger constructor as internal
* make severity an enum only
* event attributes to iterable
* inject ClockInterface, add CachedInstrumentation, update examples
* set correct defaults for events
* test coverage
* Revert "make severity an enum only"
This reverts commit 710822907b.
Also, move PSR-3 mapping into the Severity enum.
* event attributes to iterable
* apply review feedback
* move test tools into vendor-bin
To reduce (hopefully, eliminate) the situations where our testing tools have conflicting
dependencies, use bamarni/composer-bin-plugin to manage them as separate vendored dirs.
Add symlinks under tools/, and update Makefile to use the self-contained versions.
Remove the dependencies from root composer.json
Rejigger dockerfile to add opcache, and some config required for latest version of grpc
* update action tools locations
* revert phpstan from vendor-bin
the phpstan plugins do not work. phpstan has no dependencies anyway, so it's safe enough to keep in vendor
* remove tools symlinks, update makefile
* 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>
our previous method of uploading to codecov.io is suffering from throttling and taking 5+ hours,
a post in the opentelemetry maintainers channel suggests this is the way to do it now
* enable timeout for http transports
Attempt to do our own discovery for some well-known PSR-18 clients, which allows
for configuring timeout (and in future certificates, keys etc).
This is not complete and a prototype for feedback, but I've updated an example to
show that it works for Guzzle and Symfony http clients
* improve client discovery
* refactor, test, add more implementations
* add timeout for logs and metrics
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)
* port Nevay/otel-sdk-configuration into opentelemetry-php
This is a lift-and-shift, except for:
- changing namespaces
- fixes or ignore rules required to make static analysis tools happy
- commenting out one part of yaml test (unquoted hex value from env var)
* fix psalm on php81
* 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}
* Port tracestate tests
* Fix tracestate implementation
* Fix W3C test service
* Fix style
* Move tests into `TraceStateTest`
* Assert that warning is triggered when parsing invalid tracestate
* Add additional tests for valid/invalid keys/values
* 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
String values which are not valid Unicode sequences SHOULD be converted to AnyValue's bytes_value with the bytes representing the string in the original order and format of the source string.
* 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
* fix: Allow OTEL_PHP_DEBUG_SCOPES_DISABLED env var + use of null-coalescing operator
* refactor: Check order & env reset
* refactor: Use class constant
* fix: Respect order and value if it is set
* style: Lint
* tests: Falsey behavior
Modeled on python's feature to turn off all instrumentation for specific URLs,
https://opentelemetry.io/docs/languages/python/automatic/agent-config/#excluded-urls
this feature will effectively disable SDK autoloading if there is a request URI that
matches one of the provided excluded URLs, and no-op implementations will be used
for tracer/logger/meter providers.
* generate semconv 1.24.0
generate latest semconv version, and add back Trace and Resource attribute values which
seem to have been dropped in a previous change.
* document source repo release urls
* remove redundant semconv deprecations
two trace attributes were deleted then added back to upstream semconv, so remove our ones.
Optimize build times by caching php extensions for one week, particularly for 8.4/nightly which otherwise builds extensions from source each time.
This ended up being a little convoluted, since caching extensions does not run on failure. So, make all steps continue-on-failure for experimental builds, and add a final post job which checks the status of the steps and does a final fail.
- do not revalidate/normalize resource attributes on merge, since they have already been validated/normalized
- string concat is about 10x faster than sprintf, so use it in ClassConstantAccessor since it's called many times
* reduce resource creation from sdk autoloader
- instead of creating new resources from various factories, create them once from sdk autoloader and
pass them to the factories (most of which already supported this).
- check env before php.ini for config, since this is the more popular approach and saves some cycles
- cache header from OtlpUtil, to save a couple of calls to Sdk detector
* adding benchmark for resource creation
* Handle DebugScope out-of-order destruction during final shutdown
* Move debug traces from local scope storage to debug scope properties
* Fix phpstan error
* 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.
Only fails if a node that was created after exceeding 63 readers should be merged with a node that was created before exceeding 63 readers, resulting in an `GMP===int` comparison. Affected nodes were still merged on the next `::collect()` call -> solely internal change.
* Prevent propagator extensions from failing if sdk not installed
* Remove KnownValues dependency
Also prevents failing for cloudtrace: sdk < 1.0.1 and jaeger: sdk < 1.0.3.
* Add instrument advisory parameter
* Undo bucket boundaries change to preserve BC
"SDKs SHOULD use the default value when boundaries are not explicitly provided, unless they have good reasons to use something different (e.g. for backward compatibility reasons in a stable SDK release)."
* Add note that passing callback instead of advisory is deprecated
a bug in 1.23.0 meant that cloud, container and oci resource attributes were incorrectly published under trace attributes.
sort the attributes, so that future diffs are easier to read.
* update semver to 1.22.0
Since 1.19.0, the source has been split out of opentelemetry-specifiction into semantic-conventions. Update the build script accordingly.
Update to latest generator.
Add 2 new deprecations for semconvs which were renamed since 1.19
* update telemetry semconv
8.3 is in RC, so add it to the matrix.
bump 8.2 to non-experimental, which should have happened some time ago.
remove deprecated assert_options call from test bootstrap
Exposing it through Globals can cause a race condition. If something (eg, a contrib module)
retrieves the configuration resolver from Globals too early during autoloading, then it
causes the rest of the objects from Globals to be initialized. This can happen before all
required modules have been registered (depending on autoload->files execution order, which
is variable). Instead, create a simple API config resolver which does the basics of what the
SDK one does (without all the type checking and validation).
Whilst investigating upgrading to psalm 5, I notice that it generates a lot of new complaints. This fixes the ones that looked legit and
require an API change, or were trivial. Does not upgrade to psalm 5 yet, though. That's a bigger job for another day.
send errors/warnings/etc by default through PHP's error_log. This gives more control to administrators, since error_log can
be configured to write to any stream (file, stderr, etc). I think it's also less surprising for people trying out otel (particularly
with development PHP settings, where trigger_error often breaks an application).
Adding a configuration value to control where logs go: OTEL_PHP_LOG_DESTINATION.
per TC review, temporality is not part of MetricExporterInterface. Riffing on Java's solution, this moves
`temporality` into `AggregationTemporalitySelectorInterface`, and adds that interface to MetricExporter instances
that use it (everything except `NoopMetricExporter`).
https://github.com/open-telemetry/opentelemetry-specification/pull/3563 clarifies the behaviour of
forceFlush with push/non-push metric exporters.
Break forceFlush out into a PushMetricExporterInterface, and update ExportingReader to only collect/flush
if exporter is a push metric exporter.
noted in TC review. Java moved their examplar code into an internal package, and
documented that it may change. We don't have an internal package, so document
the warning in a few places.
adding a configuration resolver interface, and api+sdk implementations. the resolver is globally configured.
this allows contrib modules to fetch config if an SDK is installed, without directly using the SDK (per spec).
They aren't _truly_ safe on NTS builds either, as the functions used
are only expected to be set at certain times of the lifecycle, but in
practice it's safe enough on NTS.
However, for ZTS, these APIs are not safe to call at runtime at all.
fixing static analysis complaints, most of which were from psalm
when run with --show-info
remove deprecated httplug discovery
static data providers (phpunit10 requirement)
if an array is non-simple (has keys), it should be represented as a KeyValue in the generated
protobuf-encoded output.
Since we also need to support simple arrays of primitives, I've added a basic check so that
those are still represented as ArrayValue.
moving private method into a testable class, introduce attribute validation class
which applies to most attribute. LogRecord attributes are allowed to be complex,
so introduce a validator for these which lets everything through.
We made protobuf implementation optional back in #949 however it seems to be tripping up
a number of developers. Since native + extension can be installed at the same time (with
extension taking priority), I think that users will be less surprised when starting out
if there is a working implementation by default.
* adding badges to the various readme files to make more obvious the current versions
* list all packages and versions in main readme
* remove old README documentation (excluding development-specific), and direct users to opentelemetry.io
* link to opentelemetry.io where possible in package readme
* adding a badge to link to releases
releases are not easy to find, since they exist only in the subtree split repository
to make getting started easier (in opentelemetry.io docs), create an sdk-based metrics
exporter. this means we can export all signals without needing a protobuf implementation.
since console export is only useful for playing around, the change in format to a
simpler human-readable output seems reasonable.
* adding some links to try to make it easier for users to find the right support/repositories etc
just doing one composer file to see if it works, and will follow-up with more in a later PR
* change forum to chat
* Adding a backtrace to the errors reported via error_log (which is the default)
* Implement OTEL_LOG_LEVEL, which can be used to control which errors are reported via error_log. Note that
this doesn't use configuration code from the SDK, as the usage is in the API (because messages are logged
from many packages) and deptrac rightly complains about the dependency on SDK.
We do not actually require an async http client, so use psr/http-client-implementation instead.
We depend on the psr/http-client interface, so require it (which has a side-effect of un-breaking
the symfony http client which is frequently auto-installed by php-http/discovery's plugin)
- sdk BC was not being loaded at all in the sdk package (only in the monorepo), so add it to autoload->files
- fixing api/common BC layer (removing .php and fixing one of the FQCNs)
- apply TC review feedback to move Globals to top-level.
it was suggested to move Instrumentation into its own package, but I chose instead to just move that dir
up to the top level of API
- added a BC layer to alias the moved classes
- added some more examples
allow the existing metric exporter to be created from env vars, by creating a factory
and registering it against 'console'. Now, OTEL_METRICS_EXPORTER=console will create
a metrics provider with console output. Note that it lives in contrib/otlp, since it
uses the existing otlp converters.
To enable registering non-SDK resource detectors within the SDK, extend the SDK Registry.
Detectors will be looked up by name and applied as part of 'all', or as part of a list
of detectors
New Relic now fully supports OTLP ingestion, and having proprietary exporters is no longer their strategy. The proprietary exporters have been marked as abandoned in packagist, and suggest exporter-otlp as a replacement.
the example is very old, does not work, and it doesn't look like the capability
is in the spec these days. Remove the code so that it doesn't cause confusion.
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.
Implement OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE, which controls the temporality of meters when creating from environment vars.
Add OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION to variables, although we do not yet have anything that uses it.
use docker compose 'env_file' to include all .env file vars in container env
make the default rector action dry-run, which allows developers to inspect code changes
before applying them (and therefore giving the option to disable new rules before they
are applied to WIP).
Adding some make targets which will install composer dependencies with the lowest
package versions. This highlights some small issues with older versions, so bump up
the minimums of a few dev dependencies.
Adding more make targets:
- all-lowest (run all checks after updating with --prefer-lowest)
- all-checks (run all checks without first running a composer update)
- update-lowest (update dependencies to lowest installable versions)
Quieten unit test output (the previous testdox output is available via `make test-verbose`)
* update semantic conventions to v1.19
* updating semconv readme
* dropping attribute values
I can't find any usage of the various AttributeValues being used, and other SIGs
no longer generate them, so removing them
* removing semconv usage from API
allow deprecations of moved/removed attributes so that we don't break things across different
semconv versions (similar to how java does it, except I moved them into a file which is
imported
* implement bridge api
* adding logs memory exporter
* clarify bridge api not for developers
* adding logger provider builder
* review feedback
* removing Bridge and documenting what a bridge is
the otlp exporters (logs, metrics, traces) will fail to export if there is no protobuf implementation (which we have
just made optional, to allow users to choose between extension and native). Add a check to
the constructors which will throw a runtime exception.
If creating the exporter directly, it will be uncaught. If using a factory, it will report a
warning and return a no-op exporter.
* Make google/protobuf an optional dependency
* Update the README with more information on installing protobuf implementation
* Add some extra documentation in the OTLP exporter library
* Update proto/otel/README.md
This change instructs explode to extract at most 2 parts.
Given an example value of
```
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Basic bla64=
```
The config parser would have created the elements, where only two are required. The trailing `=` in base64 headers would then have been effectively discarded, leading to invalid configuration.
sdk-contrib is abandoned in packagist, because we publish the packages individually
and at independent versions. for the same reason, do not gitsplit tags, only main
as we do the tagging in the read-only repos now
* 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.
if an empty tracestate header was passed, we were emitting a warning (discovered in the demo app after enabling logging).
to fix this, check for empty string as well as null.
a script to identify which of our git-split repos have changes which are not in a release.
also creates release notes for the release, which can be dropped into the github UI
* print new release url
* relax symfony/yaml requirement
* warn about rate limiting if no token provided
using self.version does not work when we have different components being released individually. ^1.0 seems like a sensible initial setting now that we have reached beta.
* adding a configuration for disabling auto-instrumentations
addressing review feedback from pdelewski, provide a mechanism that can be used to disable auto-instrumentation packages
without actually uninstalling them.
A new variable, OTEL_PHP_DISABLED_INSTRUMENTATIONS, has been added which accepts a list of instrumentation names to be disabled.
Each instrumentation can call Instrumentation::isDisabled to determine if they should bail without registering hooks.
* moving instrumentation disabled into Sdk class
* allow OTEL_SDK_DISABLED to disable sdk autoloading
* review feedback
- test for sdk disabled in initializer
- sdk disabled does not disable propagator, per spec
Rather than log nothing by default, log warnings and greater to console.
By providing a psr-3 logger, users can gain greater control over logging, including disabling it (via NullLogger)
- remove baggage TODOs which have since been done.
- implement TODOs from tracestate to log warnings.
- tidy up tracestate code, simplify some const names.
* create text map propagators from registry
removing undocumented dependency between sdk and extension by adding text map propagators to a registry
as part of composer autoloading, similar to how exporters, transports etc are treated.
* remove TextMapPropagatorFactory instances and register the singletons directly
* rename FactoryRegistry to just Registry
* 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>
moving exporter examples up one directory, where I think they are more obvious to find.
remove some old and broken grpc examples.
remove unused interface.
when creating a stream from an endpoint string, the factory wasn't returning the stream. fix and add tests.
Co-authored-by: Tobias Bachert <git@b-privat.de>
* update grpc gitsplit destination
match the gitsplit destination repo to match package name: 'transport-grpc'
* adding missing autoload files for exporters
- remove Mocker mocks, which were contributing extra time, and replace with no-op implementations
- adding extra benchmarks (batch vs simple, protobuf vs json)
* 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
refactoring Environment access to allow configuration from multiple sources. Initially, the sources are env ($_SERVER) and php.ini, but this should allow us to add more sources in future without changing the API.
do not modify OTEL_EXPORTER_OTLP_TRACES_PROTOCOL
allow resolvers to return mixed
* merge otlp exporters
continuing on from Nevay's work, this removes the individual OtlpHttp and OtlpGrpc exporters, and replaces with
Otlp\Exporter using a transport to manage grpc and http/protobuf complexity.
* tidy
* use mockery overload instead of prototype clone
* making all smoke-test examples work
* removing startBatch
verified that the call attributes have the same values when using TraceServiceClient
* tidy
* tidy
* Revert "use mockery overload instead of prototype clone"
This reverts commit bbb685b4d1.
Mocking proto-generated files segfaults with ext-protobuf (which is harder to diagnose when running in a child process, which
was required for fancy mockery mocking of "new". So, back to the prototype approach, and skip the tests if ext-protobuf enabled.
* tests without mocking protobuf
* test
* typo
* reverting FromConnectionStringInterface
* grpc headers
* revert to dumb transports, handle multiple protocols
* tidy, adding initial otlp json support
* self-review
* linting
* remove redundant interface
* Revert "remove redundant interface"
This reverts commit 350d40cdfe.
* fix getFloat
Co-authored-by: Tobias Bachert <git@b-privat.de>
* move withSignal into otlp-specific interface
* moving exporter/transport env handling into a new factory
* linting
* remove unused code
* tidy
* moving OtlpHttp into Otlp
* removing OtlpTransportFactoryInterface
* fix style
* fixing psalm error
* addressing review feedback
* replacing removed code
* fixing example
Co-authored-by: Tobias Bachert <git@b-privat.de>
* refactor: provide EnvironmentVariables static class for friendly-typed access
utilizes Accessor and Variables under the hood to provide consistent default values
* 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
* Add alternative instrumentation abstraction
* Provide global access to providers
Remove logs for now, will be replaced with `LoggerProvider` in the future.
* resolve deptrac baseline
Nevay found that an @internal annotation in NonRecordingSpan was the cause of the violation, so
remove it.
* make psalm happy
* 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
Removes ScopeBound... classes to reduce the API surface.
- ScopeBoundCallable: Was intended for event loops. Event loop decorators should instead implement this in a way that fits the specific loop API the best with regard to avoiding unnecessary references to arguments and error handling.
(The implementation was (mostly) sufficient for react/event-loop but shouldn't be used for revolt/event-loop.)
- ScopeBoundPromise: Was only intended as very basic example implementation. An actual implementation has to hook into the specific promise implementation to capture the context of the initial promise.
(I'm not sure how useful promise/future support is in general, there are scenarios where we cannot preserve the context association, e.g. when extracting/awaiting the value.)
* Added B3Propagator Class to handle two configurations and storing debug flag in the returned context
* Updated B3Propagator extract according to the clarification in the specs; updated test cases
we already run psalm in the php workflow. this one doesn't add much, and is more flaky. we have decided that the serif uploading is not very important since we have good makefile-based ability for devs to run this all locally before pushing
* 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.
* 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
* 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 help to makefile
this makes the makefile a little easier to grok: now 'make' or 'make help' will list make targets and a brief description of what they do
* document make help
* 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
* Rename examples to snake case
* Move examples into signal specific folders
* Moving the exporter-specific examples into their own directory
* Update import paths for autoload.php
* Move the rest into a dedicated features folder
* Renaming the distributed-tracing folder to be slightly more self-explanatory
* Move exporters folder underneath features folder
* Woops forgot to update the Makefile too
* clarify the catch is not for otel-php but app code people might fill in the example with
* Removing sampling from examples that don't need to involve it
* Simplify names of the exporter example files
* Point back to the right vendor folder for the tracing demo
* Try get the demo a little closer back to actually working
* Add in a make target for smoke testing more of the examples
* clarify how to speed up one of the slow smoke tests
* Group spans by resource
* Use proto methods instead of array constructor
* Use consistent naming for methods
* Suppress `InvalidArgument` false positives
Caused by `RepeatedField` being not generic.
* Add rector as dev dependency
* Add rector config
* Add rector make targets
* Add intl extension to dev image to support rector
* Add rector make targets
* Apply rector PHP_74 rules
* Fix CS
* Make Phan happy
* 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.
* Updated laravel-quickstart.md
* Updated symfony-quickstart.md
* Replaced setStatus with recordException in the child span
* Removed TODO comment
* Changes from PR 701 by DrLuke
* 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
Attempts to fix the W3C test service by updating usage patterns to
match the refactorings and functional changes that have been applied
since it was last updated.
* Refactor stacktrace formatter
- fixes "... n more" to fold only identical frames
- fixes exception class names not being converted to dotted format
- fixes functions being shown as `main`
- fixes out-of-memory on circular exception
* Rename stacktrace formatter
* Update framework integration docs
* Apply suggestions from review
- Avoid multiple constructor calls.
- Grammar regression.
- Fix type `s/jaegar/jaeger`.
* Update exporters + sampling to the new API (per review)
* Fix setup instructions and improve consistency and style
* Update span status handling and current span fetch
* Introduce warnings and demote to "Exploration guides"
* chore: rename framework "guides"
it's important to detach scope for any activated span (especially in async runtimes), so ensure
that the examples show it being done where possible.
In passing, fix some broken examples.
* Add validation for package composer files
* Fix CI step order
* Exclude duplicate Composer Installed Version class
* Add packages-composer make target to 'all'
* Use PHP version in composer cache
* Added B3MultiPropagater
* Added static self and removed case insensitive getter function
* Added unit tests for B3MultiPropagator class
* Refactored B3MultiPropagator and added tests in B3MultiPropagatorTest
* Added description for B3MultiPropagator
* 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
* fixing w3c-tracecontext test startup
make w3c-trace-context was suffering from some bitrot, so this change gets it building and
running again. The tests themselves still fail due to further code-related bitrot.
* silence new phpstan error
* 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
* Add integration tests for span builder
* Space fixed
* Add more descriptive names and @group annotation
Modified the names of the tests to be more descriptive and added the
`@group compliance` notation.
Additionally, I commented out one of the tests that I was not totally
sure of. (unsure if `setAttribute()` should work with empty string `''`
values.
* Fixed test name
* Check for specific attributes and not just count
Removed `$span->end()` calls as they shouldn't be necessary
* Remove redundant `end()` calls
* Add test for getting default tracer
Test to get default tracer. Also, added `@group` php unit annotation for
tests to check specification compliance
* Fixed warning
* Fixed style warning
* Extract InstrumentationLibrary key generation logic
Factors key generation logic for InstrumentationLibrary instances
out to a helper method in a utils class.
* Remove @see PHP annotation
Phan doesn't like it, couldn't see an acceptable workaround.
* Change key generator namespace and class
Changes the key generator's namespace to Util\Instrumentation and classname to
KeyGenerator, refactoring usages.
* Add unit tests for Instrumentation key generator
* Add test case for non-null version and null schema
Also renames the other 2 tests for descriptiveness.
* Fix typos and some redundancy
Fixed a few typos and removed mentions of "from your bash compatible
shell" (we use make so these commands are compatible with all clis)
* Make BC error level configurable
* Add information about BC errors to README
* Make CS happy
* Silence Psalm
* Add missing test
* Remove unused data annotation
this should make the build green for 8.1, finally. We can now consider 8.1 supported,
and so it moves out of experimental - future 8.1 breaks will fail the pipeline.
allow logging methods in LogsMessagesTrait to be called from within either a static or non-static method.
in passing, adding a missing coversNothing annotation on a complaining integration test
* Add @group annotation to compliance tests
Marked tests for environment variables with phpunit @group annotations to identify
compliance tests. This enables for a way to run just those specific
test and will serve as a useful form of documentation.
* Add trace signal specific notation
* Add test based on the spec
* Fix the other tests which appear flaky
* Clarify the randomness in these tests
* Add concrete example from Go for the trace id splitting
* Fix style
a bug when fetching settings from environment was causing the grpc exporter to always use our default
value, rather than the one provided to the exporter's constructor
* Factor a class out for handling the id conversion
* Remove remaining direct intval references
* Further isolating the soon-to-be-replaced use of intval
* Use brick\math to fix the issue and update the existing tests
* Adding brick\math to composer.json because I missed it in the previous commit?
* Adding some edge case unit tests around the id conversion
* Move explanatory comments into the data provider itself
* Add new package to phan config
* Fix style
* Try clarify comment
* Extract constant
* Remove comments
* Try quick manual merge to fix merge conflicts
* Commit in progress work because Gitpod is weird
* Finish initial stab at the changes
* Forgot to update the exporter
* Add in proper handling of serialization of ResourceInfo
* ksort doesn't return the array...
* Only PHP 8.1 supports key-ed array destructuring
* Creating some adapters to break the hard dependency on Batch to make testing easier
* Refactoring to break the hard dependency on Batch
* Add initial unit tests around the new logic in HttpSender
* Some refactoring of the test's helpers
* Another small refactor
* Some more refactoring
* Rename ResourceInfo's test file to match it's file name
* Move a test our of REsourceInfoTest into a more appropriate file
* Add some basic conformance tests around the new ResourceInfo::serialize method
* Add a test to try and catch future properties that aren't added to ResourceInfo::serialize
* CLean up comments
* Replace string with constant
* Improve variable names
* Cleaning up comment
* Split out tag creation into a helper class
* Phan didn't like the type docs
* Fix style
* Fix tests after merge from main
* Fix coverage reporting issues on 2 of the new files
* Fix style
* Rename vals to values
* Shortening the batch adapter factory method name to create
* Inline a method call
* Inline some method calls
* Shorten factory method to just "create"
* Inline some code
* Split assertions into 3 tests
* Rename parameter in interface implementation for psalm + update the rest of the file to match
Co-authored-by: Timo Michna <timomichna@yahoo.de>
* Move Clock classes to SDK\Common\Time namespace
* Move conversion methods to Util class
* Implement StopWatch
* Implement ClockFactory
* Fix StopwatchInterface
* Finalize ClockFactory
* Implement StopWatchFactory
* Deprecate AbstractClock
* Add BC alias
* Add initial start time to StopWatch
* Unify and optimize SystemClock methods
* Use ClockFactory in Span
* Use ClockFactory in BatchSpanProcessor
* Use ClockInterface in BatchSpanProcessorTest
* Use ClockFactory in SpanData
* Use ClockFactory in examples
* Add millisToNanos Util method
* Use StopWatch in BatchSpanProcessor
* Make Phan happy
* Make Psalm happy
* Make PHPUnit happy
* Remove sllh/composer-versions-check from allowed composer plugins
* Use correct assertion
* Use correct assertion
* Assert difference
* Move Attribute classes to Common namespace
* refactor AttributesTest
* Move Attribute classes to Common namespace in examples
* Introduce AttributeLimitsInterface
* Fix bug in total added values calculation
* Move compare test to correct test-class
* Apply CS
* Refactor Attributes
* Fix attributes in Benchmark
* Move AttributeLimits defaults to interface
phpstan has just started to fail on a couple of test assertions based on their phpdoc return type:
Call to method PHPUnit\Framework\Assert::assertNotSame() with mixed and mixed will always evaluate to false
This doesn't consider that assert<Not>Same will also check for whether two objects are the same instance, so
ignore the error.
* Added OTEL_PHP_DETECTORS environment variable to configure detectors from environment
* Added unit tests for defaultResource
* Review comment: Added exapmle
* Refactoring to keep the syntax same across examples
* Review comment: Using static method instead creating instance and using constants
* Scaffold the new exporter and helper class
* Make the SpanConverter compliant to the interface the others are
* Removing check already covered by SpanExporterTrait
* Adding in scaffolding for a happy path test through the new code
* Fix bugs when path is present or endpoint scheme is https
* Remove type doc to fix psalm errors
* Comment out doc type to fix phan issue
* Fix style
* Add missing type in constructor
* Shorten ternary
* Inline function calls in doExport
* Inline function calls in doExport
* Revert ternary condensation commit from earlier
* Not requiring a port be set in the endpoint URL and inferring it from the scheme when it's missing
* Try adjusting thttpclient with a subclass instead of adapter (#2)
* Setup the exporter for injecting a psr-18 client
* Switch to using a subclass of THttpCLient
* Getting the psr-18 client into the subclass
* Copy verbatim from THttpCLient the method that needs working
* Getting the request and stream factories in there too
* Migrating the headers over to use the psr18 and psr7 things
* Migrating over the body
* Commenting out some more things Otel doesn't need
* Commenting out the rest as it seems accounted for
* Removing the last of the old implementation
* Fix to undefined variable from previous commit
* Actually otel isn't using any custom headers so we don't need to handle those either
* Remove all the commented out code
* Updating fromConnectionString to use the discovery helpers to find and inject the PSR-18 and PSR-7 classes HttpCollectorExporter needs
* Reworking happy path test to use mocks of the PSR-18/PSR-7 interfaces
* Turning TODO in to comment
* Adjust line breaks
* Fix style
* Fix potential array key access error Phan noticed
* Ignore psalm false positives in the test file
* Workaround odd psalm bug/behavior of surfacing errors in THttpClient after it's been subclassed
* Switch to correct shortening of ternaries this time
* Minimal changes needed to drop dependence on THttpClient
* Moving some of the setters into the constructor now that the THttpClient superclass is gone
* Cleaning up endpointURL duplication and removing host_ member that's not really needed anymore
* Naming the copied over buf_ member a little more explicitly
* Naming the main test object in the span converter test class more clearly
* Renaming 2 of the files/classes to be more clear
* Remove inaccurate copy pasta leftover from THttpClient
* Fix style
* Factor out a helper object for parsing the endpoints to help satisfy Phan
* Have codecov pick up on the hlper class for code coverage
* Refactor the UDP exporter to also use the new ParsedEndpointUrl helper class
* Fix style
* Psalm makes a good point that the defaults for host/port in the UDP exporter can never be hit since the entry point requires them to be present in the endpoint URL
* Add support for OTLP signal specific environment overrides
Modified the OTLP gPRC and HTTP trace exporters to allow for
configuration options overrides by signal specific options to comply
with OpenTelemetry specs.
* Revert overrides for the INSECURE variable
* Add check method to EnvironmentVariableTrait
For better code readabilty, added a hasEnvironmentVariable() to
EnvironmentVariableTrait.
* Add check for empty certificate file
* Fix style and add check for endpoint variable
* Add in the span kind mapping
* Improve colocation of the 64 bit check
* Make the order of the helper functions better match the usage in the entry method
* Rename otlp to otel since that was tripping me up a little
* Initial work for events conversion
* Making the previous commit functional and adding tests
* Factoring out a chunk of code from the entrypoint
* Fixing style
* Extract confusing constants
* Uncommenting the handling for tags of non-string types
* Making the string tag type the default fallback, matching the sanitiseTagValue method
* Moving the array serialization into the buildTag method
* Opening up the tag creation to arbitrary types, not just strings
* Moving the array serialization method to be more colocated
* Fix existing tests
* Removing hard to reach branch that should already be covered by the default case
* Extending existing test to cover the new number cases
* Refactor to avoid possibly mutating argument reference
* Implement error flag section of the spec
* Implement the Links section from the spec
* Refactoring the span id conversion for better colocation
* Fix assertion parameter order in a few tests
* Fix style
* Fix style post manual merge from main
* Inline helper method call
* Remove elseif branches
* Re-cover bool to string conversion line and remove less-than-helpful comment nearby
psalm has started to complain that random_bytes must receive a positive integer. We always
provide a positive integer, so suppress the warning. In passing, make randomHex method
private, since it is not called from anywhere that I can find.
* Add in the span kind mapping
* Improve colocation of the 64 bit check
* Make the order of the helper functions better match the usage in the entry method
* Rename otlp to otel since that was tripping me up a little
* Initial work for events conversion
* Making the previous commit functional and adding tests
* Factoring out a chunk of code from the entrypoint
* Fixing style
* Extract confusing constants
After reading a few open GitHub issues, I'm aware that it is known that the Symfony/Laravel examples as a whole are not up-to-date with the sdk code, but the docker-compose tutorial is on point. So if it's okay, I want to update it to the latest Jaeger version.
https://github.com/jaegertracing/jaeger/releases/tag/v1.22.0
> --collector.zipkin.http-port is replaced by --collector.zipkin.host-port
* Include library name and version in the jaeger span
* Implementing the span status conversion part of the base spec
* Add test now instead of later to pass coverage requirements
* Trying to clarify how the mapped statuses are distinct from the input ones with constant names
* Update namings of constants to be more flexible
* fixing otlp span converter with ext-protobuf
There looks to be a bug in ext-protobuf, where an array with any empty string top-level values cause an error. A workaround for this is to strip out entries with empty values.
Adding ext-protobuf to the test matrix, and in passing fixing a mis-named test class
* document and suggest protobuf extension
* Moving the files to what I think are their correct new location
* Initial resolution of some of the parsing and intellisense errors
* Installing apache/thrift to solve more of the parsing issues
* Updating AgentExporter to conform to the updated SpanExporterInterface
* Switching to the new method names on SpanDataInterface
* Make the thrift generation script executable
* Fixing the last intellisense issue in AgentExporter
* Generating these thrift IDL files seems to have resolved the remaining parsing/intellisense errors
* Update thrift generation script to change target directory
* Generate the thrift idl files in the new directory
* Clean up conflicts with SpanExporterTrait's declaration of isRunning
* initial scaffolding for a happy path
* Fix lookup for socket functions to not look in the Jaeger declared namespace
* Setting up the autoloader so auto-generated thrift files can be found
* Switching to use the static method for creating the object under test
* Add a method and assertions to the happy path
* Doing some more exercise by passing in a shell span to export
* Clean up the socket at the end of the test
* Extend the happy path's coverage slightly
* Move exertion of the tag generation logic into a unit test
* Commenting out apparently dead code
* Adding a unit test exercising the happy path of the SpanConverter in more detail
* Ordering assertSame parameters correctly
* Cleaning up the 2 new tests a little
* Updating tests to match the new naming convention upstream
* Run make style
* Fix psalm errors
* Fixing most of the phpstan errors
* Fix test broken by psalm changes
* Fix phan config issues
* Fix phpstan issues
* Preventing installations on non-64 bit systems that won't work with Jaeger ids
* Manually merge changes to composer.json
* Fix 64 bit requirement setup
* Some more manual merging to try and resolve composer.json conflicts
* Update namespace for SpanData test helper to fix psalm issues
* Move the test files to what appear to be their new locations
* Fix failing test around getValue call on attributes (not exactly sure how this was passing before, but now it matches the zipkin version)
* Add @covers attributes to the test files
* Moving AgentExporterTest under the Unit folder because tests under the integration folder don't have their coverage reported
* Commenting out CodecUtility to see how that affects the coverage
* Adding in requirements and suggestions for ext-sockets into the composer.json's
* Switch to self when invoking the static method
* Rename Transport to TransportInterface
* Switch to using the logging trait instead of calling error_log directly
* Removing 64-bit install requirement
* Refactor anything needing to use intval into 1 function
* Adding a runtime check for 64-bit integer support
* Adding missing return types on methods
* Moving ext-sockets to be a suggest in the contrib composer.json too
* Remove extraneous comments in tests
* Switch to use shared time unit conversion method
* Clarify what the pre-existing commented out code should be used for
* Run style fixer
* Move 64bit check into a constructor
* Deleting the unused CodecUtility file
* Converting the TODO to a NOTE for the 2nd commented out block in SpanConverter
* adding covers annotations to all tests
* clock tests
* adding unit tests
* feedback
- cleaning up ValueRecorder tests
- ints are floats, so type-hint ValueRecorder::record and remove some checks
* reorganise tests
moving tests under tests/Unit and tests/Integration, and updating namespaces
changing 'make test' to just run unit tests, and generate coverage off that
adding a 'make test-integration' to run integration tests (without coverage)
adding test-integration to 'make all'
adding a separate github action to run integration tests
* tidy 'make test'
make test is now a combination of test-unit and test-integration
* fixing 'make all'
* adding unit tests for TraceIdRatioBasedSampler
I grabbed a couple of the more unit-tests tests from the integration tests. Also starting to add some @covers
annotations to start to remove false coverage
* Rename test methods
Ensure all test methods:
- are snake_case
- have "test" prefix
Private methods, data providers, setUp/tearDown and external functions
remain camelCase.
* Add return type to test methods
Ensure all test methods have return type "void".
* Remove extraneous @test from test method docblocks
Where it is the only entry, remove the docblock entirely.
* Fix missing test prefix
Add test prefix and fix mixed snake_case and camelCase test name.
* Move Attributes and Clock out of /Trace namespace
Also needed for other components (metrics).
* Move Event and Link to SDK
* Move NoopTracer to API
* Remove `Attribute` abstraction
* Move `Attributes` to SDK by widening API attributes types to `iterable`
* Move `Clockinterface` to SDK
* Fix fqcn usage
* Readd `AttributesInterface` mock
* Move `TraceState` and W3C `TraceContextPropagator` to API
* Add tests for noop `SpanContext` propagation
* Fix noop `SpanContext` propagation
* Remove global context usage in `NoopSpanBuilder`
* Make `Context` non-final until `ContextInterface` is introduced
Workaround for mocking failure on php8.1.
* fixing fiber test crash
instead of serializing FFI into a const, stash it in a static as suggested by @nevay
* update comment on FFI reference
* review feedback
moving ffi+fiber code into a class, and protecting it behind a new env var
replacing class with a mock in ArrayAccessGetterSetterTest
* review feedback
putting back FFI::scope which is required for other SAPIs, and starting to document preloading
* Add PHP 8.1 to test matrix
* Fix composer package versions
* Set the php-cs-fixer version to 'dev-master'
* Reset the php-cs-fixer version to stable one
* Set friendsofphp/php-cs-fixer version to 3.4
* Fix PHPStan covariant error in PHP8.1
* Fix optional parameter declared before required parameter error
* fix the matrix
* more matrix fixing
a failing experimental job no longer stops the whole build, although we will see a red X. There is a feature request to be able to set jobs as "allowed-to-fail", but until that feature exists this looks like the best github actions can do.
* creating a global logger holder
since logging errors can live in all parts of the sdk (logs, metrics, traces), creating a singleton
in the top-level SDK namespace seems the best place. This commit just gets the mechanism in place
and implements a couple of log messages to get feedback on whether this is a good way to go
* adding a trait for accessing logger
* logging example, improve logged messages
* build for multiple php versions
allow building for multiple php versions by making Dockerfile php version an argument, and
relaxing extension location (by using find instead of hard-coded location).
Relax a couple of dev dependencies so they can install for 7.4->8.1.
Adding an example .env file, and allow configurating xdebug via environment.
Adding a couple of whitespace-related php-cs-fixer rules.
* run image build to schedule (midnight sunday UTC)
instead or rebuilding on each push to main, just rebuild weekly. The workflow can also be manually triggered
by a maintainer if required
* review feedback - wordsmithing supported versions
* Add semantic conventions for Resource and Trace attributes
* Add SCHEMA_URL pointing to the scheme used for code generation
* Fix setting of SERVICE_NAME in default Resource instance
* Add information about semantic conventions to README.md
* span converter rework
- combine otlp's grpc and http span converters into one
- adjust UsesSpanConverterTrait to always deal with arrays of spans, since span processors only accept arrays
Still to do:
- combine duplicated grpc/http span converter tests
* tidy
* make internal otlp span converted methods private
* WIP
* Return Opts object so chain config
* More WIP
* combining otlp and grpc config
based on SeanHood's initial work for #383, I've fleshed out ConfigOpts, and used it to
simplify the configuration of the http and grpc exporters
* tidy
* changing compression to string, per spec
* update example - insecure defaults to false per spec
* moving more config into ConfigOpts
now both http and grpc exporters have almost the same constructor (todo Grpc accepts a SpanConverter
but http does not)
* removing unused SpanConverter param
* remove unused function
* test coverage for grpc exporter
Co-authored-by: Sean Hood <me@seanhood.co.uk>
* benchmark setup
some initial benchmarking tests, based loosely on the spec and with some inspiration from the python-otlp tests
* link to extensive go benchmarks for inspiration
* style
* psalm + phpstan
* remove accidental commit
* style fix
* more benchmarks
* undo accidental commit
* Initial stab at implementing the event attributes logic
* In-progress work on the Remote Endpoint logic
* Partial progress on the ip portion of this
* Finish adapting the Go code
* Adding a check for if ipv6 support is enabled
* Add happy path test through remote endpoint code + fix comparison bug it uncovered too
* Add test through the ipv4 and port handling + fix bug with the preferred attribute key selection
* Partial progress on test through ipv6 handling code
* Switching the expected/actual for the new tests
* Fix up the ipv6 test
* Dropping back to assertSame since it's just a string comparison now
* Removing a piece of currently dead code
* Factoring out the Zipkin annotation generation
* Add return type
* Extract remote endpoint logic out into a function
* Factoring out the ranking logic into its own function
* Extracting the constant array into a class constant
* Flattening out 1 level of the nested ifs
* De-dup and flatten ifs some more
* Switch to a switch statement
* Factor out the ip address specific piece
* Flattening some more ifs
* Factoring out the port number lookup into its own function
* Composing the port number calculation in
* Cleaning out some comments + adding validation that the found port number is a real port
* Removing some more comments
* Another minor cleanup
* Adding a test for an else branch
* Updating the test to match the spec and fixing the code
* Refactoring and cleaning up toAnnotation
* Fix to Psalm noticing the ip methods only take strings but the attributes can have more general values
* Fix Phan recommendations on return types
* Fix style issues
* Don't recall what I changed in this file, but hopefully this gets rid of the merge conflicts
* Extract out a constant
* Restrict code coverage to the class under test
* Stregthen a comparison against null
* Swap string interpolation for sprintf
* Configuration from environment variables.
Allow configuring resources, (some) exporters, samplers, and span processors from environment.
Add a TraceProviderFactory as a top-level method of creating a span processor from environment variables.
I think that other span exporters can be made to be env-configurable, but holding off until an upcoming improvement to use psr-7 discovery lands, which should simplify
most of the exporters.
* setting io.opentelemetry.contrib.php as the default tracer name
* review feedback
- Throwing InvalidArgumentExceptions from some factories.
- Removing guzzle client from ExporterFactory.
* magic values to consts
* moving queue init to property
* adding root sampler to parentbased sampler description
this makes parent-based description more meaningful, and also useful for test assertions
* fixing tracer provider factory tests
* improving span processor factory tests
* use ReflectionObject in test
* Adding a trait for retrieving and processing environment variables
* empty value must be treated as unset
* fixing default service name
* Add scope out-of-order detection and support for execution context switching
* Remove Scope in favor of ScopeInterface
* Add fiber support
* Resolve/suppress phan/psalm/phpstan errors
Suppresses errors related to not available classes Fiber/FFI in code that is written for php ^8.1.
* Add missing test annotations
* updating BatchSpanProcessor to spec
The spec for SpanProcessor::shutdown() says 'MUST include the effects of ForceFlush', so implement that logic and add a test (also updated a couple of other tests to add a new expectation on forceFlush)
The spec for SpanProcessor::forceFlush() also says that built-in span processors MUST call forceFlush() on the exporter.
Bugfix: SpanInterface::scheduledDelayMillis clearly accepts milliseconds, but time checking arithmetic uses nanoseconds. Adding a constant to convert between the two (todo, write a test?)
* renaming const, adding batch example
* style fix
* unit tests for batch span processor delay
* improving code coverage of BatchSpanProcessor
* span resources example
example code for setting span resource attribute, which are sent as part of the payload of each span. also adds to ConsoleSpanExporter a
representation of each span's resources
* concurrent spans example
* linting, updating ConsoleSpanExporter tests
* adding some stable resource constants
* update span name
span-n should be more obvious when reading a trace
* Add docs + ConsoleSpanExporter
- [ ] Add tests
- [ ] Support Events/Attributes/Status
- [ ] Kind should return friendly string not int
* Update ConsoleSpanExporter to match SpanExporterInterface
* Tests! and more
* Tests!
* Kind now returns the API name rather than the integer
* Added attributes
* Added status
* Added events
* Fix trace parent id
* Update docs + examples
* Make phan/phpstan/psalm/style happy
* Make palm happy on PHP 7.4?
* Document more functions
* Adding in the 'kind' attribute
* Add in the instrumentation library attributes and extend the happy path test
* Add conditional logic around status and description tags
* Don't add parentId to row when it's not valid
* Drop kind from payload if null
* Omitting tags if there aren't any
* Update `SpanExporterInterface` Status constants to better leverage psalm
Implement `forceFlush` for all exporters
* Make CI happy
* Spec said Export not Shutdown
* Update OtlpHttp port in Exporter to be 4318 per most recent edition of spec
* Update old collector port to new one for Otlp/Http (and HTTP!?!)
* Fix typo. Yay tests!
* Also made that mistake here
* Make `shutdown` and `forceFlush` return `bool`
Rename `Exporter` to `SpanExporterInterface`
Update docs to include links to spec
* Return a noop tracer if the provider has been shutdown
* Make CI happy
Revamp `SimpleSpanProcessorTest`
This commit removes the old Otlp Exporter which wasn't to spec. I feel it's causing confusion about it being there.
On a side note, I was going to put common parts of OtlpGrpc and OtlpHttp into this namespace but haven't got around to it yet. So small clean up commit, until I find the time.
* Move `Baggage` logic into the API namespace
Make `TextMapPropagator` methods non-static
First pass at adding `BaggagePropagator`
Create no-op and multiple text map propagator implementations
* Move `Baggage` tests to API test namespace
Modernize `TraceContextPropagator`
* More test coverage
Move some tests into a `Propagation` namespace
* Properly encode/decode baggage values
* Don't use PHP8 only method
* Make CI happy
* Expose helper method to get a composite propagator
* Move field extraction logic into private method
* Create and move namespaces into `src/` directory
* Update `composer.json`
Move test helpers outside of `SDK` namespace into `Tests`
* Follow PSR naming conventions for interfaces
* Follow PSR naming conventions for abstract classes and traits
* Do a pass on CI configs
* Add examples directory to cs-fixer config
* Fix some erroneously renamed type names
* Return empty object if no spans are passed for OTLPGrpc
* Return empty object if no spans are passed for OtlpHttp
* Remove trailing whitespace
* Remove extra whitespace
* Adding a test to hit line 150 of OtlpGrpc/Exporter.php
* Adding a test through line 162 of OtlpGrpc/Exporter.php
* Updating testExporter's test name to be more specific to what it seems to be doing
* Switching to the normal Mockery syntax to enable argument matching
* Add argument expectations to the 2 new tests
* Fixes after running "make style"
* Fix after running "make psalm"
* Switch out assertEquals for assertSame
* De-duplicate mock client setup
* Forgot to run "make style" on the recent changes
* Fix to PHP 7.4 using non-strict comparison to an integer
* Allow `BatchSpanProcessor` to use any `API\Clock`
Clarify and update batch processor to use `nanoTime` since it is calculating elapsed time
Update unit test to make use of `TestClock`
Add default timestamp to `TestClock`
* Fix lint errors
* Replace `Links` and `Events` types with `array`
Apply limits to links and event attribute lengths
Some minor changes to `API\Event`
* Move `$events` property to non readonly section
Update `.gitignore`
* First pass at updating Span API
* First pass at updated Span implementation
* Update SDK Span return types to `ReadWriteSpan`
Drop support for PHP 7.3
* Finish initial implementation
* Implement `SpanData`
* Implement `StatusData`
* Re-implement and rename `NoopSpan` to `NonRecordingSpan`
* Updates to support `SpanData` in exporters/span processors
* Add timestamp conversion helper methods
Update Exporters to use `SpanData`
Start updating Exporter tests
Implement non immutable `SpanData` test helper class
* Finish updating exporters/converters
* Fix next batch of tests
* First pass at `Tracer` refactor
Leverage a `SpanBuilder` to create the span
Use a dedicated object to share state
* Just use `NonRecordingSpan` constructor versus `create`
Start of adding tests for new Tracer implementation
* Remove some unneeded `max`
Make `Sampler` the 2nd arg to `TraceProvider`
Fix Integration tests
* Add `NoopSpanProcessor`
Continue updating/adding tests
* Install mockery
Ensure span processor is called with expected contexts/spans
* Update `SpanData` to directly return dropped amounts
Make `SpanProcessor#onStart` take a `ReadWriteSpan`
Update empty span fallback name
* Revamp `Clock` interface/implementation
* Add some additional doc comments
Continued work on updating test coverage
* Add more `Span` tests
* Get tests to a passing state
* Fix type errors
* Make CI happy
* Apply limits within `Span` constructor and `SpanBuilder` logic
Add test coverage for these cases
* Return empty object if no spans are passed for OTLPGrpc
* Return empty object if no spans are passed for OtlpHttp
* Remove trailing whitespace
* Remove extra whitespace
* Update `TextMapPropagator` interface
* Update trace context propagator
* Implement `ImplicitContextKeyed`
First pass at moving span activation outside of `Tracer`
* Set span as current when activating in `Tracer`
Fix some tests
* Make CI happy
* Use single method to get context
Add doc comments where needed
Update spec links to use specific version
* Normalize `Link` to use `getContext` as well
Reintroduce `getContext` to `ReadableSpan`
Make CI happy
* Update/Rename getter/setter type to be spec compliant
* Revert `Link` method name change
Makes it more clear you're getting a `SpanContext` not some sort of`LinkContext`
* Rename `makeCurrent` to `activate`
* Rename `Context` methods to better reflect their purpose
* Make carrier the 2nd arg
Implement `KeyedArrayAccess` and rename the propagation getter/setter to `ArrayAccessGetterSetter`
* Fix typing issues
* Update link API to be spec compliant
Remove `addLink` from `Span`
Rename `addLinks` to `addLink` in `SpanOptions`
Add settings attributes and links on `Span` creation
* Update tests and refine API changes
* Fix some psalm errors
* Manually stub grpc to fix psalm errors
Can remove the stub once the root cause is determined
* Add `ext-grpc` to `composer.json`
* Fix psalm security action
* Remove stub in favor of running psalm in single threaded mode
* Implement Link & Links types
Include links when exporting via Otlp Grpc or Protobuf
Use `__toString` instead of `build` to get a string representation of a TraceState
* Assert links are propagated to span created via a tracer
* Fix psalm error
* Fix unit tests
* Add SpanConverter test coverage
2021-09-06 12:17:54 -04:00
1432 changed files with 93181 additions and 18054 deletions
<sub>**Tip**: [React](https://github.blog/news-insights/product-news/add-reactions-to-pull-requests-issues-and-comments/) with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding `+1` or `me too`, to help us triage it. Learn more [here](https://opentelemetry.io/community/end-user/issue-participation/).</sub>
@ -17,3 +17,5 @@ Which alternative solutions or features have you considered?
**Additional context**
Add any other context about the feature request here.
<sub>**Tip**: [React](https://github.blog/news-insights/product-news/add-reactions-to-pull-requests-issues-and-comments/) with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding `+1` or `me too`, to help us triage it. Learn more [here](https://opentelemetry.io/community/end-user/issue-participation/).</sub>
Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer)
Welcome to the OpenTelemetry PHP repository! We appreciate your interest in contributing and helping improve this project. No contribution is too small—whether you're fixing a typo, improving documentation, or implementing a major feature, we value your help.
This repository is part of the larger OpenTelemetry ecosystem, aimed at providing observability solutions for PHP applications. If you have any questions, feel free to ask in our community channels (See further help below). Your contributions make a difference!
Find more information about the approver role in the [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver)
To contribute effectively, ensure you have the following tools installed:
We aim to support officially supported PHP versions, according to https://www.php.net/supported-versions.php. The
developer image `ghcr.io/open-telemetry/opentelemetry-php/opentelemetry-php-base` is tagged as `8.1`, `8.2` and `8.3`
respectively, with `8.1` being the default. You can execute the test suite against other PHP versions by running the
following command:
Find more information about the triager role in the [community repository](https://github.com/open-telemetry/community/blob/master/community-membership.md#triager)
```bash
PHP_VERSION=8.1 make all
#or
PHP_VERSION=8.3 make all
```
For repeatability and consistency across different operating systems, we use the [3 Musketeers pattern](https://3musketeers.pages.dev/). If you're on Windows, it might be a good idea to use Git bash for following the steps below.
**Note: After cloning the repository, copy `.env.dist` to `.env`.**
Skipping the step above would result in a "`The "PHP_USER" variable is not set. Defaulting to a blank string`" warning
We use `docker` and `docker compose` to perform a lot of our static analysis and testing. If you're planning to develop for this library, it'll help to install
[docker engine](https://docs.docker.com/engine/install/) and the [compose plugin](https://docs.docker.com/compose/install/).
Development tasks are generally run through a `Makefile`. Running `make` or `make help` will list available targets.
## Workflow
### Pull Requests
To propose changes to the codebase, you need
to [open a pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request)
to the opentelemetry-php project.
After you open the pull request, the CI will run all the
To ensure your PR doesn't emit a failure with GitHub actions, it's recommended that you run the important CI tests locally with the following command:
```bash
make all # composer update, then run all checks
make all-lowest # composer update to lowest dependencies, then run all checks
```
This does the following things:
* Installs/updates all the required dependencies for the project
* Uses [Rector](https://github.com/rectorphp/rector) to refactor your code according to our standards.
* Uses [php-cs-fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) to style your code using our style preferences.
* Uses [Deptrac](https://github.com/qossmic/deptrac) to check for dependency violations inside our code base
* Makes sure the composer files for the different components are valid
* Runs all of our [phpunit](https://phpunit.de/) unit tests.
* Performs static analysis with [Phan](https://github.com/phan/phan), [Psalm](https://psalm.dev/)
and [PHPStan](https://phpstan.org/user-guide/getting-started)
## Local Run/Build
To ensure you have all the correct packages installed locally in your dev environment, you can run
```bash
make install
```
This will install all the library dependencies to
the `/vendor` directory.
To update these dependencies, you can run
```bash
make update
```
To downgrade to the lowest dependencies, you can run
```shell
make update-lowest
```
To run all checks without doing a composer update:
```shell
make all-checks
```
## Testing
To make sure the tests in this repo work as you expect, you can use the included docker test wrapper.
To run the test suite, execute
```bash
make test
```
This will output the test output as well as a test coverage analysis (text + html - see `tests/coverage/html`). Code
that doesn't pass our currently defined tests will emit a failure in CI
## Contributing Rules
Even though it may not be reflected everywhere in the codebase yet, we aim to provide software which is easy to read and change.
The methods described in Clean Code book(s) by Robert C. Martin (Uncle Bob) are a de facto industry standards nowadays.
Reading those books is highly recommended, however you can take a look at the examples given at [Clean Code PHP](https://github.com/jupeter/clean-code-php).
While we have no rule to strictly follow said methods and patterns, they are highly recommended as an orientation for
your pull requests and to be referenced in reviews.
We might add additional guidelines regarding for example testing in the future.
## Additional Information
### Automatic Refactoring and Upgrading
We use [Rector](https://github.com/rectorphp/rector) to automatically refactor our code according to given standards
and upgrade the code to supported PHP versions.
The associated configuration can be found [here](./.rector.php)
If you want to check what changes would be applied by rector, you can run:
```bash
make rector
```
This command will simply print out the changes `rector` would make without actually changing any code.
To refactor your code following our given standards, you can run:
```bash
make rector-write
```
This command applies the changes to the code base.
Make sure to run `make style` (see below) after running the `rector`command as the changes might not follow our coding standard.
### Styling
We use [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) for our code linting and standards fixer. The
associated configuration can be found [here](./.php-cs-fixer.php)
To ensure that your code follows our coding standards, you can run:
```bash
make style
```
This command executes a required check that also runs during CI. This process performs the required fixes and prints them
out. Code that doesn't meet the style pattern will emit a failure with GitHub actions.
### Static Analysis
We use [Phan](https://github.com/phan/phan/) for static analysis. Currently, our phan configuration is just a standard
default analysis configuration. You can use our phan docker wrapper to easily perform static analysis on your changes.
To run Phan, one can run the following command:
```bash
make phan
```
This process will return 0 on success. Usually this process is performed as part of a code checkin. This process runs
during CI and is a required check. Code that doesn't match the standards that we have defined in
our [phan config](https://github.com/open-telemetry/opentelemetry-php/blob/master/.phan/config.php) will emit a failure
in CI.
We also use [Psalm](https://psalm.dev/) as a second static analysis tool.
You can use our psalm docker wrapper to easily perform static analysis on your changes.
To run Psalm, one can run the following command:
```bash
make psalm
```
This process will return 0 on success. Usually this process is performed as part of a code checkin. This process runs
during CI and is a required check. Code that doesn't match the standards that we have defined in
our [psalm config](https://github.com/open-telemetry/opentelemetry-php/blob/main/psalm.xml.dist) will emit a failure in
CI.
We use [PHPStan](https://github.com/phpstan/phpstan) as our third tool for static analysis. You can use our PHPStan
docker wrapper to easily perform static analysis on your changes.
To perform static analysis with PHPStan run:
```bash
make phpstan
```
This process will return 0 on success. Usually this process is performed as part of a code checkin. This process runs
during CI and is a required check. Code that doesn't match the standards that we have defined in
our [PHPStan config](https://github.com/open-telemetry/opentelemetry-php/blob/main/phpstan.neon.dist) will emit a
failure in CI.
### Code Coverage
We use [codecov.io](https://about.codecov.io/) to track code coverage for this repo. This is configured in the [php.yaml github action](https://github.com/open-telemetry/opentelemetry-php/blob/main/.github/workflows/php.yml#L71-L72). We don't require a specific level of code coverage for PRs to pass - we just use this tool in order to understand how a PR will potentially change the amount of code coverage we have across the code base. This tool isn't perfect - sometimes we'll see small deltas in code coverage where there shouldn't be any - this is nothing to fret about.
If code coverage does decrease on a pull request, you will see a red X in the CI for the repo, but that's ok - the reviewer will use their judgement to determine whether or not we have sufficient code coverage for the change.
### Dependency Validation
To make sure the different components of the library are distributable as separate packages, we have to check
for dependency violations inside the code base. Dependencies must create a [DAC](https://en.wikipedia.org/wiki/Directed_acyclic_graph) in order to not create recursive dependencies.
For this purpose we use [Deptrac](https://github.com/qossmic/deptrac) and the respective configuration can be found
[here](./deptrac.yaml)
To validate the dependencies inside the code base, you can run:
```bash
make deptrac
```
This command will create an error for any violation of the defined dependencies. If you add new dependencies to the code base,
please configure them in the rector configuration.
## PhpMetrics
To generate a report showing a variety of metrics for the library and its classes, you can run:
```bash
make phpmetrics
```
This will generate a HTML PhpMetrics report in the `var/metrics` directory. Make sure to run `make test` before to
create the test log-file, used by the metrics report.
### Proto Generation
Our protobuf files are committed to the repository into the `/proto` folder. These are used in gRPC connections to the
upstream. These get updated when the [opentelemetry-proto](https://github.com/open-telemetry/opentelemetry-proto)
repo has a meaningful update. The maintainer SIG is discussing a way to make this more automatic in the future.
To generate protobuf files for use with this repository, you can run the following command:
```bash
make protobuf
```
This will replace `proto/otel/Opentelemetry` and `proto/otel/GPBMetadata` with freshly generated code based on the
latest tag from `opentelemetry-proto`, which can then be committed.
### Semantic Conventions Generation
Autogenerated semantic convention files are committed to the repository in the `/src/SemConv` directory. These files are
updated manually when a new version of [semantic-conventions](https://github.com/open-telemetry/semantic-conventions) is
released.
```bash
SEMCONV_VERSION=1.8.0 make semconv
```
Run this command in the root of this repository.
### API Documentation
We use [phpDocumentor](https://phpdoc.org/) to automatically generate API documentation from DocBlocks in the code.
To generate a recent version of the API documentation, you can run:
```bash
make phpdoc
```
To preview the documentation and changes you might expect, you can run:
```bash
make phpdoc-preview
```
This will start a HTTP server running at <http://localhost:8080> serving the updated documentation files.
- [Brett McBride](https://github.com/brettmc/), Deakin University
For more information about the maintainer role, see the [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer).
For more information about the approver role, see the [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver).
## Triagers
For more information about the triager role, see the [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#triagers).
For more information about the emeritus role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager).
## Further Help
Most of our communication is done on CNCF Slack in the channel [otel-php](https://cloud-native.slack.com/archives/C01NFPCV44V).
To sign up, create a CNCF Slack account [here](http://slack.cncf.io/)
Our meetings are held weekly on zoom on Wednesdays at 10:30am PST / 1:30pm EST.
A Google calendar invite with the included zoom link can be found [here](https://calendar.google.com/event?action=TEMPLATE&tmeid=N2VtZXZmYnVmbzZkYjZkbTYxdjZvYTdxN21fMjAyMDA5MTZUMTczMDAwWiBrYXJlbnlyeHVAbQ&tmsrc=google.com_b79e3e90j7bbsa2n2p5an5lf60%40group.calendar.google.com&scp=ALL)
Our open issues can all be found in the [GitHub issues tab](https://github.com/open-telemetry/opentelemetry-php/issues). Feel free to reach out on Slack if you have any additional questions about these issues; we are always happy to talk through implementation details.
#### Thanks to all the people who already contributed!
smoke-test-examples:smoke-test-isolated-examplessmoke-test-exporter-examplessmoke-test-collector-integrationsmoke-test-prometheus-example## Run smoke test examples
smoke-test-isolated-examples:## Run smoke test isolated examples
This is the **[monorepo](https://en.wikipedia.org/wiki/Monorepo)** for the **main** components of [OpenTelemetry](https://opentelemetry.io/) for PHP.
This project currently lives in a pre-alpha status. Our current release is not production ready; it has been created in order to receive feedback from the community.
## Documentation
We attempt to keep the [OpenTelemetry Specification Matrix](https://github.com/open-telemetry/opentelemetry-specification/blob/master/spec-compliance-matrix.md) up to date in order to show which features are available and which have not yet been implemented.
Please read the official documentation: https://opentelemetry.io/docs/instrumentation/php/
If you find an inconsistency in the data in the matrix vs. the data in this repository, please let us know in our slack channel and we'll get it rectified.
## Communication
Most of our communication is done on CNCF Slack, in the [otel-php](https://cloud-native.slack.com/archives/C01NFPCV44V) channel. To sign up, create a CNCF slack account here http://slack.cncf.io/
API Documentation is available here: https://open-telemetry.github.io/opentelemetry-php/
Our meetings are held weekly on zoom on Wednesdays at 10:30am PST / 1:30pm EST.
A Google calendar invite with the included zoom link can be found [here](https://calendar.google.com/event?action=TEMPLATE&tmeid=N2VtZXZmYnVmbzZkYjZkbTYxdjZvYTdxN21fMjAyMDA5MTZUMTczMDAwWiBrYXJlbnlyeHVAbQ&tmsrc=google.com_b79e3e90j7bbsa2n2p5an5lf60%40group.calendar.google.com&scp=ALL)
## Packages and versions
Our open issues can all be found in the [github issues tab](https://github.com/open-telemetry/opentelemetry-php/issues). Feel free to reach out on Slack if you have any additional questions about these issues; we are always happy to talk through implementation details.
To your project's `composer.json` file, as this utility has not reached a stable release status yet.
[](https://github.com/open-telemetry/opentelemetry-php/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) [](https://github.com/open-telemetry/opentelemetry-php/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) [](https://github.com/open-telemetry/opentelemetry-php/pulls?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) [](https://github.com/open-telemetry/opentelemetry-php/issues?q=is%3Aopen)
2.) Install the dependency with composer:
We would love to have you on board, please see our [Contributing README](./CONTRIBUTING.md)
```bash
$ composer require open-telemetry/opentelemetry
```
## Specification conformance
## Development
We use `docker` and `docker-compose` to perform a lot of our static analysis and testing.
We attempt to keep the [OpenTelemetry Specification Matrix](https://github.com/open-telemetry/opentelemetry-specification/blob/master/spec-compliance-matrix.md) up to date in order to show which features are available and which have not yet been implemented.
If you're planning to develop for this library, it'll help to install `docker engine` and `docker-compose`.
If you find an inconsistency in the data in the matrix, please let us know in our slack channel and we'll get it rectified.
You can find installation instructions for these packages can be found [here](https://docs.docker.com/install/), under the `Docker Engine` and `Docker Compose` submenus respectively.
## Backwards compatibility
To ensure you have all the correct packages installed locally in your dev environment, you can run
See [compatibility readme](src/SDK/Common/Dev/Compatibility/README.md).
```bash
make install
```
From your bash compatible shell. This will install all of the necessary vendored libraries that the project uses to
the
`/vendor` directory.
To update these dependencies, you can run
```bash
make update
```
In order to update all the vendored libraries in the `/vendor` directory.
## Pull Requests
Once you've made the update to the codebase that you'd like to submit, you may [create a pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request) to the opentelemetry-php project.
After you open the pull request, the CI/CD pipeline will run all of the associated [github actions](https://github.com/open-telemetry/opentelemetry-php/actions/workflows/php.yml).
You can simulate the important github actions locally before you submit your PR by running the following command:
```bash
make install && make update && make style && make test && make phan && make psalm && make phpstan
```
from your bash compatible shell. This does the following things:
* Installs all the required dependencies for the project and ensures they are up to date
* Uses [php-cs-fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) to style your code using our style preferences.
* Runs all of our [phpunit](https://phpunit.de/) unit tests.
* Performs static analysis with [Phan](https://github.com/phan/phan), [Psalm](https://psalm.dev/) and [PHPStan](https://phpstan.org/user-guide/getting-started)
## Proto Generation
Our proto files are committed to the repository into the `/proto` folder. These are used in gRPC connections to the
upstream. These get updated when the [opentelemetry-proto](https://github.com/open-telemetry/opentelemetry-proto)
repo has a meaningful update. The maintainer SIG is discussing a way to make this more automatic in the future.
If you'd like to generate proto files for use with this repository, one can run the following command:
```bash
make proto
```
From your bash compatible shell in the root of this directory. This wil create a `/proto` folder in the root
directory of the
repository.
## Styling
We use [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) for our code linting and standards fixer. The associated configuration for this standards fixer can be found in the root of the repository [here](https://github.com/open-telemetry/opentelemetry-php/blob/master/.php_cs)
To ensure that your code is stylish, you can run the follwing command:
```bash
make style
```
from your bash compatible shell. This process will print out the fixes that it is making to your
associated files. Usually this process is performed as part of a code checkin. This process runs during CI and is a required check. Code that doesn't follow this style pattern will emit a failure in CI.
## Static Analysis
We use [Phan](https://github.com/phan/phan/) for static analysis. Currently our phan configuration is just a standard default analysis configuration. You can use our phan docker wrapper to easily perform static analysis on your changes.
To run Phan, one can run the following command:
```bash
make phan
```
from your bash compatible shell.
This process will return 0 on success.
Usually this process is performed as part of a code checkin. This process runs during CI and is a required check. Code that doesn't match the standards that we have defined in our [phan config](https://github.com/open-telemetry/opentelemetry-php/blob/master/.phan/config.php) will emit a failure in CI.
We also use [Psalm](https://psalm.dev/) as a second static analysis tool.
You can use our psalm docker wrapper to easily perform static analysis on your changes.
To run Psalm, one can run the following command:
```bash
make psalm
```
from your bash compatible shell. This process will return 0 on success. Usually this process is performed as part of a code checkin. This process runs during CI and is a required check. Code that doesn't match the standards that we have defined in our [psalm config](https://github.com/open-telemetry/opentelemetry-php/blob/main/psalm.xml.dist) will emit a failure in CI.
We use [PHPStan](https://github.com/phpstan/phpstan) as our third tool for static analysis.
You can use our PHPStan docker wrapper to easily perform static analysis on your changes.
Execute `make phpstan` from your bash compatible shell. This process will return 0 on success. Usually this process is
performed as part of a code checkin. This process runs during CI and is a required check. Code that doesn't match the
standards that we have defined in
our [PHPStan config](https://github.com/open-telemetry/opentelemetry-php/blob/main/phpstan.neon.dist) will emit a failure
in CI.
## Testing
To make sure the tests in this repo work as you expect, you can use the included docker test wrapper.
To run the test suite, execute
```bash
make test
```
from your bash compatible shell. This will output the test output as well
as a test coverage analysis. Code that doesn't pass our currently defined tests will emit a failure in CI
## Examples
### Trace
You can use the [examples/AlwaysOnZipkinExample.php](/examples/AlwaysOnZipkinExample.php) file to test out the reference implementation we have for zipkin. This example perfoms a sample trace with a grouping of 5 spans and POSTs the result to a local zipkin instance.
You can also use the [examples/AlwaysOnJaegerExample.php](/examples/AlwaysOnJaegerExample.php) file to test out the reference implementation we have for jaegar. This example perfoms a sample trace with a grouping of 5 spans and POSTs the result to a local jaegar instance.
You can use the [examples/AlwaysOnZipkinToNewrelicExample.php](/examples/AlwaysOnZipkinToNewrelicExample.php) file to test out the reference implementation we have for zipkin to Newrelic. This example perfoms a sample trace with spans and POSTs the result to a Newrelic endpoint. This requires a license key (free accounts available) to be set in the environment (NEW_RELIC_INSERT_KEY) to authenticate to the backend.
You can use the [examples/AlwaysOnNewrelicExample.php](/examples/AlwaysOnNewrelicExample.php) file to test out the reference implementation we have for Newrelic. This example perfoms a sample trace with spans and POSTs the result to a Newrelic endpoint. This requires a license key (free accounts available) set in the environment (NEW_RELIC_INSERT_KEY) to authenticate to the backend.
The PHP for all examples should execute by itself (if you have a zipkin or jaegar instance running on localhost), but if you'd like a no-fuss way to test this out with docker and docker-compose, you can perform the following simple steps:
1.) Install the necessary dependencies by running `make install`. This will install the composer dependencies and store them in `/vendor`
2.) Execute the example trace using `make trace examples`.
Exported spans can be seen in zipkin at [http://127.0.0.1:9411](http://127.0.0.1:9411)
Exported spans can also be seen in jaeger at [http://127.0.0.1:16686](http://127.0.0.1:16686)
### Metrics
You can use the [examples/prometheus/PrometheusMetricsExample.php](/examples/prometheus/PrometheusMetricsExample.php) file to test out the reference implementation we have. This example will create a counter that will be scraped by local Prometheus instance.
The easy way to test the example out with docker and docker-compose is:
1.) Run `make metrics-prometheus-example`. Make sure that local ports 8080, 6379 and 9090 are available.
2.) Open local Prometheus instance: http://localhost:9090
3.) Go to Graph section, type "opentelemetry_prometheus_counter" in the search field or select it in the dropdown menu. You will see the counter value. Every other time you run `make metrics-prometheus-example` will increment the counter but remember that Prometheus scrapes values once in 10 seconds.
4.) In order to stop docker containers for this example just run `make stop-prometheus`
## User Integration Guides
* [Integrating OpenTelemetry PHP into Laravel Applications](./docs/laravel-integration.md)
* [Integrating OpenTelemetry PHP into Symfony Applications](./docs/symfony-integration.md)
## Versioning
OpenTelemetry for PHP aims to support all officially supported PHP versions according to https://www.php.net/supported-versions.php, and
support will be dropped for PHP versions within 12 months of that version going _End of life_.
Versioning rationale can be found in the [Versioning Documentation](/docs/versioning.md)
# Integrating Opentelemetry PHP into Laravel Applications
## Introduction
Distributed tracing helps developers and management gain insights into how well applications perform in terms of traces, metrics, and logs. This guide shows how developers can integrate OpenTelemetry PHP into their Laravel applications for the above benefits. Our example application visualizes exceptions from a Laravel application using both Jaeger and Zipkin.
To follow this guide you will need:
* PHP Installed; this example uses PHP 7.4.
* [Composer](https://getcomposer.org/download/ ) for dependency management.
* [Docker](https://docs.docker.com/get-docker/) for bundling our visualization tools. We have setup instructions for docker on this project's [readme](https://github.com/open-telemetry/opentelemetry-php#development).
This example uses Laravel version 8.40 .
## Step 1 - Creating a Laravel Application
The Laravel framework supports creating applications using composer. To do that, run `composer create-project <project-name>` . We are naming our project `otel-php-laravel-basic-example`, so the command is as follows:
To confirm that our application works, we can move to the application directory using `cd otel-php-laravel-basic-example` , then serve the application with `php artisan serve` .
Starting from version `v.0.0.2`, the open-telemetry php package allows users to use their preferred HTTP layers for exporting traces. The benefit of this is that users can reuse already existing HTTP configurations for their applications. Hence, there is need to require packages that satisfy both `psr/http-client-implementation` and `psr/http-factory-implementation` before requiring the opentelemetry-php package.
By default, the Laravel framework utilizes `guzzlehttp/guzzle` and this satisfies `psr/http-client-implementation`, so we need to require the `guzzlehttp/psr7` to meet the `psr/http-factory-implementation` requirement. Let's run `composer require guzzlehttp/psr7:2.0.0-rc1`.
Note: We are specifying `2.0.0-rc1` as that is the release for `guzzlehttp/psr7` that includes HTTP factories as at the time of writing this guide.
Next, let's run `composer require open-telemetry/opentelemetry` to pull in the openTelemetry-php package.
## Step 3 - Bundle Zipkin and Jaeger into the Application
To visualize traces exported from our application, we need to integrate open source tracing tools [Zipkin](https://zipkin.io/) and [Jaeger](https://www.jaegertracing.io/) into our setup using docker.
First, we create a `docker-compose.yaml` file in the root of our project, with content as follows:
```yaml
version: '3.7'
services:
zipkin:
image: openzipkin/zipkin-slim
ports:
- 9411:9411
jaeger:
image: jaegertracing/all-in-one
environment:
COLLECTOR_ZIPKIN_HOST_PORT: 9412
ports:
- 9412:9412
- 16686:16686
```
Next, we pull in Zipkin and Jaeger by running `docker-compose up -d`. This might take some time, depending on your internet connection speed.
We can confirm that Zipkin is up by navigating to `http://localhost:9411/` on our browser. For Jaeger, navigating to `http://localhost:16686/` on our browser should display the Jaeger home page.
For this step, we will utilize our OpenTelemetry PHP Library to export traces to both Zipkin and Jaeger.
The default entry point for Laravel applications is the `index.php` file located in the `public` folder. If we navigate to `public\index.php` we can see that the index file autoloads classes from packages within our vendor folder, making them easily useable within our application.
```php
require __DIR__.'/../vendor/autoload.php';
```
The other parts of the `index.php` file enable request and response resolution using the application kernel.
It is worthy of note that resources(namespaces, classes, variables) created within the `index.php` file are available within the entire application.
To use open-telemetry specific classes within our application we have to import them at the top of our index file, using the `use` keyword. This is what our list of open-telemetry imported classes should look like:
```php
use OpenTelemetry\Contrib\Jaeger\Exporter as JaegerExporter;
use OpenTelemetry\Contrib\Zipkin\Exporter as ZipkinExporter;
use OpenTelemetry\Sdk\Trace\Clock;
use OpenTelemetry\Context\Context;
use OpenTelemetry\Sdk\Trace\Sampler\AlwaysOnSampler;
use OpenTelemetry\Sdk\Trace\SamplingResult;
use OpenTelemetry\Sdk\Trace\SpanProcessor\BatchSpanProcessor;
use OpenTelemetry\Sdk\Trace\TracerProvider;
use OpenTelemetry\Trace as API;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\HttpFactory;
```
Remember that these imports should go side by side with the default class imports that come with the `index.php` file.
Next, we create a sample recording trace using the [AlwaysOnSampler](https://github.com/open-telemetry/opentelemetry-php/blob/main/sdk/Trace/Sampler/AlwaysOnSampler.php) class, just before the app instance is created like below:
```php
$sampler = new AlwaysOnSampler();
$samplingResult = $sampler->shouldSample(
new Context(),
md5((string) microtime(true)),
'io.opentelemetry.example',
API\SpanKind::KIND_INTERNAL
);
```
Since we are looking to export traces to both Zipkin and Jaeger we have to make use of their exporters;
```php
$jaegerExporter = new JaegerExporter(
'Hello World Web Server Jaeger',
'http://localhost:9412/api/v2/spans',
new Client(),
new HttpFactory(),
new HttpFactory()
);
$zipkinExporter = new ZipkinExporter(
'Hello World Web Server Zipkin',
'http://localhost:9411/api/v2/spans',
new Client(),
new HttpFactory(),
new HttpFactory()
);
```
Next, we create a trace then add processors for each trace(One for Jaeger and another for Zipkin). Then we proceed to start and activate a span for each trace. We create a trace only if the RECORD AND SAMPLED sampling result condition passes as follows;
```php
if (SamplingResult::RECORD_AND_SAMPLE === $samplingResult->getDecision()) {
$jaegerTracer = (new TracerProvider(null, $sampler))
Finally, we end the active spans if sampling is complete, by adding the following block at the end of the `index.php` file;
```php
if (SamplingResult::RECORD_AND_SAMPLE === $samplingResult->getDecision()) {
$zipkinSpan->end();
$jaegerSpan->end();
}
```
Let's confirm that we can see exported traces on both Zipkin and Jaeger. To do that, we need to reload `http://127.0.0.1:8000` on our browser;
We also need reload both Zipkin and Jaeger on our browser, using the URLs `http://localhost:9411/` and `http://localhost:16686/`. Do ensure that both your Laravel server and docker instance are running for this step.
For Jaeger under service, you should see a `Hello World Web Server Jaeger` service. Go ahead and click find traces to see exported traces.
Since resources in Laravel's `public\index.php` file are available to the entire application, we can use any of the already instantiated tracers to further instrument controllers or any other parts of our application.
Let's create a `Hello` controller to check this out. Run the command `php artisan make:controller HelloController`
Next we need to add a route for accessing the controller. To do this we need to utilize the `HelloController` class within our web routes file located in the `routes\web.php` as follows:
```php
use App\Http\Controllers\HelloController;
```
Next we need to add a route and method for the controller.
The above snippet routes every GET request from the `/hello` route on the browser to an index method within the `HelloController` class. For now, this method does not exist, so we have to add it to our controller as follows
```php
public function index(){
return "hello";
}
```
Let's confirm that everything works well by visiting the `/hello` route on our browser.
In the above snippet we change the span name and attributes for our Zipkin trace, we also add an exception event to the span.
We need to reload our `http://127.0.0.1:8000/hello` route, then navigate to Zipkin like before, to see that our span name gets updated to `new name` and our `Exception Example` is visible.
With the above example we have been able to instrument a Laravel application using the OpenTelemetry PHP library. You can fork the example project [here](https://github.com/prondubuisi/otel-php-laravel-basic-example).
# Integrating Opentelemetry PHP into Symfony Applications
## Introduction
As a developer, you might be wondering how OpenTelemetry could be beneficial to you. Without practical examples, the usefulness of distributed tracing can be difficult to grasp for persons without a cloud or site reliability engineering background. This user guide shows how OpenTelemetry could be useful to gain insights into exceptions happening within an application. This example uses the OpenTelemtry PHP library integrated into a Symfony application, bundled with Jaeger and Zipkin, for visualizing data.
## Prerequisites
To follow this guide you will need:
* PHP Installed, this example uses PHP 7.4.
* [Composer](https://getcomposer.org/download/ ) for dependency management.
* [Symfony CLI](https://symfony.com/download) for managing your Symfony application.
* [Docker](https://docs.docker.com/get-docker/) for bundling our visualization tools. We have setup instructions for docker on this project's [readme](https://github.com/open-telemetry/opentelemetry-php#development).
This example uses Symfony version 5.2 .
## Step 1 - Creating a Symfony Application
Create a Symfony application by running the command `symfony new my_project_name`. We are calling this example `otel-php-symfony-basic-example`, so the command is as follows;
`symfony new otel-php-symfony-basic-example` .
## Step 2 - Require and Test Symfony Dependencies
To define our routes within our controller methods, let's require the Doctrine annotation library by running the command `composer require doctrine/annotations`.
We can test that routes defined within Controllers work by creating a `HelloController.php` file within the `src\Controller` folder as follows:
```php
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class HelloController extends AbstractController
{
/**
* @Route("/hello", name="hello")
*/
public function index(): Response
{
return new Response('Hello World');
}
}
```
To check out the routes available in our current project run `php bin/console debug:router`.
For this step, we require the OpenTelemetry PHP Library by running the command `composer require open-telemetry/opentelemetry`. It is worthy of note that this command pulls in the last stable release for the library.
## Step 4 - Bundle Zipkin and Jaeger into the Application
To visualize traces from our application, we have to bundle open source tracing tools [Zipkin](https://zipkin.io/) and [Jaeger](https://www.jaegertracing.io/) into our application using docker.
Let's add a `docker-compose.yaml` file in the root of our project with the content as follows:
```yaml
version: '3.7'
services:
zipkin:
image: openzipkin/zipkin-slim
ports:
- 9411:9411
jaeger:
image: jaegertracing/all-in-one
environment:
COLLECTOR_ZIPKIN_HTTP_PORT: 9412
ports:
- 9412:9412
- 16686:16686
```
To confirm that docker is installed and running on our system, we can run the hello world docker example using the command `docker run -it --rm hello-world`. If everything works well, run `docker-compose up -d` to pull in Zipkin and Jaeger. This might take some time, depending on your internet connection speed.
We can confirm that Zipkin is up by navigating to `http://localhost:9411/` on our browser. For Jaeger, navigating to `http://localhost:16686/` on our browser should display the Jaeger home page.
Now it is time to utilize our OpenTelemetry PHP Library to export traces to both Zipkin and Jaeger.
## Step 5 - Instrument Symfony Application
The entry point for all Symfony applications is the `index.php` file located in the `public` folder. Let's navigate to `public\index.php` to see what is happening. It is worthy of note that resources(namespaces, classes, variables) created within the `index.php` file are available within the entire application, by default the index file imports all auto loaded classes within the vendor folder. It also imports contents of the `.env` file. The other parts of the `index.php` file enable debugging as well as support request and response resolution using the application kernel.
To use open-telemetry specific classes we have to import them at the top of our index file, using the `use` keyword. This is what our imports look like:
```php
use App\Kernel;
use OpenTelemetry\Contrib\Jaeger\Exporter as JaegerExporter;
use OpenTelemetry\Contrib\Zipkin\Exporter as ZipkinExporter;
use OpenTelemetry\Sdk\Trace\Clock;
use OpenTelemetry\Sdk\Trace\Sampler\AlwaysOnSampler;
use OpenTelemetry\Sdk\Trace\SamplingResult;
use OpenTelemetry\Sdk\Trace\SpanProcessor\BatchSpanProcessor;
use OpenTelemetry\Sdk\Trace\TracerProvider;
use OpenTelemetry\Trace as API;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\ErrorHandler\Debug;
use Symfony\Component\HttpFoundation\Request;
```
Next, we create a sample recording trace using the [AlwaysOnSampler](https://github.com/open-telemetry/opentelemetry-php/blob/main/sdk/Trace/Sampler/AlwaysOnSampler.php) class, just before the Kernel instance is created like below:
```php
$sampler = new AlwaysOnSampler();
$samplingResult = $sampler->shouldSample(
null,
md5((string) microtime(true)),
substr(md5((string) microtime(true)), 16),
'io.opentelemetry.example',
API\SpanKind::KIND_INTERNAL
);
```
Since we are looking to export traces to both Zipkin and Jaeger we have to make use of their individual exporters;
```php
$jaegerExporter = new JaegerExporter(
'Hello World Web Server Jaeger',
'http://localhost:9412/api/v2/spans'
);
$zipkinExporter = new ZipkinExporter(
'Hello World Web Server Zipkin',
'http://localhost:9411/api/v2/spans'
);
```
Next we create a trace, and add processors for each trace(One for Jaeger and another for Zipkin). Then we proceed to start and activate a span for each trace. We create a trace only if the RECORD AND SAMPLED sampling result condition passes as follows;
```php
if (SamplingResult::RECORD_AND_SAMPLED === $samplingResult->getDecision()) {
$jaegerTracer = (new TracerProvider(null, $sampler))
Finally we end the active spans if sampling is complete, by adding the following block at the end of the `index.php` file;
```php
if (SamplingResult::RECORD_AND_SAMPLED === $samplingResult->getDecision()) {
$zipkinSpan->end();
$jaegerSpan->end();
}
```
lets confirm that we can see exported traces on both Zipkin and Jaeger. To do that we need to reload `http://127.0.0.1:8000/hello` or any other route on our symfony server;
We also need reload both Zipkin and Jaeger on our browser, using the URLs `http://localhost:9411/` and `http://localhost:16686/`. Do ensure that both your symfony server and docker instance are running for this step.
For Jaeger under service, you should see a `Hello World Web Server Jaeger` service, go ahead and click find traces to see exported traces.
Since resources in Symfony's `public\index.php` file are available to the entire application, we can use any of the already instantiated tracers within `HelloController`. In addition to the tracers, we can also utilize associated properties, methods and events.
Lets try using the `addEvent` method, to capture errors within our controller as follows:
In the above snippet we change the span name and attributes for our Zipkin trace, we also add an exception event to the span.
We need to reload our `http://127.0.0.1:8000/hello` route, then navigate to Zipkin like before to see that our span name gets updated to `new name` and our `Exception Example` is visible
With the above example we have been able to instrument a Symfony application using the OpenTelemetry php library. You can fork the example project [here](https://github.com/prondubuisi/otel-php-symfony-basic-example). You can also checkout the original test application [here](https://github.com/dkarlovi/opentelemetry-php-user-test).