Skip to content

feat(telemetry): fix escapes, add alerts, and add test utilities - #1753

Open
jbuckmccready wants to merge 3 commits into
jbuckmccready/testing-pilotfrom
jbuckmccready/logging-improvements
Open

feat(telemetry): fix escapes, add alerts, and add test utilities#1753
jbuckmccready wants to merge 3 commits into
jbuckmccready/testing-pilotfrom
jbuckmccready/logging-improvements

Conversation

@jbuckmccready

@jbuckmccready jbuckmccready commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixed logfmt quoting and escaping for quotes, backslashes, equals signs, whitespace, and control characters.
  • Refactored to use precomputed encoding plans to avoid excessive repeated calls to formatter functions to determine byte lengths and need for quoting.
  • Added .alert(.dev | .operator) logging fields with configurable panic policies in tests (logged alert concept is described in this PR: test(gossip): pilot for component tests #1744)
  • Introduced TestLogStore for capturing, iterating, inspecting, and resetting structured logs.

NOTE: no tests inspect logs in this PR since there isn't really a good use case currently in gossip, but it still asserts there is no logged alerts (using TestLogStore in the TestNode gossip harness). It would look something like this:

    var logs = test_node.logs().iterator();
    const record = logs.next() orelse return error.ExpectedLog;
    try std.testing.expectEqual(lib.telemetry.log.Level.err, record.level);
    try std.testing.expectEqualStrings("processMessage", record.scope);

    const propagated_record = logs.next() orelse return error.ExpectedLog;
    try std.testing.expectEqual(lib.telemetry.log.Level.err, propagated_record.level);
    try std.testing.expectEqualStrings("processPacket", propagated_record.scope);
    try std.testing.expectEqual(null, logs.next());

@github-project-automation github-project-automation Bot moved this to 🏗 In progress in Sig Jul 22, 2026
@jbuckmccready
jbuckmccready force-pushed the jbuckmccready/logging-improvements branch 6 times, most recently from 46fd4c1 to 37823ad Compare July 23, 2026 13:43
@jbuckmccready
jbuckmccready marked this pull request as ready for review July 23, 2026 13:46
@jbuckmccready jbuckmccready self-assigned this Jul 23, 2026
@jbuckmccready
jbuckmccready requested a review from Copilot July 23, 2026 13:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the telemetry logging system by fixing logfmt escaping/quoting, adding a first-class “alert” field for targeted operational signaling, and introducing test utilities to capture and assert on structured logs in in-process tests.

Changes:

  • Added Alert support and .alert(.dev | .operator) logging fields, plus test-time panic policies for alert emission.
  • Refactored log encoding to use precomputed encoding plans (byte lengths + quoting decisions) to avoid repeated formatter passes and improve correctness for escaping.
  • Introduced TestLogStore and integrated it into the gossip TestNode harness to capture logs and enforce “no alerts emitted” behavior by default.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
v2/lib/telemetry/tests/TestLogStore.zig New in-memory structured log capture utility for tests, with optional panic-on-alert behavior.
v2/lib/telemetry/tests.zig Ensures TestLogStore tests are included in the telemetry test suite.
v2/lib/telemetry/log.zig Adds Alert, introduces encoding plans, and implements logfmt quoting/escaping fixes with new tests.
v2/lib/telemetry.zig Exposes TestLogStore, adds .alert() to the logger API, and uses encoding plans during logging.
v2/lib/gossip/tests/TestNode.zig Integrates TestLogStore into the gossip test harness and routes node logs into it.
Comments suppressed due to low confidence (1)

v2/lib/telemetry/log.zig:1024

  • LogfmtEscapingWriter.drain assumes data.len >= 1 and will underflow / OOB if invoked with an empty slice list. Add an assertion (or early return) to guard against that case.
        const self: *LogfmtEscapingWriter = @alignCast(@fieldParentPtr("writer", w));
        const rest = data[0 .. data.len - 1];
        const pattern = data[data.len - 1];

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread v2/lib/telemetry/log.zig
Comment on lines +974 to 976
const self: *LogfmtValueAnalyzer = @alignCast(@fieldParentPtr("writer", w));
const rest = data[0 .. data.len - 1];
const pattern = data[data.len - 1];

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added assertions (it's required by the std Writer.drain contract to be non-zero): 7eddd95

Comment thread v2/lib/telemetry/log.zig Outdated
Comment on lines +662 to +665
/// Formatted output from function provided must be valid UTF-8 and identical on every call (as
/// visible by this formatter). Encoding-plan computation and output formatting invoke the formatter
/// separately (to produce a byte length prefix), so differing output between calls corrupts that
/// length-prefix.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adjusted the comment for clarity: 9d827ca

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.74648% with 8 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
v2/lib/telemetry/tests/TestLogStore.zig 97.90% 4 Missing ⚠️
v2/lib/telemetry.zig 70.00% 3 Missing ⚠️
v2/components/gossip/tests/TestNode.zig 83.33% 1 Missing ⚠️
Files with missing lines Coverage Δ
v2/lib/telemetry/log.zig 65.05% <100.00%> (ø)
v2/components/gossip/tests/TestNode.zig 94.87% <83.33%> (ø)
v2/lib/telemetry.zig 90.42% <70.00%> (ø)
v2/lib/telemetry/tests/TestLogStore.zig 97.90% <97.90%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jbuckmccready
jbuckmccready force-pushed the jbuckmccready/logging-improvements branch from 9d827ca to 478a33f Compare July 27, 2026 14:13
@jbuckmccready
jbuckmccready force-pushed the jbuckmccready/testing-pilot branch from 244acdf to b1bf333 Compare July 27, 2026 14:41
@jbuckmccready
jbuckmccready force-pushed the jbuckmccready/logging-improvements branch from 478a33f to e24e290 Compare July 27, 2026 14:47
@jbuckmccready
jbuckmccready force-pushed the jbuckmccready/testing-pilot branch from b1bf333 to 5f924fb Compare July 27, 2026 22:37
@jbuckmccready
jbuckmccready force-pushed the jbuckmccready/logging-improvements branch from e24e290 to a81c79f Compare July 27, 2026 22:48
@dnut
dnut requested a review from InKryption July 29, 2026 02:29
@github-project-automation github-project-automation Bot moved this from 🏗 In progress to 👀 In review in Sig Jul 29, 2026
Comment thread v2/lib/telemetry.zig
Comment on lines +325 to +328
const AlertValue = struct {
const value = @tagName(audience);
};
return self.field("alert", &AlertValue.value);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you try this already and it had a problem?

Suggested change
const AlertValue = struct {
const value = @tagName(audience);
};
return self.field("alert", &AlertValue.value);
return self.field("alert", @tagName(audience));

tagName already returns a pointer. You don't need a pointer to a pointer. I think you can eliminate this struct too since the lifetime of the pointer returned by tagName should be static.

@jbuckmccready
jbuckmccready force-pushed the jbuckmccready/testing-pilot branch from 510face to 33e65e7 Compare July 30, 2026 14:08
@jbuckmccready
jbuckmccready force-pushed the jbuckmccready/logging-improvements branch from a81c79f to 841ddd5 Compare July 30, 2026 14:10
@jbuckmccready
jbuckmccready force-pushed the jbuckmccready/testing-pilot branch from 33e65e7 to ba65023 Compare July 30, 2026 15:20
@jbuckmccready
jbuckmccready force-pushed the jbuckmccready/logging-improvements branch from 841ddd5 to bddebca Compare July 30, 2026 15:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

4 participants