You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(observability): apply WH_LOG_LEVEL to the OTLP log exporter - #850
Before: WH_LOG_LEVEL reached only the stdout handler. Neither the otelslog bridge nor the log SDK filters by level, so with OTLP logs on, WH_LOG_LEVEL=WARN still built and exported every DEBUG and INFO record at otel.logs.sample_rate. The docs said the level applied to both.
After: the OTLP leg sits behind levelGate, which reads the same LevelVar as stdout and runs before the sampler. A record below the level is now neither written nor exported, and because both legs report disabled, slog skips building it at all. The WARN/ERROR 100% floor (invariant #15) still applies to every record the level admits.
How: internal/observability/logger.go adds levelGate (an slog.Handler whose Enabled checks the level, and whose WithAttrs/WithGroup keep the gate) and otlpLeg, which builds gate, then sampler, then exporter. NewLogger uses it. No wiring files changed. configuration.mdx, architecture.md, AGENTS.md and the CHANGELOG are updated to describe the behaviour.
Test plan
New tests in logger_test.go: a level table (WARN drops DEBUG/INFO, ERROR drops WARN, DEBUG admits all), the WARN floor at rate 0, runtime LevelVar changes, and the gate surviving With/WithGroup
make build, go vet ./..., go test -race ./internal/observability/ ./internal/app/
Pre-push code and docs reviewers: ship_it
GitHub CI green on 3c2d706 (lint, unit, integration, E2E, docs, coverage). This stands in for a local make ci, by the owner's decision; the local git hooks were skipped with the owner's OK.
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Advanced
Run ID: 7770eae8-71af-4540-9dd2-d528915d36e5
📥 Commits
Reviewing files that changed from the base of the PR and between 2a9fa5f and 69075f8.
📒 Files selected for processing: 6
AGENTS.md
CHANGELOG.md
docs/src/content/docs/architecture.md
docs/src/content/docs/configuration.mdx
internal/observability/logger.go
internal/observability/logger_test.go
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.
Applicability reference: AGENTS.md: # AGENTS.md — AI Agent Instructions for WaveHouse **Scope** is the canonical docs-prose set from `scripts/docs-prose.sh` — a *denylist*: every tracked `.md`/`.mdx` EXCEPT `.claude/**`, `.github/**`, `CHAN...
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Files:
docs/src/content/docs/configuration.mdx
Source excerpt: **In MDX, leave a blank line between a JSX tag and a code fence.**
📄 CodeRabbit inference engine (AGENTS.md)
Files:
docs/src/content/docs/configuration.mdx
🧠 Learnings: 1📓 Common learnings
Learnt from: CR
Repo: Wave-RF/WaveHouse
Timestamp: 2026-10-14T15:43:00.442Z
Learning: Source excerpt:
# AGENTS.md — AI Agent Instructions for WaveHouse
## Operating Rules
3. **Every code change updates its docs + `CHANGELOG.md` in the same PR** — a code change without its doc update is incomplete ([§Documentation Sync](#documentation-sync)).
🪛 LanguageToolCHANGELOG.md
[typographical] ~33-~33: Consider using an em dash in dialogues and enumerations.
Context: - **WH_LOG_LEVEL now filters the OTLP l...
(DASH_RULE)
docs/src/content/docs/architecture.md
[style] ~198-~198: Consider shortening this phrase to just ‘whether’, unless you mean ‘regardless of whether’.
Context: ...ogger in it too, so stdout carries them whether or not OTLP logs are on. otlpSamplerFn is ex...
(WHETHER)
🔇 Additional comments: 6
internal/observability/logger.go: 1
62-93: LGTM!
Also applies to: 96-99, 117-117
internal/observability/logger_test.go: 1
200-234: LGTM!
Also applies to: 236-250, 252-266, 268-279
AGENTS.md: 1
44-44: LGTM!
CHANGELOG.md: 1
33-33: LGTM!
docs/src/content/docs/architecture.md: 1
198-198: LGTM!
docs/src/content/docs/configuration.mdx: 1
301-301: LGTM!
Also applies to: 334-334
📝 Summary
Summary by CodeRabbit
Bug Fixes
WH_LOG_LEVEL now filters records for both stdout and OTLP logging. Records below the configured level are not written to either output.
OTLP sampling continues to apply to admitted DEBUG and INFO records, while WARN and ERROR records remain exported at 100%.
Documentation
Updated logging and configuration guidance to clarify how the log level and OTLP sampling affect each output.
The OTLP log path now applies the shared WH_LOG_LEVEL threshold before sampling and export. Tests cover threshold changes, derived handlers, and sampling behavior. Documentation and the changelog describe the updated filtering rules.
The OTLP leg checks the shared level before sampling and export. Tests cover configured and changing thresholds, derived handlers, and zero sampling. Documentation describes which records pass the level gate and sampling rules.
sequenceDiagram
participant Logger
participant levelGate
participant sampler
participant OTLPExporter
Logger->>levelGate: Send log record
levelGate->>sampler: Forward record when level meets threshold
sampler->>OTLPExporter: Forward record according to sampling rules
Loading
Suggested reviewers:ericandrechek
Merge Risk:⚪ Minimal · up to 69075
This change makes WH_LOG_LEVEL filter OTLP log export as well as stdout, which matches the documentation. No actionable merge-blocking risk was found.
Pre-merge checks: 4 · 1
Failed checks: 1 warning
Check name
Status
Explanation
Resolution
Docstring Coverage
Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 2 files. (4 skipped: 4…
Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed checks: 4 passed
Check name
Status
Explanation
Linked Issues check
Issue #397 requires WH_LOG_LEVEL to filter the OTLP leg, avoid sub-level export and record construction, and preserve the WARN/ERROR 100% sampling floor. levelGate reads the shared slog.LevelVar…
Out of Scope Changes check
The changed logger code directly implements issue #397. The logger tests verify the new level gate and the existing sampling floor. The configuration, architecture, AGENTS.md, and CHANGELOG updates do…
Title check
The title clearly and concisely identifies the main change: applying WH_LOG_LEVEL to the OTLP log exporter.
Description check
The description directly explains the OTLP level gate, sampling behavior, implementation, documentation updates, and test coverage.
Full details: Docstring Coverage
Explanation
Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 2 files. (4 skipped: 4 unsupported.)
Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
Commit to this branch
Create a new PR
🧪 Generate unit tests (beta)
Commit to this branch
Create a new PR
✨ Simplify code
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
area/docsDocumentation, site/, READMEarea/observabilityMetrics, logs, traces, health, profilingdocumentationImprovements or additions to documentationgoPull requests that update go code
1 participant
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Taite · project thread
Summary
Before:
WH_LOG_LEVELreached only the stdout handler. Neither the otelslog bridge nor the log SDK filters by level, so with OTLP logs on,WH_LOG_LEVEL=WARNstill built and exported every DEBUG and INFO record atotel.logs.sample_rate. The docs said the level applied to both.After: the OTLP leg sits behind
levelGate, which reads the sameLevelVaras stdout and runs before the sampler. A record below the level is now neither written nor exported, and because both legs report disabled, slog skips building it at all. The WARN/ERROR 100% floor (invariant #15) still applies to every record the level admits.How:
internal/observability/logger.goaddslevelGate(anslog.HandlerwhoseEnabledchecks the level, and whoseWithAttrs/WithGroupkeep the gate) andotlpLeg, which builds gate, then sampler, then exporter.NewLoggeruses it. No wiring files changed.configuration.mdx,architecture.md, AGENTS.md and the CHANGELOG are updated to describe the behaviour.Test plan
logger_test.go: a level table (WARN drops DEBUG/INFO, ERROR drops WARN, DEBUG admits all), the WARN floor at rate 0, runtimeLevelVarchanges, and the gate survivingWith/WithGroupmake build,go vet ./...,go test -race ./internal/observability/ ./internal/app/make ci, by the owner's decision; the local git hooks were skipped with the owner's OK.Related Issues
Closes #397
Part of #777.
🤖 Generated with Claude Code
https://claude.ai/code/session_01KLenXpzcNWTroqhcTf5PMX