Skip to content

Comments

Wide event logging#59

Closed
mishankov wants to merge 13 commits intomainfrom
log2
Closed

Wide event logging#59
mishankov wants to merge 13 commits intomainfrom
log2

Conversation

@mishankov
Copy link
Member

@mishankov mishankov commented Feb 14, 2026

Summary by CodeRabbit

  • New Features

    • Added a configurable wide-event logging system with lifecycle events, steps, errors, tail-sampling, JSON/text output, sensible defaults, and a default logger.
    • Added HTTP middleware that records one rich event per request (request/response details, route, panic handling).
    • Context-aware propagation of event data (trace/user IDs).
  • Tests

    • Comprehensive unit and integration tests covering events, middleware, sampling, and helpers.
  • Documentation

    • New docs page and navigation entry for the logging package.
  • Chores

    • Minor lint suppression and docs dev script tweaks.

@coderabbitai
Copy link

coderabbitai bot commented Feb 14, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new event-based logging package "log2": configurable Logger and Config defaults, context-attached Event objects (Add/Step/Error/Finish), a rule-driven tail sampler, HTTP middleware emitting one wide request event, and comprehensive unit tests and documentation.

Changes

Cohort / File(s) Summary
Configuration & Defaults
log2/config.go
Add Config and DefaultConfig() with Writer, Format, Level, ContextKeys, Sampler, and MaxSteps; set sensible defaults (stdout, "json", info, default tail sampler, default max steps).
Context Integration
log2/context.go, log2/context_test.go
Introduce LogEventContextKey, WithEvent(), EventFromContext(); tests validate context propagation, Start() integration, and JSON output.
Event Core
log2/event.go, log2/event_test.go
Add Event type, ErrEventAlreadyFinished, methods Add/Step/Error/Finish, internal payload conversion, step capping, and sampling interaction; tests cover lifecycle, concurrency, double-finish, attribute behavior, and sampling outcomes.
Logger & Emission
log2/logger.go
Add Logger type, New(Config), SetDefault, package Default, Start helpers, and emit() which builds slog.Record and writes via configured handler (JSON/text).
Tail Sampling
log2/sampling.go, log2/sampling_test.go
Add TailSampler interface, DefaultTailSamplerConfig, KeepRule, EventView, SamplingDecision, NewDefaultTailSampler with rule evaluation (eq, in, exists, true) and random fallback; tests cover error/status/slow/rule/random paths.
HTTP Middleware
log2/http_middleware.go, log2/http_middleware_test.go
Add NewHTTPMiddleware and HTTPMiddlewareConfig to emit one wide event per request (method/path/route/status/bytes), inject event into request context, recover panics (log then re-panic); tests for normal and panic flows.
Test Helpers
log2/test_helpers_test.go
Add readEvents(), requireMap(), requireSlice(), and samplerFunc adapter to parse newline JSON events and support deterministic sampler testing.
Minor Linting
log/log.go
Adjust package comment to suppress revive linter with no functional changes.
Docs
docs/astro.config.mjs, docs/src/content/docs/packages/log2.mdx
Expose packages/log2 in docs config and add a new MDX page documenting usage, lifecycle, sampling, and middleware examples.
Docs tooling
Taskfile.dist.yml, docs/package.json
Change docs dev runner: use bun run dev and add --host to astro dev script.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Middleware as HTTP Middleware
    participant Logger
    participant Event
    participant Sampler
    participant Handler as slog Handler

    Client->>Middleware: HTTP Request
    Middleware->>Logger: Start(ctx, "http_request", attrs)
    Logger->>Event: initialize (context attrs + supplied attrs)
    Middleware->>Event: Add(request/response attrs)
    Note over Middleware,Event: Handler runs (deferred Finish)
    alt Handler panics
        Middleware->>Event: Error(panic)
    end
    Middleware->>Event: Finish(status, bytes)
    Event->>Sampler: ShouldSample(EventView)
    Sampler-->>Event: SamplingDecision{Keep,Reason}
    alt Keep == true
        Event->>Logger: emit(eventPayload)
        Logger->>Handler: Handle(slog.Record)
    end
    Middleware-->>Client: HTTP Response (or re-panic)
