Download the PHP package eerzho/opentelemetry-auto-class without Composer
On this page you can find all versions of the php package eerzho/opentelemetry-auto-class. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download eerzho/opentelemetry-auto-class
More information about eerzho/opentelemetry-auto-class
Files in eerzho/opentelemetry-auto-class
Package opentelemetry-auto-class
Short Description Trace what your methods received, returned, and threw — without writing a single span. No framework required.
License MIT
Informations about the package opentelemetry-auto-class
opentelemetry-auto-class
Trace what your methods received, returned, and threw — without writing a single span. No framework required.
This is a read-only sub-split. Please open issues and pull requests in the monorepo.
The framework-agnostic engine — the Laravel and Symfony integrations build on it to discover and register your classes automatically.
Installation
Requirements:
- ext-opentelemetry
- PHP 8.2+
Usage
Start with a plain service — we'll add tracing to it one attribute at a time:
1. #[Trace] — mark a class for tracing
2. #[TraceMethod] — trace a method
A method gets a span with #[TraceMethod]. By default, it captures the arguments and the return value, and records exceptions. Turn each off with arguments: false, return: false, or exception: false (a disabled exception still sets the span status to ERROR, only its event is omitted).
3. #[TraceProperties] — expand an object argument
4. Register
Once the attributes are in place, scan the classes and register the hooks — once, at bootstrap:
Manual registration
Skip AttributeScanner and hand register() the method map directly:
Each method maps to its arguments (name => position) plus the return and exception flags. Missing keys default to off. Anything not listed is not traced.
Traced output
Selecting what to trace
include and exclude behave the same wherever they appear — #[TraceMethod] (arguments) and #[TraceProperties] (properties):
include |
exclude |
Result |
|---|---|---|
[] |
[] |
Everything (default) |
[a, b] |
[] |
Only a and b |
[] |
[a] |
Everything except a |
[a, b] |
[b] |
Only a — exclude wins on conflict |
An empty include means "no allowlist" (everything), not "nothing".
All properties are expanded — use exclude to drop sensitive ones (tokens, hashes).
Argument serialization
Each captured argument is serialized to a span-compatible value:
| Type | Result |
|---|---|
string, int, float, bool |
As-is |
null |
"null" |
BackedEnum |
Backing value |
DateTimeInterface |
RFC3339 with milliseconds |
Object with #[TraceProperties] |
Expanded properties |
Object with __toString() |
String cast |
Object without #[TraceProperties] and __toString() |
Class name (FQCN) |
array |
First element sampled + array_count |
Other (resource, ...) |
gettype() result |
Object expansion via #[TraceProperties]:
- Each property becomes its own attribute, keyed
code.argument.{name}.{property}(e.g.code.argument.address.city). - Recursive and unbounded — a nested property keeps expanding while its class also has
#[TraceProperties]; otherwise it falls back to the rules above. - An uninitialized typed property is recorded as
"uninitialized". - Circular references are broken — a repeated object degrades to its class name.
- Any reflection or
__toString()failure falls back to the class name, so serialization never breaks the traced call.
Array expansion:
- Only the first element is sampled (serialized by the same rules, e.g.
code.argument.orders.0.id) — enough to see the shape without flooding the span. - The full size is always recorded as
code.argument.{name}.array_count(e.g.code.argument.orders.array_count).
Span structure
Each traced call produces an INTERNAL span named ClassName::methodName, with:
| Attribute | Value |
|---|---|
code.function.name |
ClassName::methodName |
code.file.path |
File where the method is defined |
code.line.number |
Line number of the method |
code.return |
Return value, serialized the same way |
code.argument.{name} |
Method argument, keyed by parameter name, serialized the same way |
If the method throws, the span records an exception event and its status is set to ERROR:
| Event attribute | Value |
|---|---|
exception.type |
Exception class name |
exception.message |
Exception message |
exception.stacktrace |
Full stack trace |
With exception: false the status still becomes ERROR, but the event above is omitted.
How it works
AttributeScanner::scan() reflects over the classes you pass it:
- Skips abstract classes, interfaces, traits, and enums.
- Reads
#[Trace]on the class — no attribute, no instrumentation. - Collects every method carrying
#[TraceMethod], and for each the arguments, return value, and exception recording it configures.
It returns a class → method → {arguments, return, exception} map. ClassInstrumentation::register() then installs an ext-opentelemetry hook on every mapped method:
- pre — opens the span and attaches the
code.*attributes and serialized arguments. - post — captures the return value on success, records the exception and sets
ERRORstatus on failure, then ends the span.
Disabling instrumentation
All versions of opentelemetry-auto-class with dependencies
ext-opentelemetry Version *
open-telemetry/api Version ^1.0
open-telemetry/sem-conv Version ^1.33