OpenTelemetry Tracing for Jetty Edge
Status: Implemented
Overview
Distributed tracing for the Jetty edge server and tunnel agent using OpenTelemetry. Traces follow the W3C Trace Context (traceparent) standard and flow from the public HTTP request through the WebSocket tunnel to the PHP agent and back.
Architecture
Browser/Client
| traceparent header (optional)
v
jetty-edge (Go)
| Start span "edge.http_request"
| Extract or generate traceparent
| Pass trace_parent in WS http_request frame
v
WebSocket tunnel
v
PHP EdgeAgent
| Read trace_parent from frame
| Set traceparent header on upstream curl request
| Include trace_parent in http_response frame
v
Local upstream (Laravel, etc.)
Configuration
| Variable | Default | Description |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT |
(empty = disabled) | gRPC/HTTP endpoint for OTLP span export |
JETTY_EDGE_TRACE_SAMPLE_RATE |
0.01 (1%) |
Sampling rate 0.0-1.0 |
When OTEL_EXPORTER_OTLP_ENDPOINT is not set, the tracer is a no-op with
zero overhead.
Components
1. Tracing package (cli/internal/tracing/tracing.go)
Init()/InitFromConfig()-- create a Tracer from env or explicit configStartSpan(ctx, tracer, name, traceparent)-- begin a span, parse incoming traceparentEndSpan(span)-- finish span, record durationSpan.Traceparent()-- format W3C traceparent for propagation- No-op when OTLP endpoint is not configured
2. Edge server integration (cli/internal/edge/edge.go)
Config.OTLPEndpointandConfig.TraceSampleRatefieldsListenAndServe: initialize tracer, defer shutdownhandlePublicHTTP: start span, add attributes, propagate via frame
3. Wire protocol (cli/internal/wsproto/proto.go)
HTTPRequest.TraceParentfield (json:trace_parent,omitempty)HTTPResponse.TraceParentfield (json:trace_parent,omitempty)
4. PHP EdgeAgent (jetty-client/src/EdgeAgent.php)
- Read
trace_parentfromhttp_requestframe - Set
traceparentheader on upstream curl request - Return
trace_parentinhttp_responseframe
Span attributes
The edge.http_request span includes:
http.method-- request methodhttp.target-- request pathhttp.status_code-- response statusjetty.subdomain-- tunnel subdomainjetty.request_id-- internal request ID
Future work
- Add OTEL SDK dependencies to go.mod (currently stubbed with TODO comments)
- Span export batching and retry configuration
- Baggage propagation for custom metadata
- PHP-side span creation (requires PHP OTEL extension)
Send feedback
Found an issue or have a suggestion? Let us know.