Loading
sequenceDiagram
    participant App
    participant Logger
    participant Event
    participant Sampler as Tail Sampler
    participant Handler

    App->>Logger: New(Config)
    Logger-->>App: *Logger (with sampler, context keys)
    App->>Logger: Start(ctx, name, attrs...)
    Logger->>Event: create with ctx attrs
    App->>Event: Add/Step/Error...
    App->>Event: Finish(attrs)
    Event->>Sampler: ShouldSample(view)
    Sampler->>Sampler: evaluate errors/status/slow/rules/random
    Sampler-->>Event: SamplingDecision
    alt Keep == true
        Event->>Logger: emit(payload)
        Logger->>Handler: write formatted record
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hop with a pen and an eager twitch,
I mark each step and catch the glitch,
Rules and tails to keep the tale,
HTTP hops and panic trail,
Logs neatly stitched in a carrot-rich dish. 🥕

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.05% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Wide event logging' accurately describes the main addition of this pull request: a comprehensive wide-event logging system for the log2 package with configurable events, steps, errors, sampling, and HTTP middleware.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch log2

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

@coveralls
Copy link

coveralls commented Feb 14, 2026

Pull Request Test Coverage Report for Build 22051299645

Details

  • 0 of 646 (0.0%) changed or added relevant lines in 9 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-12.7%) to 25.45%

Changes Missing Coverage Covered Lines Changed/Added Lines %
log3/logger.go 0 12 0.0%
log2/config.go 0 13 0.0%
log2/context.go 0 14 0.0%
log3/sampler.go 0 32 0.0%
log2/middleware.go 0 63 0.0%
log2/logger.go 0 80 0.0%
log3/event.go 0 88 0.0%
log2/sampling.go 0 115 0.0%
log2/event.go 0 229 0.0%
Totals Coverage Status
Change from base Build 21670678201: -12.7%
Covered Lines: 495
Relevant Lines: 1945

