Plack-Middleware-OpenTelemetry
view release on metacpan or search on metacpan
0.262410 -- Fri Aug 28 21:28:30 PDT 2026
- Fix context propagation for streaming responses (thanks @abraxxa)
- Remove duplicate repository URL from the distribution metadata
(thanks @abraxxa)
0.252280 -- Fri Aug 15 23:49:53 -04 2025
- Lower minimum Perl version requirement from 5.36 to 5.30
- Improve documentation
0.252270 -- Thu Aug 14 23:22:12 -04 2025
- Fix variable shadowing bug in resource creation (thanks @abraxxa)
- Ensure Plack is loaded for resource version data (José JoaquÃn Atria)
lib/Plack/Middleware/OpenTelemetry.pm view on Meta::CPAN
The middleware automatically:
=over
=item * Creates OpenTelemetry spans for HTTP requests
=item * Extracts W3C trace context from incoming requests
=item * Sets standard HTTP semantic attributes following OpenTelemetry conventions
=item * Handles both synchronous and streaming responses
=item * Records exceptions and sets appropriate span status
=back
The following HTTP attributes are set on spans:
=over
=item * C<http.request.method> - HTTP method
t/otel_integration.t view on Meta::CPAN
my $path = $env->{PATH_INFO} || '/';
if ($path eq '/success') {
return [200, ['Content-Type' => 'text/plain'], ['OK']];
} elsif ($path eq '/not_found') {
return [404, ['Content-Type' => 'text/plain'], ['Not Found']];
} elsif ($path eq '/server_error') {
return [500, ['Content-Type' => 'text/plain'], ['Server Error']];
} elsif ($path eq '/exception') {
die "Test exception message";
} elsif ($path eq '/streaming') {
return sub {
my $respond = shift;
my $writer = $respond->([200, ['Content-Type' => 'text/plain']]);
$writer->write("chunk1");
$writer->write("chunk2");
$writer->close;
};
} else {
return [200, ['Content-Type' => 'text/plain'], ['Default']];
}
t/otel_integration.t view on Meta::CPAN
};
my $span = parse_console_span($span_output);
is $span->{status}{code}, SPAN_STATUS_ERROR, 'Exception marked span as error';
is $span->{attributes}->{'http.response.status_code'}, 500, 'Exception sets 500 status';
# Check if exception was recorded
ok $span->{events} && @{$span->{events}}, 'Exception events recorded';
};
# Test streaming responses
subtest 'Streaming Response' => sub {
my $app = build_app();
my $span_output = capture_stderr {
test_psgi $app, sub {
my $cb = shift;
my $res = $cb->(GET 'http://example.com/streaming');
is $res->code, 200;
is $res->content, 'chunk1chunk2', 'Streaming content received';
};
};
# For streaming responses, multiple spans might be output or format might differ
# Just verify we captured some span output
ok $span_output, 'Span output captured for streaming response';
like $span_output, qr/streaming|GET request/, 'Span output contains expected content';
};
# Test resource attributes
subtest 'Resource Attributes' => sub {
my $app = build_app(
resource_attributes => {
'service.name' => 'test-service',
'service.version' => '1.0.0'
}
);
( run in 1.737 second using v1.01-cache-2.11-cpan-6736b670a1e )