NAME

Punk::OpenTelemetry - OpenTelemetry for Punk: traces, metrics and logs over OTLP

VERSION

Version 0.04

SYNOPSIS

package MyApp;
use Punk;
use Punk::Plugin::OpenTelemetry;

otel service_name => 'checkout';
plugin 'OpenTelemetry';

get '/orders/:id' => sub {
    my ($c) = @_;
    $c->json({ id => $c->param('id') });
};

That is the whole of it. Every request is now a span named for its route pattern, every outbound call a child span with the traceparent on the wire, every query a span carrying the prepared statement, and batches leave for the collector on a timer.

Or with no code at all, which is how a deployment usually wants it:

OTEL_SERVICE_NAME=checkout \
OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318 \
  plackup -s Hyperman app.psgi

DESCRIPTION

An OpenTelemetry SDK for Punk: the tracer and its spans, the OTLP encoders and transports, context propagation, resource detection, metrics, log records, and the plugin that wires all of it into an application.

There is a working demonstration in example/ - an instrumented application and a collector that prints what it receives to STDERR, so the whole path is visible without a vendor account.

What you get by registering the plugin

  • Server spans named for the route pattern, "GET /users/:id" and never "GET /users/7". The span opens before routing, when only the method is known, and is renamed once the pattern exists. Naming it after the path would be a cardinality mistake that no dashboard recovers from.

  • Client spans for outbound HTTP, with the traceparent injected on the way out. Without that injection the far side starts a new trace and the two halves of a call are never joined.

  • Database spans carrying the prepared statement. Bind values are not passed to an observer at all, so the literal data cannot leak by accident.

  • Metrics and log records when they are asked for, the logs correlated to the trace that produced them.

  • Batching, on the worker's own event loop. Nothing is sent from the request path and nothing is waited on, so a collector that is down costs the application nothing.

Both OTLP transports, and gRPC

Protobuf over HTTP is the default, because it is three to five times smaller on the wire than the JSON form. JSON is supported for the times when being able to read a payload matters more than its size, which is most of them when something has gone wrong. OTLP/gRPC is there too, as the narrow fixed use of HTTP/2 that it is rather than as a framework dependency.

THE MODULES

Start with the plugin. The rest is what it is made of, and is documented because a telemetry layer nobody can read is a telemetry layer nobody can trust.

IF NOTHING ARRIVES

There is no default endpoint. With none configured the SDK builds, instruments the request path, records spans and drops them for want of anywhere to send them - it does not fall back to http://localhost:4318 the way some other SDKs do. That is the first thing to check, because everything else looks healthy when it happens.

The boot diagnostic prints the endpoint it resolved, along with the service name, the protocol, the sampler and the propagators. Read that line before reading anything else.

TURNING IT OFF

OTEL_SDK_DISABLED=true

Answered before anything is built and before a single hook is registered: no tracer, no exporter, nothing in the request path. An SDK that still builds a tracer and throws the spans away has not been disabled, it has been made pointless.

The value is the specification's boolean and not Perl's truth: only the string true, case-insensitively. Under any looser rule OTEL_SDK_DISABLED=false would switch telemetry off, using the word an operator reaches for to switch it on.

SEE ALSO

Punk, Hyperman, Fetch.

The OpenTelemetry specification: https://opentelemetry.io/docs/specs/otel/, and the OTLP protocol: https://opentelemetry.io/docs/specs/otlp/.

AUTHOR

LNATION <email@lnation.org>

BUGS

Please report any bugs or feature requests to bug-punk-opentelemetry at rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Punk-OpenTelemetry. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Punk::OpenTelemetry

You can also look for information at:

LICENSE AND COPYRIGHT

This software is Copyright (c) 2026 by LNATION <email@lnation.org>.

This is free software, licensed under:

The Artistic License 2.0 (GPL Compatible)