Skip to content

feat(eventrecorder): add stdout output type#5311

Open
mihir-dixit2k27 wants to merge 4 commits into
prometheus:mainfrom
mihir-dixit2k27:feat/event-recorder-stdout
Open

feat(eventrecorder): add stdout output type#5311
mihir-dixit2k27 wants to merge 4 commits into
prometheus:mainfrom
mihir-dixit2k27:feat/event-recorder-stdout

Conversation

@mihir-dixit2k27

Copy link
Copy Markdown
Contributor

Title: eventrecorder: add stdout output type

Adds a new stdout_outputs destination to the event_recorder configuration. When running Alertmanager in a container, users can now capture structured alert events through the container runtime log driver (Docker, Kubernetes, etc.) without managing a separate file, Kafka cluster, or webhook endpoint. Implementation follows the existing per-type-list pattern used by file_outputs, webhook_outputs, and kafka_outputs. The StdoutOutput implements the Destination interface and serializes events as newline-delimited JSON via protojson, matching the format used by FileOutput. Closes #5306

Pull Request Checklist

Which user-facing changes does this PR introduce?

[FEATURE] event_recorder: Add stdout_outputs destination type to stream alert events as newline-delimited JSON to stdout, enabling container deployments to capture events via the runtime log driver without a separate file, Kafka, or webhook setup.

Description

Adds a stdout_outputs destination to the event_recorder configuration block.

When running Alertmanager in a container, alert events can now be captured through the container runtime's log driver (Docker, Kubernetes, Loki, etc.) alongside regular logs, without needing a separate file path, Kafka cluster, or webhook endpoint.

Config example:

event_recorder:
  outputs:
    stdout_outputs:
      - {}

Implementation notes:

  • Follows the existing per-type-list pattern used by file_outputs, webhook_outputs, and kafka_outputs.
  • StdoutOutput serializes events as newline-delimited JSON via protojson, matching the format produced by FileOutput.
  • Close() is a no-op — the process owns os.Stdout.
  • No new dependencies introduced.
Adds a new stdout_outputs destination to the event_recorder configuration. When running Alertmanager in a container, users can now capture structured alert events through the container runtime log driver (Docker, Kubernetes, etc.) without managing a separate file, Kafka cluster, or webhook endpoint. Implementation follows the existing per-type-list pattern used by file_outputs, webhook_outputs, and kafka_outputs. The StdoutOutput implements the Destination interface and serializes events as newline-delimited JSON via protojson, matching the format used by FileOutput. Closes prometheus#5306

Signed-off-by: Mihir Dixit <dixitmihir1@gmail.com>
@mihir-dixit2k27 mihir-dixit2k27 requested a review from a team as a code owner June 18, 2026 01:31
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8a33fbe8-cd1b-41d4-8490-da4889984fb1

📥 Commits

Reviewing files that changed from the base of the PR and between 2e8f136 and ff17b52.

📒 Files selected for processing (1)
  • docs/configuration.md
✅ Files skipped from review due to trivial changes (1)
  • docs/configuration.md

📝 Walkthrough

Walkthrough

Adds stdout as a new event recorder destination. Configuration, recorder wiring, implementation, tests, and docs are updated so events can be emitted as newline-delimited JSON on standard output.

Changes

Stdout Output Destination

Layer / File(s) Summary
StdoutOutput implementation
eventrecorder/stdout.go
Defines StdoutOutputConfig with always-equal semantics and StdoutOutput with Name(), JSONL event serialization to os.Stdout, serialization-error wrapping, and no-op Close().
Config and recorder wiring
eventrecorder/config.go, eventrecorder/recorder.go, docs/configuration.md
Adds StdoutOutputs to Config, includes stdout in totalOutputs(), compares stdout output lists in configEqual(), wires buildOutputs() to create stdout outputs, and documents stdout_outputs and stdout_output.
Stdout output tests
eventrecorder/stdout_test.go
Adds captureStdout plus tests for Name(), event serialization, repeated writes, Close(), interface compliance, recorder integration, config counting and equality, and YAML unmarshalling.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise, specific, and accurately describes the main change: adding a stdout output type to eventrecorder.
Description check ✅ Passed The description covers the feature summary, checklist items, release notes, example config, and implementation notes required by the template.
Linked Issues check ✅ Passed The changes satisfy #5306 by adding stdout output support, tests, and docs for structured event records in containerized deployments.
Out of Scope Changes check ✅ Passed The PR stays focused on stdout output support and related tests/docs, with no clear unrelated or out-of-scope code changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
eventrecorder/recorder.go (1)

14-33: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Update package documentation to include stdout output.

The package-level documentation should be updated to reflect the new stdout output destination. Line 16-17 currently lists "(JSONL file, webhook, kafka)" but should include stdout. Similarly, the file layout comment around line 32 should list stdout.go alongside file.go, webhook.go, and kafka.go.

As per coding guidelines, package-level documentation must be kept up to date.

📝 Suggested documentation update

Update line 16-17 to mention stdout:

 // significant Alertmanager events.  Events are serialized as JSON and
-// fanned out to one or more configured destinations (JSONL file,
-// webhook, kafka).
+// fanned out to one or more configured destinations (JSONL file, stdout,
+// webhook, kafka).

Add stdout.go to the package layout comment:

 //   - file.go        File output and its config.
 //   - webhook.go     Webhook output and its config.
 //   - kafka.go       Kafka output and its config.
