Repository navigation
fix(metrics): write label values that are not UTF-8 as \DDD escapes - #798
Conversation
Names taken from packets, such as DNS qnames and DHCP hostnames, can hold any byte. pktvisor passed them unchanged into OTLP string attributes, Prometheus label values and JSON top-N names. A strict OTLP decoder then refused the whole export, Prometheus refused the whole scrape, and the JSON dump threw. Every label value now goes through utf8_label_value. A valid value is unchanged; each byte outside a well-formed UTF-8 sequence becomes \DDD, the decimal escape of DNS presentation format. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sh text A backslash followed by three digits is now written as \092, so the text \255 and the byte 0xff no longer render as the same label. Valid values take a fast path, and the tests cover truncated, overlong and boundary sequences. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
AI Code Review — risk tier: Advisory only. A human owns the merge decision. Summary — Net-positive change: packet-derived label values (DNS qnames, DHCP hostnames) are now correctly validated and 🤖 AI Code Review · run · prompts: |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LCOV of commit
|
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. More of your lovely PRs please. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
Some label values come from packets: DNS query names in the top QNAME tables, and the hostname a DHCP client sends. A DNS name or DHCP hostname can hold any byte, and pktvisor passed those bytes unchanged into every output:
contains invalid UTF-8 data when serializing. A strict decoder refuses the whole message. The orb-agent's OTLP bridge decodes with Go protobuf, so one such qname drops every pktvisor metric of that interval.invalid UTF-8 label value), failing the whole scrape.nlohmann::json::dump()throwstype_error.316on the top-N name, so the REST metrics response fails.Every label value now goes through
utf8_label_value:\DDD, its decimal value, as in DNS presentation format\092, so a name holding the text\255stays distinct from one holding the byte 0xFF; any other backslash is unchanged, so values such as Windows interface names keep their current formA query for
www.bad<0xff>name.testis now counted in every output as.bad\255name.testindns_top_qname2_xacts, and aswww.bad\255name.testindns_top_qname3_xacts,dns_top_noerror_xactsanddns_top_nodata_xacts.Where it applies:
add_label_attributeshelper replaces the five copied attribute loops (Counter, Cardinality, Histogram, Quantile, TopN).PrometheusSerializer::append_escapedescapes a value first, then applies the usual Prometheus escaping. Values that need no escaping take the old path with no extra allocation.TopN::to_jsonescapes string items.Testing
www.bad<0xff>name.test, between documentation addresses. The JSON, Prometheus and OTLP outputs all carry the escaped name,dump()no longer throws, and the serialised OTLP parses back with protobuf's strict UTF-8 check. Before the fix, all five checks fail.proto.Unmarshal, as the agent's bridge does:string field contains invalid UTF-8, and all 31 metrics are lostctestpasses, 25 of 25 tests, on macOS arm64 (Apple clang 21, Release).Not changed
policy_name. Neither is escaped. Keys come from code and config, and policy names must match pktvisor's module name pattern; neither comes from packets.--otel-interval. Separately:pktvisordparses--otel-intervalbut never copies it intoOtelConfig, so OTLP pushes always run every 60 seconds. The orb-agent does not pass that flag. I left it for a separate change.🤖 Generated with Claude Code