💛 - Coveralls

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@log2/context.go`:
- Around line 24-26: WithEvent currently calls context.WithValue on the incoming
ctx which will panic if ctx is nil; mirror EventFromContext's guard by checking
for nil and substituting context.Background() before calling context.WithValue.
Update the WithEvent function to do: if ctx == nil { ctx = context.Background()
} then return context.WithValue(ctx, LogEventContextKey, ev) so it no longer
panics on nil contexts.

In `@log2/http_middleware.go`:
- Around line 50-55: The middleware currently adds the client's raw r.RemoteAddr
to requestAttrs (see requestAttrs map in http_middleware.go), which may expose
PII; update the middleware to make including remoteAddr opt-in via a
configuration flag or context option (e.g., includeRemoteAddr boolean) and when
enabled redact or normalize the value (strip port with net.SplitHostPort or
replace with a hashed/pseudonymized token) before inserting into requestAttrs;
also document the opt-in behavior and default it to disabled so remote IPs are
not logged unless explicitly allowed.
- Around line 83-99: The statusRecorder wrapper currently embeds
http.ResponseWriter but doesn't forward optional interfaces, causing type
assertion failures for handlers expecting Hijacker, Flusher, or Pusher; update
the statusRecorder type to implement and forward these by adding methods
Hijack() (net.Conn, *bufio.ReadWriter, error), Flush(), and Push(target string,
opts *http.PushOptions) error that first check whether r.ResponseWriter
implements the corresponding interface and, if so, delegate the call and return
its results (otherwise return the zero-values/error as appropriate or no-op for
Flush), leaving existing methods WriteHeader and Write unchanged.

In `@log2/logger.go`:
- Around line 53-61: The package-level Default variable is written unsafely by
SetDefault and read by Start/Logger.Start; replace the raw global with an
atomic.Pointer[Logger] (e.g., var Default atomic.Pointer[Logger]) and update
SetDefault to use Default.Store(ptr) (storing a pointer returned from
New(DefaultConfig()) when l==nil or the provided l), and update all reads (Start
and Logger.Start) to use Default.Load() and check for nil before dereferencing;
ensure nil handling mirrors existing behavior so callers still get a valid
logger when none was set.
🧹 Nitpick comments (1)
log2/context.go (1)

7-8: Prefer a typed, immutable context key.

any makes the exported key reassignable/type-unsafe from other packages, which can silently break lookups. Use the unexported contextKey type directly to prevent accidental mutation.

♻️ Suggested change
- var LogEventContextKey any = contextKey("platformaLog2Event") //nolint:gochecknoglobals
+ var LogEventContextKey = contextKey("platformaLog2Event") //nolint:gochecknoglobals

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@Taskfile.dist.yml`:
- Line 27: Update documentation and/or Taskfile to keep docs build working for
contributors without bun: either change docs/README.md to require bun (mention
docs/bun.lock and add install + "bun run dev" instructions) or modify the
Taskfile docs target (replace the single "- bun run dev" invocation with a
fallback that tries bun first then falls back to npm/yarn, e.g. an OR-style or
conditional that runs "bun run dev" and if it fails runs "npm run dev" or "yarn
dev"). Ensure you reference Taskfile's docs target and docs/README.md so both
the task and the README are consistent.
🧹 Nitpick comments (1)
docs/package.json (1)

6-6: Consider avoiding unconditional --host to reduce unintended exposure.
--host binds the dev server to all network interfaces (0.0.0.0), making it reachable from other devices on your LAN. While convenient, this can expose the docs server on shared networks. Consider adding a separate script (e.g., dev:host) or documenting when to use host binding, so the default dev script keeps the server localhost-only.

🔧 Suggested script split
   "scripts": {
-    "dev": "astro dev --host",
+    "dev": "astro dev",
+    "dev:host": "astro dev --host",
     "start": "astro dev",
     "build": "astro build",
     "preview": "astro preview",
     "astro": "astro"
   },

dir: docs
cmds:
- npm run dev
- bun run dev
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for bun mentions in key documentation files
echo "=== Checking for bun in documentation ==="
find . -maxdepth 3 \( -name "README.md" -o -name "CONTRIBUTING.md" -o -name "package.json" \) | head -20 | while read f; do
  if [ -f "$f" ]; then
    echo "--- File: $f ---"
    rg -i "bun" "$f" || echo "No mention of bun"
  fi
done

echo -e "\n=== Checking Taskfile.dist.yml context ==="
if [ -f "Taskfile.dist.yml" ]; then
  head -40 Taskfile.dist.yml
fi

echo -e "\n=== Looking for bun in all YAML files ==="
rg -i "bun" --type yaml || echo "No bun mentions in YAML files"

Repository: platforma-dev/platforma

Length of output: 919


🏁 Script executed:

#!/bin/bash
# Check the overall tooling and dependencies
echo "=== Checking for package managers references ==="
rg -i "pnpm|npm|yarn|bun" package.json 2>/dev/null | head -20

echo -e "\n=== Check if there's a .node-version, .tool-versions, or similar ==="
ls -la | grep -E "^\." | head -20

echo -e "\n=== Check git history to see what changed ==="
git log --oneline -20 2>/dev/null || echo "Git history not available"

Repository: platforma-dev/platforma

Length of output: 267


🏁 Script executed:

#!/bin/bash
# Check the docs directory structure and dependencies
echo "=== Docs directory structure ==="
ls -la docs/ | head -30

echo -e "\n=== Contents of docs/package.json ==="
if [ -f "docs/package.json" ]; then
  cat docs/package.json
fi

echo -e "\n=== Check for lockfiles in docs ==="
ls -la docs/ | grep -E "lock|yarn|pnpm"

echo -e "\n=== Check if root has package.json ==="
if [ -f "package.json" ]; then
  cat package.json
fi

echo -e "\n=== Check for any dev setup docs ==="
find . -maxdepth 2 -name "*SETUP*" -o -name "*setup*" -o -name "*DEV*" 2>/dev/null | grep -v node_modules | head -10

Repository: platforma-dev/platforma

Length of output: 1371


🏁 Script executed:

#!/bin/bash
# Check the docs README for setup instructions
echo "=== Contents of docs/README.md ==="
cat docs/README.md

Repository: platforma-dev/platforma

Length of output: 1888


Update documentation to reflect bun as the required package manager for docs, or add a fallback.

The docs task now requires bun run dev, but docs/README.md still instructs contributors to use npm install and npm run dev. This mismatch will break the workflow for contributors without bun. Since docs/bun.lock confirms bun is the intended package manager, update docs/README.md to document bun as a requirement, or add a fallback command in the Taskfile to maintain npm compatibility.

🔧 Fallback option for Taskfile
   docs:
     dir: docs
     cmds:
-      - bun run dev
+      - |
+          if command -v bun >/dev/null 2>&1; then
+            bun run dev
+          else
+            npm run dev
+          fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- bun run dev
docs:
dir: docs
cmds:
- |
if command -v bun >/dev/null 2>&1; then
bun run dev
else
npm run dev
fi
🤖 Prompt for AI Agents
In `@Taskfile.dist.yml` at line 27, Update documentation and/or Taskfile to keep
docs build working for contributors without bun: either change docs/README.md to
require bun (mention docs/bun.lock and add install + "bun run dev" instructions)
or modify the Taskfile docs target (replace the single "- bun run dev"
invocation with a fallback that tries bun first then falls back to npm/yarn,
e.g. an OR-style or conditional that runs "bun run dev" and if it fails runs
"npm run dev" or "yarn dev"). Ensure you reference Taskfile's docs target and
docs/README.md so both the task and the README are consistent.

@mishankov mishankov linked an issue Feb 15, 2026 that may be closed by this pull request
@mishankov mishankov closed this Feb 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wide events loggin support

2 participants