open-telemetry / opentelemetry-php

The OpenTelemetry PHP Library
https://opentelemetry.io/docs/instrumentation/php/
Apache License 2.0
751 stars 186 forks source link

Do we have any plan about auto instrumentation? #402

Closed tydhot closed 2 years ago

tydhot commented 3 years ago

I have found a project lately: https://github.com/SkyAPM/SkyAPM-php-sdk. It support auto instrument for php app. I think if we can support the auto instrumentation, it will be an exciting feature for otel php user too. Do we have any plan about this?

bobstrecansky commented 3 years ago

There is not currently a plan for auto-instrumentation. Would love to hear suggestions / implementations if you have them!

Grunet commented 3 years ago

More of an experience report, but I had a chance to try out OTEL auto instrumentation for a simple (Node) Express server during a recent workshop (and it was super cool!), and from what I could tell the npm package being used specifically to instrument Express was doing some form of "monkey patching" of Express's methods (I think maybe hooking into Node's module require system iirc) to layer on the instrumentation from the core Node/JS OTEL library.

I'd be very curious if a pattern like that would be viable for PHP. Like say every framework/library got their own package on top of OTEL-PHP that would then monkey-patch (via reflection?) it the first time it gets used (maybe by adjusting autoloaders or similar?). I'm still new to PHP so I have no idea if that could even be possible...

tidal commented 3 years ago

Monkey patching is not possible with "vanilla PHP", but there are the runkit, componere and uopz extensions which allow for monkey patching (SkyAPM-php-sdk is an extension, too, btw.)

However such "hacks" are not necessarily needed to make auto instrumentation possible. Since I took over the creation of the Symfony bundle, you will see (Once I pushed my first draft), that it will just work out-of-the-box, without touching any code. Adjustments can be made via configuration and/or env vars. This is possible, because it leverages Symfony's event system, which is the standard way to hook into its front controller and request/response flow. Later on it will be possible to implement the same for DB queries, since the Doctrine ORM (used by Symfony) exposes lifecycle events as well.

Other frameworks have similar event systems or use AOP to get cross cutting concerns out of application code.

For a general purpose auto instrumentation, yes, using the autoloader is not a bad idea. A simple composer plugin could provide a wrapper for the standard autoload function to start tracing and a shutdown function could stop it. This would allow for a single span per request, and basic configuration could be done via env vars and/or the "extra" entry in composer.json.

To provide more granular auto instrumentation for frameworks/libs which don't come with events or aop, there are still possibilities without using one of the mentioned extensions. Basically PHP allows to hook into or even replace the behavior of every standard I/O operation via stream filters/wrappers. This includes file access and specifically also expressions like "require_once", etc. This would allow to create wrappers for specific classes by simply patching the namespace of said class. To initialize this behavior a autoload wrapper (as above) can be used.

Besides file operations stream wrappers can also filter, manipulate or replace any HTTP call (even via curl). This allows for tracing API calls and/or propagating trace contexts without touching any application code.

Last but not least, it's also possible to create handlers for custom "protocols" like "jaeger+http://", though I cannot come up with any real use case atm.

haad commented 2 years ago

Hmm so what would be actual way how we can add auto tracers to quite simple sympfony based php application.

Is it even possible without extension and can it work without any library changes ?

tidal commented 2 years ago

@haad In case of Symfony that's fairly easy and doesn't need any extension or changes to the library. First off Symfoyn exposes life-cyle events, which are easy to hook into. You can find an example here: https://github.com/opentelemetry-php/otel-sdk-bundle-example-sf5/blob/main/src/EventSubscriber/OtelKernelSubscriber.php

But even without events it's possible to create decoraters for all types of "services" in Symfony in a bundle configuration and/or with compiler passes.

All of above is what should be implemented in the Symfony InstrumentationBundle: https://github.com/open-telemetry/opentelemetry-php/issues/568

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 2 years ago

This issue has been automatically closed because it has not had recent activity, but it can be reopened. Thank you for your contributions.