NAME
Langertha::Runtime::Metrics - Prometheus text exposition format parser with prefix filter
VERSION
version 0.503
SYNOPSIS
use Langertha::Runtime::Metrics;
my $metrics = Langertha::Runtime::Metrics->new;
my $records = $metrics->parse($prometheus_payload);
# Filter to engine-specific keys only
my $vllm_only = $metrics->filter_prefix($records, 'vllm:');
# Same, in one step
my $vllm_only = $metrics->parse_and_filter($prometheus_payload, 'vllm:');
DESCRIPTION
Parser for the Prometheus text exposition format. Accepts a raw payload string (the body of a GET /metrics response) and returns an ArrayRef of HashRefs with shape:
{
name => 'vllm:gpu_cache_usage_perc', # metric name (str)
type => 'gauge', # counter | gauge | histogram |
# summary | untyped
value => 0.42, # numeric value
labels => { model_name => 'Qwen/Qwen2.5-7B-Instruct' }, # label set
# (HashRef, possibly empty)
}
Only sample lines are returned. # HELP and # TYPE directive lines inform the type field on the following sample(s) but are not emitted on their own.
Counter / gauge / untyped lines yield a single record each. Histogram and summary lines yield one record per emitted series (the _bucket, _sum, and _count series that follow the # TYPE histogram directive).
The parser is intentionally permissive: malformed lines are skipped with a warning rather than croaking, so a partial scrape (truncated body, comment-only line at EOF) returns the lines it could parse rather than nothing.
Wire contract
The exact metric-key shape per engine lives in Langertha::Runtime::Metrics::EngineContract. Use filter_prefix to restrict the parser output to that engine's allowlist before doing anything with the records (logging, OTLP export, etc.) — Prometheus process_* and go_* entries ship from the same /metrics body and are not engine-specific.
parse
my $records = $metrics->parse($payload);
Parses a Prometheus text-format payload into an ArrayRef of { name, type, value, labels } HashRefs. See "DESCRIPTION" for the exact shape. Malformed lines are skipped, never fatal.
filter_prefix
my $vllm = $metrics->filter_prefix($records, 'vllm:');
my $sg = $metrics->filter_prefix($records, 'sglang:');
my $llama = $metrics->filter_prefix($records, 'llama_');
Returns the subset of $records whose name starts with the given prefix. Use to restrict parser output to the engine's allowlist per Langertha::Runtime::Metrics::EngineContract.
parse_and_filter
my $vllm = $metrics->parse_and_filter($payload, 'vllm:');
my $both = $metrics->parse_and_filter($payload, 'vllm:', 'http:');
Convenience wrapper around "parse" + "filter_prefix". Multiple prefixes are OR-ed (a record is kept if it matches any prefix).
SEE ALSO
Langertha::Runtime::Metrics::EngineContract - Per-engine wire contract (allowlist prefixes, URL paths)
Langertha::Role::Runtime::MetricsPoll - Async scraper that drives this parser
Langertha::Runtime::Metrics::OTLP - Serializes the record shape into an OTLP/HTTP JSON metrics payload
https://prometheus.io/docs/instrumenting/exposition_formats/ - Prometheus text exposition format spec
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.