+//   - stdout.go      Stdout output and its config.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@eventrecorder/recorder.go` around lines 14 - 33, Update the package-level
documentation in the eventrecorder package to reflect the new stdout output
destination. In the main package comment (around the line describing
destinations), change the list from "(JSONL file, webhook, kafka)" to include
stdout as a new destination option. Additionally, update the package layout
comment section to add stdout.go to the list of files documented, inserting it
logically alongside the other output implementations like file.go, webhook.go,
and kafka.go.

Source: Coding guidelines

🧹 Nitpick comments (1)
eventrecorder/stdout_test.go (1)

98-120: ⚖️ Poor tradeoff

Consider more deterministic synchronization for the integration test.

The time.Sleep(100 * time.Millisecond) on line 114 introduces potential flakiness on slow CI systems. While acceptable for an integration test given the comprehensive unit test coverage, a more robust approach would be to wait on a specific condition (e.g., polling a metric or using a synchronization channel).

That said, this is a low-priority improvement since the unit tests provide deterministic coverage of the core functionality.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@eventrecorder/stdout_test.go` around lines 98 - 120, Replace the hardcoded
time.Sleep(100 * time.Millisecond) in the
TestStdoutOutput_IntegrationWithRecorder function with a more deterministic
synchronization mechanism, such as polling a condition or using a
synchronization channel, to ensure the test waits for the event to actually be
processed rather than relying on an arbitrary delay that can be flaky on slow CI
systems.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@eventrecorder/recorder.go`:
- Around line 14-33: Update the package-level documentation in the eventrecorder
package to reflect the new stdout output destination. In the main package
comment (around the line describing destinations), change the list from "(JSONL
file, webhook, kafka)" to include stdout as a new destination option.
Additionally, update the package layout comment section to add stdout.go to the
list of files documented, inserting it logically alongside the other output
implementations like file.go, webhook.go, and kafka.go.

---

Nitpick comments:
In `@eventrecorder/stdout_test.go`:
- Around line 98-120: Replace the hardcoded time.Sleep(100 * time.Millisecond)
in the TestStdoutOutput_IntegrationWithRecorder function with a more
deterministic synchronization mechanism, such as polling a condition or using a
synchronization channel, to ensure the test waits for the event to actually be
processed rather than relying on an arbitrary delay that can be flaky on slow CI
systems.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e362c9ec-a123-4319-8a3c-023bcc979b6c

📥 Commits

Reviewing files that changed from the base of the PR and between f29d44c and f6ec39e.

📒 Files selected for processing (4)
  • eventrecorder/config.go
  • eventrecorder/recorder.go
  • eventrecorder/stdout.go
  • eventrecorder/stdout_test.go
Comment thread eventrecorder/stdout_test.go Outdated
Comment thread eventrecorder/recorder.go Outdated
Comment thread eventrecorder/recorder.go Outdated
Signed-off-by: Mihir Dixit <dixitmihir1@gmail.com>
@mihir-dixit2k27 mihir-dixit2k27 force-pushed the feat/event-recorder-stdout branch from f6ec39e to 1638bfd Compare June 20, 2026 03:04
@TheMeier

Copy link
Copy Markdown
Contributor

Thanks @mihir-dixit2k27

When testing I noticed the mixed output format when NOT using --log.format=json. Not an issue, but maybe a note is in order about this, or even a gate that disallows using it with default log-format.

@mihir-dixit2k27 mihir-dixit2k27 force-pushed the feat/event-recorder-stdout branch from 3252922 to 2e8f136 Compare June 24, 2026 14:46
Signed-off-by: Mihir Dixit <dixitmihir1@gmail.com>
@mihir-dixit2k27 mihir-dixit2k27 force-pushed the feat/event-recorder-stdout branch from 2e8f136 to 5835040 Compare June 24, 2026 14:51
@mihir-dixit2k27

Copy link
Copy Markdown
Contributor Author

Thanks @mihir-dixit2k27

When testing I noticed the mixed output format when NOT using --log.format=json. Not an issue, but maybe a note is in order about this, or even a gate that disallows using it with default log-format.

Done, added the docs note about --log.format=json @TheMeier. Lmk if you will like any changes to the wording.

@Spaceman1701 Spaceman1701 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.

I don't necessarily have a problem with the implementation as is, but how would you feel about changing it so that it's a logger output instead of directly writing to stdout? This would ensure that the logger config would apply to the event recorder.

@mihir-dixit2k27

Copy link
Copy Markdown
Contributor Author

@Spaceman1701 my thinking is that routing through the logger wraps the event in a log envelope, whereas file_outputs and webhook_outputs emit raw protojson ,wanted stdout to stay consistent with those. Happy to change it if you think it's worth the trade-off.

@Spaceman1701

Copy link
Copy Markdown
Contributor

@Spaceman1701 my thinking is that routing through the logger wraps the event in a log envelope, whereas file_outputs and webhook_outputs emit raw protojson ,wanted stdout to stay consistent with those. Happy to change it if you think it's worth the trade-off.

I don't feel too strongly, I just wanted to raise this to make sure it's been considered. It's also not like having the stdout event output is mutually exclusive with adding a logger based output later.

@mihir-dixit2k27

mihir-dixit2k27 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

I don't feel too strongly, I just wanted to raise this to make sure it's been considered. It's also not like having the stdout event output is mutually exclusive with adding a logger based output later.

makes sense, thanks for raising it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

4 participants