brettmc / otel-php-rust
Prototype SDK + auto-instrumentation using Rust
Installs: 20
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
Language:Rust
Type:php-ext
Requires
- php: ^8.0
This package is auto-updated.
Last update: 2025-03-03 07:21:34 UTC
README
Intro
This is a prototype PHP extension, using phper to expose opentelemetry-rust via PHP classes and implement auto-instrumentation.
The initial idea was to implement the PHP API in an extension, which could be a drop-in replacement for the core of opentelemetry-php. Since 3rd parties are strongly encouraged to only depend on the API, this should be all they need.
Installation
PIE (PHP Installer for Extensions)
Requires llvm-dev
, libclang-dev
, rust compiler and cargo.
php pie.phar install brettmc/otel-php-rust:dev-main
Development
Using docker + compose, Dockerfile
provides PHP 8.4 + rust environment to build and
test in. I've added Makefile
s to make things easier, and written some tests using PHP's
phpt.
Quick-start:
git clone <this repo>
make build
make bash
From this bash shell, there is another Makefile to build the extension and run the tests. Tests are organised as:
test
- all teststest-auto
- auto-instrumentationtest-otlp
- otlp (http/protobuf
+grpc
) exporting to a local collectortest-phpt
- test the API via PHP code
For the otlp
tests, be sure to docker compose up -d collector
first.
What works?
- Auto-instrumentation of userland and internal code, via zend_observer API (see
tests/auto/*
) - Start a span in RINIT for non-
cli
SAPIs, usetraceparent
headers, set HTTP response code in RSHUTDOWN - TracerProvider globally registered in MINIT, and shutdown on MSHUTDOWN
- Spans can be built through a SpanBuilder, some updates made (not all implemented yet), and
end()
ed - Spans can be
activate()
d, and scope detached - Spans export to stdout, otlp
- Get SpanContext from a Span
$provider = \OpenTelemetry\API\Globals::tracerProvider(); $tracer = $provider->getTracer('name', '0.1' /*other params*/); $span = $tracer ->spanBuilder('test-span') ->setAttribute('key', 'value'); $span->updateName('updated'); var_dump($span->getContext()->getTraceId()); $span ->setStatus('Ok') ->end();
What doesn't work or isn't implemented? (todo list)
Tracers
Tracers are re-fetched all over the shop from tracer_provider.rs
RINIT
- Context propagation from incoming request headers doesn't correctly set IsRemote (when root span fetched via
Span::getCurrent()
)
SpanBuilder
- doesn't keep a reference to the tracer, and instead fetches a new tracer each time (losing any InstrumentationScope)
Span
getCurrent()
fetches the current span as aSpanRef
, and presents it as a CurrentSpan (which mirrors Span, but they don't share an interface)addLink
panics when trying to retrieve rust span-context object from a wrapped PHP SpanContext
StatusCode
- not implemented. PR accepted in
phper
to allow adding consts to classes & interfaces to enable this.
The future
Depending on what we can get to work, or not, this extension could go in a number of directions.
- An implementation of the opentelemetry-php API, backed by opentelemetry-rust API+SDK
- Do not expose any classes, and use opentelemetry-rust to support only auto-instrumentation a-la SkyWalking, Compass.
- Implement an entirely new API, closer to opentelemetry-rust's (ie, don't try to match opentelemetry-php)
- Some combination of the above (probably 1+2 or 2+3)
- Abandon ship, chalk it up to experience