opentelemetry-php icon indicating copy to clipboard operation
opentelemetry-php copied to clipboard

Support for FrankenPHP

Open benr77 opened this issue 7 months ago • 13 comments

Does this package provide support for working with FrankenPHP? I've tried in vain to get it to work via opentelemetry-php/contrib-auto-symfony but have had no luck whatsoever. It seems all the env var configuration is completely ignored.

Thank you.

benr77 avatar May 24 '25 07:05 benr77

There is support already built in to FrankenPHP - see https://github.com/dunglas/frankenphp/issues/1608#issuecomment-2906779395

benr77 avatar May 24 '25 11:05 benr77

Just so that you're clear, the tracing in frankenphp is not the same thing as opentelemetry-php. It looks like it will create a span for the incoming web request, but not the php application itself. If that's all you need, then great, but if you also want tracing of the internals of a Symfony application, outbound distributed trace headers etc, then you need opentelemetry-php.

brettmc avatar May 25 '25 00:05 brettmc

OK so I wasn't fully understanding this because I do want tracing of the actual Symfony app. Thank you for pointing this out!

I have reopened this issue because my attempts to implement opentelemetry-php have not been successful with FrankenPHP so I could do with some more info.

Has anybody managed to get it set up this way? Thanks

benr77 avatar May 25 '25 04:05 benr77

I don't have any specific experience with frankenphp, however if it's running PHP and using composer, it should work. The first things to check are that you've followed all of the requirements documented in https://opentelemetry.io/docs/zero-code/php/ (have you installed the extension and the SDK as well as contrib-auto-symfony?)

If those are all ok, if you var_dump($_ENV) from your index.php do you see all the environment variables you expect? Especially OTEL_PHP_AUTOLOAD_ENABLED=true.

brettmc avatar May 25 '25 09:05 brettmc

@benr77 Can you elaborate a bit:

  1. do you run in worker mode?
  2. do you run in regular mode?
  3. do you use auto-instrumentation package? do you have env variable for auto load set to true ?
  4. in worker mode, you need to start root span in closure and end it there, then call force flush/shutdown to "close" everything in preparation for the next request.

hostaway-greg avatar May 26 '25 09:05 hostaway-greg

Not using worker mode at the moment, but plan to in the near future.

Was using https://github.com/opentelemetry-php/contrib-auto-symfony package yes.

Env vars were all set but my hunch is that they were not reaching the package, so the telemetry was trying to lookup localhost which was simply timing out with the PHP max execution time.

My dev site is in Docker, but Signoz installed on remote server, so the hostname/IP of Signoz I set in the env var was not being respected.

I checked I could ping the remote Signoz installation on the correct port from with the Docker container so no worries there.

benr77 avatar May 26 '25 10:05 benr77

Do you use opentelemetry collector ? If yes then you can add debug exporter and see in the console. If not then you should add it to see debug in console ;)

Regular mode should work out of the box, worker mode is the problem.

GrzegorzDrozd avatar May 29 '25 14:05 GrzegorzDrozd

Related to https://github.com/open-telemetry/opentelemetry-php/issues/1496#issuecomment-2645907919 ? That's for Laravel, but depending on how you start your application, could it be the same issue of OTEL_* env vars not being propagated to a newly-spawned process? If that's the case, you could try to put all of your config into a .ini file (php.ini or another that's loaded by php at startup)

brettmc avatar Jun 13 '25 04:06 brettmc

In FrankenPHP there is no fork/thread/spawn of sub/processes/childs. I think problem is that you need to create root span within frankenphp_handle_request and end it there near the end of handler code. Creating span/trace in "worker" code will make it super long AND it will cover multiple requests. Also: otel relies heavily on register shutdown function which is NOT called until worker process actually ends. You need to duplicate \OpenTelemetry\SDK\Common\Util\ShutdownHandler::register to call all this at request end OR get Span/Metric Collector and flush it after request

GrzegorzDrozd avatar Jun 13 '25 08:06 GrzegorzDrozd

Also: otel relies heavily on register shutdown function which is NOT called until worker process actually ends. You need to duplicate \OpenTelemetry\SDK\Common\Util\ShutdownHandler::register to call all this at request end OR get Span/Metric Collector and flush it after request

I often run opentelemetry-instrumented apps through roadrunner, which I think is similar. The issue you're describing is that we don't have true async export, so when the batch export delay passes, export will not happen until a span is ended (and sent to the batch processor) after that time. That's usually part of a subsequent request. The data will be exported eventually, but if you have 8 workers and not many requests, it can take a while before the worker with enqueued traces next gets the change to export. As a workaround, I do the second option: manually flush after each request.

I think problem is that you need to create root span within frankenphp_handle_request and end it there near the end of handler code.

Yes, that's pretty much what I do with RoadRunner...

brettmc avatar Jun 13 '25 11:06 brettmc

OK so I now have this working correctly, and wanted to document the issue here for future reference.

In our development environment, we are running a Symfony app inside a Docker container with Docker Compose, and are configuring via opentelemetry-php/contrib-auto-symfony.

As @brettmc commented:

If those are all ok, if you var_dump($_ENV) from your index.php do you see all the environment variables you expect? Especially OTEL_PHP_AUTOLOAD_ENABLED=true.

I went and used dd($_ENV) in a controller, to check if the environment variables were present.

When I enter the OTEL_ environment variables into our .env.dev.local file, to be picked up as usual by Symfony's DotEnv component, the above dd() command does correctly show the variables in the $_ENV, however, no telemetry data is sent.

Conversely, when I enter the OTEL_ env vars into the docker-compose.yml via the environment key (i.e. expose them into the actual container environment, instead of relying on the DotEnv component), the variables DO NOT show in the dd() yet the telemetry data is sent correctly

This is extremely counter-intuitive, but I guess all of the documentation does say configure via environment variables and nowhere I have seen says DotEnv is supported.

Is this because the OpenTelemetry PHP extension is looking for the environment variables before the DotEnv component can populate them?

For Symfony applications it is common and recommended practice to use .env files, so I can see this tripping up users often enough - perhaps a note in the docs to say this won't work would be good?

Thanks

benr77 avatar Jun 28 '25 14:06 benr77

Is this because the OpenTelemetry PHP extension is looking for the environment variables before the DotEnv component can populate them?

Yes, the SDK is initialized (using composer autoload/files) before the SymfonyRuntime/FrankenPhpSymfony\Runtime calls DotEnv::bootEnv().

This is extremely counter-intuitive, but I guess all of the documentation does say configure via environment variables and nowhere I have seen says DotEnv is supported.

https://github.com/open-telemetry/opentelemetry-php/pull/1523 will add DotEnv support.

Nevay avatar Jun 28 '25 20:06 Nevay

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] avatar Oct 18 '25 05:10 stale[bot]