NAME
Langertha::Runtime::Metrics::OTLP - Convert parsed Prometheus records to an OTLP/HTTP (JSON) metrics payload
VERSION
version 0.503
SYNOPSIS
use Langertha::Runtime::Metrics;
use Langertha::Runtime::Metrics::OTLP;
my $records = Langertha::Runtime::Metrics->new->parse($prometheus_body);
my $otlp = Langertha::Runtime::Metrics::OTLP->new;
my $payload = $otlp->build_payload($records,
service_name => 'vllm',
resource_attributes => { trace_id => 'trace-123' },
);
my $json = $otlp->to_json($records, service_name => 'vllm');
DESCRIPTION
Serializes the record shape produced by Langertha::Runtime::Metrics ({ name, type, value, labels }) into an OpenTelemetry OTLP/HTTP JSON metrics payload: resourceMetrics / scopeMetrics / metric. The payload is a plain HashRef (or JSON string via "to_json") ready to POST to any OTLP/HTTP metrics receiver — an OpenTelemetry Collector, a Prometheus OTLP receiver, Grafana, or any other backend that speaks OTLP/HTTP.
Type mapping:
gauge/untyped— OTLPgaugedata point (asDouble)counter— OTLPsumwithisMonotonic => trueandaggregationTemporality => AGGREGATION_TEMPORALITY_CUMULATIVE(Prometheus counters are cumulative monotonic sums)histogram— the_bucket/_sum/_countseries are re-grouped into a single OTLPhistogrammetric. Buckets are sorted by theirlebound (+Inflast),explicitBoundsexcludes+Inf, andbucketCountskeeps the cumulative counts including the+Infbucket.summary— the_sum/_countseries plus any{quantile="..."}series are re-grouped into a single OTLPsummarymetric withquantileValues.
Langfuse note: Langfuse does not ingest OTLP metrics. Its /api/public/otel endpoint accepts traces only; a POST to /api/public/otel/v1/metrics is accepted and silently discarded (dummy route since langfuse/langfuse#6408). The /api/public/metrics REST endpoint is a read-only query API over Langfuse's own trace data, not an ingestion endpoint. Point this serializer at a real OTLP metrics backend (Collector, Prometheus, Grafana) — see "export_otlp_f" in Langertha::Role::Runtime::MetricsPoll for the exporter and the sources.
build_payload
my $payload = $otlp->build_payload($records, %opts);
Builds the OTLP/HTTP JSON metrics payload HashRef for the given records. Optional %opts:
service_name— convenience for theservice.nameresource attributeresource_attributes— HashRef of extra resource attributes (e.g.{ trace_id => 'trace-123' }to attach a trace context)scope_name— instrumentation scope name (default'langertha')timestamp— epoch seconds (default: now); rendered astimeUnixNanoon every data point
to_json
my $json = $otlp->to_json($records, %opts);
Same as "build_payload" but returns the JSON-encoded string, ready to POST as the request body.
SEE ALSO
Langertha::Runtime::Metrics - The parser that produces the record shape this serializes
Langertha::Role::Runtime::MetricsPoll - Scraper role with export_otlp_f that POSTs this payload
https://opentelemetry.io/docs/specs/otlp/ - OTLP specification (JSON/protobuf encoding)
https://github.com/langfuse/langfuse/issues/6395 - Langfuse: no OTel metrics support (accepted-and-discarded)
https://github.com/orgs/langfuse/discussions/10686 - Langfuse maintainer: "no support for OTel Metrics"
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/Getty/langertha/issues.
IRC
Join #langertha on irc.perl.org or message Getty directly.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <getty@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus https://raudssus.de/.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.