11# PHPUnit Telemetry Bridge
22
3- PHPUnit extension allowing to collect test suite telemetry and export to OTEL collector.
3+ PHPUnit extension allowing to collect test suite telemetry and export it to any OTLP-compatible backend (OpenTelemetry
4+ Collector, Grafana Alloy, Honeycomb, Datadog, Jaeger, etc.).
45
56- [ Back] ( /documentation/introduction.md )
67- [ Packagist] ( https://packagist.org/packages/flow-php/phpunit-telemetry-bridge )
@@ -12,47 +13,148 @@ PHPUnit extension allowing to collect test suite telemetry and export to OTEL co
1213
1314## Installation
1415
15- For detailed installation instructions, see the [ installation page] ( /documentation/installation/packages/phpunit-telemetry-bridge.md ) .
16+ For detailed installation instructions, see
17+ the [ installation page] ( /documentation/installation/packages/phpunit-telemetry-bridge.md ) .
1618
1719## Configuration
1820
1921Add the extension to your ` phpunit.xml.dist ` :
2022
2123``` xml
24+
2225<extensions >
2326 <bootstrap class =" Flow\Bridge\PHPUnit\Telemetry\TelemetryExtension" >
2427 <parameter name =" service_name" value =" my-test-suite" />
25- <parameter name =" otel_collector_url " value =" http://localhost:4318" />
28+ <parameter name =" endpoint " value =" http://localhost:4318" />
2629 <parameter name =" emit_traces" value =" true" />
2730 <parameter name =" emit_metrics" value =" true" />
28- <parameter name =" emit_test_spans" value =" false " />
29- <parameter name =" emit_test_case_spans" value =" false " />
31+ <parameter name =" emit_test_spans" value =" true " />
32+ <parameter name =" emit_test_case_spans" value =" true " />
3033 </bootstrap >
3134</extensions >
3235```
3336
3437## Configuration Parameters
3538
36- | Parameter | Default | Description |
37- | -----------| ---------| -------------|
38- | ` service_name ` | ` phpunit ` | Service name used in telemetry data |
39- | ` otel_collector_url ` | ` http://localhost:4318 ` | OTLP HTTP endpoint URL |
40- | ` emit_traces ` | ` true ` | Enable/disable trace emission |
41- | ` emit_metrics ` | ` true ` | Enable/disable metric emission |
42- | ` emit_test_spans ` | ` true ` | Create individual spans for each test |
43- | ` emit_test_case_spans ` | ` true ` | Create spans for test case classes |
39+ ### Shared
40+
41+ | Parameter | Environment variable | Default | Description |
42+ | ------------------------| ------------------------------------------| -------------------------| ----------------------------------------------------------------|
43+ | ` service_name ` | ` FLOW_PHPUNIT_OTEL_SERVICE_NAME ` | ` phpunit ` | Service name reported in telemetry data |
44+ | ` transport ` | ` FLOW_PHPUNIT_OTEL_TRANSPORT ` | ` curl ` | Transport type: ` curl ` or ` grpc ` |
45+ | ` endpoint ` | ` FLOW_PHPUNIT_OTEL_ENDPOINT ` | ` http://localhost:4318 ` | OTLP endpoint URL (for ` grpc ` use host: port , e.g. ` otel:4317 ` ) |
46+ | ` headers ` | ` FLOW_PHPUNIT_OTEL_HEADERS ` | — | Additional headers (see [ Authentication] ( #authentication ) ) |
47+ | ` emit_traces ` | ` FLOW_PHPUNIT_OTEL_EMIT_TRACES ` | ` true ` | Enable/disable trace emission |
48+ | ` emit_metrics ` | ` FLOW_PHPUNIT_OTEL_EMIT_METRICS ` | ` true ` | Enable/disable metric emission |
49+ | ` emit_test_spans ` | ` FLOW_PHPUNIT_OTEL_EMIT_TEST_SPANS ` | ` true ` | Create individual spans for each test |
50+ | ` emit_test_case_spans ` | ` FLOW_PHPUNIT_OTEL_EMIT_TEST_CASE_SPANS ` | ` true ` | Create spans for test case classes |
51+
52+ ### Curl transport (` transport=curl ` )
53+
54+ | Parameter | Environment variable | Default | Description |
55+ | -------------------------| -------------------------------------------| ---------| ---------------------------------------------|
56+ | ` curl_timeout ` | ` FLOW_PHPUNIT_OTEL_CURL_TIMEOUT ` | ` 30 ` | Request timeout in seconds |
57+ | ` curl_connect_timeout ` | ` FLOW_PHPUNIT_OTEL_CURL_CONNECT_TIMEOUT ` | ` 10 ` | Connection timeout in seconds |
58+ | ` curl_compression ` | ` FLOW_PHPUNIT_OTEL_CURL_COMPRESSION ` | ` false ` | Enable automatic response decompression |
59+ | ` curl_follow_redirects ` | ` FLOW_PHPUNIT_OTEL_CURL_FOLLOW_REDIRECTS ` | ` true ` | Follow HTTP redirects |
60+ | ` curl_max_redirects ` | ` FLOW_PHPUNIT_OTEL_CURL_MAX_REDIRECTS ` | ` 3 ` | Maximum number of redirects to follow |
61+ | ` curl_proxy ` | ` FLOW_PHPUNIT_OTEL_CURL_PROXY ` | — | Proxy server URL (e.g. ` http://proxy:8080 ` ) |
62+ | ` curl_ssl_verify_peer ` | ` FLOW_PHPUNIT_OTEL_CURL_SSL_VERIFY_PEER ` | ` true ` | Verify SSL peer certificate |
63+ | ` curl_ssl_verify_host ` | ` FLOW_PHPUNIT_OTEL_CURL_SSL_VERIFY_HOST ` | ` true ` | Verify SSL host name |
64+ | ` curl_ssl_cert_path ` | ` FLOW_PHPUNIT_OTEL_CURL_SSL_CERT_PATH ` | — | Path to client SSL certificate |
65+ | ` curl_ssl_key_path ` | ` FLOW_PHPUNIT_OTEL_CURL_SSL_KEY_PATH ` | — | Path to client SSL private key |
66+ | ` curl_ca_info_path ` | ` FLOW_PHPUNIT_OTEL_CURL_CA_INFO_PATH ` | — | Path to CA certificate bundle |
67+ | ` curl_serializer ` | ` FLOW_PHPUNIT_OTEL_CURL_SERIALIZER ` | ` json ` | Payload serializer: ` json ` or ` protobuf ` |
68+
69+ ### gRPC transport (` transport=grpc ` )
70+
71+ Requires the ` grpc ` PHP extension and the ` google/protobuf ` + ` open-telemetry/gen-otlp-protobuf ` packages. Payload is
72+ always protobuf (per OTLP/gRPC spec).
73+
74+ | Parameter | Environment variable | Default | Description |
75+ | -----------------| -----------------------------------| ---------| ----------------------------------|
76+ | ` grpc_insecure ` | ` FLOW_PHPUNIT_OTEL_GRPC_INSECURE ` | ` true ` | Use insecure channel credentials |
77+
78+ ## Authentication
79+
80+ OTLP endpoints that require authentication (Grafana Alloy with Bearer auth, Honeycomb with ` x-honeycomb-team ` , vendor
81+ tenant headers, etc.) are configured through the ` headers ` parameter.
82+
83+ Headers use the OpenTelemetry spec format: comma-separated ` name=value ` pairs, with values URL-encoded (so commas,
84+ spaces and equal signs inside values don't collide with the delimiter):
85+
86+ ``` xml
87+
88+ <parameter name =" endpoint" value =" https://alloy.example.com:4318" />
89+ <parameter name =" headers" value =" Authorization=Bearer%20xxx,X-Scope-OrgID=tenant-1" />
90+ ```
91+
92+ Invalid header format (missing ` = ` , empty name) will throw ` InvalidArgumentException ` when PHPUnit boots the extension.
93+
94+ ## gRPC Transport
95+
96+ ``` xml
97+
98+ <extensions >
99+ <bootstrap class =" Flow\Bridge\PHPUnit\Telemetry\TelemetryExtension" >
100+ <parameter name =" transport" value =" grpc" />
101+ <parameter name =" endpoint" value =" otel.example.com:4317" />
102+ <parameter name =" headers" value =" api-key=xxx" />
103+ <parameter name =" grpc_insecure" value =" false" />
104+ </bootstrap >
105+ </extensions >
106+ ```
107+
108+ ## Environment Variables
109+
110+ Every parameter has an env var counterpart (see the tables above).
111+
112+ ** Precedence:** environment variable > ` <parameter> ` in ` phpunit.xml ` > default. Empty-string env vars are treated as unset.
113+
114+ ** Lookup order:** ` $_ENV ` → ` $_SERVER ` → ` getenv() ` . Values loaded by Symfony DotEnv or ` vlucas/phpdotenv `
115+ (which populate ` $_ENV ` / ` $_SERVER ` but don't always call ` putenv() ` ) are picked up the same as shell env vars.
116+
117+ > [ !IMPORTANT]
118+ > When setting boolean env vars through PHPUnit's ` <env> ` directive in ` phpunit.xml.dist ` , add ` verbatim="true" ` — otherwise
119+ > PHPUnit casts the bare strings ` "true" ` / ` "false" ` to PHP booleans, which ` putenv() ` then stringifies to ` "1" ` / ` "" ` , and
120+ > the empty string is treated as unset by the resolver (falling back to the default).
121+ >
122+ > ``` xml
123+ > <env name =" FLOW_PHPUNIT_OTEL_EMIT_TEST_SPANS" value =" false" verbatim =" true" />
124+ > ```
125+ >
126+ > This only applies to `<env >` in PHPUnit XML; real shell env vars and `.env` entries are already plain strings.
127+
128+ Typical usage — credentials stay out of version control:
129+
130+ ```bash
131+ export FLOW_PHPUNIT_OTEL_ENDPOINT="https://alloy.example.com:4318"
132+ export FLOW_PHPUNIT_OTEL_HEADERS="Authorization=Bearer%20${ALLOY_TOKEN}"
133+
134+ ./vendor/bin/phpunit
135+ ```
136+
137+ ## Deprecation: ` otel_collector_url `
138+
139+ The ` otel_collector_url ` parameter and its ` FLOW_PHPUNIT_OTEL_COLLECTOR_URL ` environment variable are deprecated and
140+ trigger ` E_USER_DEPRECATED ` . They remain functional as an alias for ` endpoint ` with ` transport=curl ` .
141+
142+ Mixing the deprecated parameter with any of the new-shape parameters (` transport ` , ` endpoint ` , ` headers ` , ` curl_* ` ,
143+ ` grpc_* ` ) throws ` InvalidArgumentException ` — migrate fully when you switch.
44144
45145## Features
46146
47147### Traces
48148
49149When enabled, the extension creates spans for:
150+
50151- Test suite runs (root span)
51152- Individual test suites
52153- Test case classes (optional)
53154- Individual tests (optional)
54155
55156Each span includes attributes like:
157+
56158- ` test.suite ` - Test suite name
57159- ` test.id ` - Test identifier
58160- ` test.name ` - Test name
@@ -63,6 +165,7 @@ Each span includes attributes like:
63165### Metrics
64166
65167When enabled, the extension records:
168+
66169- ` phpunit.suite.duration ` - Histogram of suite execution time
67170- ` phpunit.suite.test_count ` - Counter of tests per suite
68171- ` phpunit.test.duration ` - Histogram of individual test execution time
0 commit comments