[claude]
Problem
On a postgres lane the session opened and session closed log lines carry two principal keys:
{"msg":"session opened","principal":"anonymous","principal":"app_user","upstream":"db.example.internal:5432"}The logger is built with principal=anonymous before the pgwire StartupMessage is read. When the user is learned, log.With("principal", user) appends a second key. slog never replaces an attribute. The deferred teardown logs through the same logger, so session closed shows it too.
Fix
Rebuild the logger from the root with the final principal. One line in sidecar/proxy/proxy.go.
How to test
make test-sidecar, or the one test:
cd sidecar && CGO_ENABLED=0 go test ./proxy/ -run TestSessionLinesLogThePrincipalOnce -count=1The test starts a postgres lane with a JSON logger, sends a StartupMessage for user alice, and decodes the session opened and session closed lines with a token decoder that counts top-level principal keys. It fails on the old code with principal keys = ["anonymous" "alice"].
Manual: open psql through a postgres lane and check both lines have one principal key.
Not in scope
The session_start audit event also reports anonymous, because the gate starts before the startup message is read. The store folds later events, so the session row ends up correct. Reordering that is a separate change.
🤖 Generated with Claude Code
Activity
7I have read the CLA Document and I hereby sign the CLA
PR Summary by Qodo
Log one pgwire principal per sidecar session line
🐞 Bug fix 🧪 Tests 🕐 10-20 Minutes
AI Description
-
• Rebuilds pgwire session loggers with the discovered user, preventing duplicate principal keys. • Verifies opened and closed JSON logs contain exactly one final principal.
Diagram
-
sequenceDiagram actor Client as PostgreSQL Client participant Proxy as Sidecar Proxy participant PGWire as PGWire Negotiation participant Logger as Root Logger Client->>Proxy: Open connection Proxy->>Logger: Create anonymous context Proxy->>PGWire: Read startup message PGWire-->>Proxy: Return claimed user Proxy->>Logger: Rebuild final context Logger-->>Proxy: Single principal logger Proxy->>Logger: Log opened and closed
High-Level Assessment
-
Rebuilding the session logger from the root is the best approach because slog attributes are append-only and cannot safely overwrite the earlier anonymous principal. Delaying principal attachment would complicate non-PostgreSQL and pre-negotiation logging, while handler-level duplicate suppression would introduce broad behavior for a localized issue.
Files changed (2) +123 / -1
-
Bug fix (1)
+4 / -1-
proxy.go
Rebuild pgwire logger with the final principal+4/-1
Rebuild pgwire logger with the final principal
• Recreates the session logger from the server’s root logger after pgwire reveals the claimed user. This preserves the session identifier while preventing the initial anonymous and final user principals from appearing together on lifecycle log lines.
Tests (1)
+119 / -0-
proxy_test.go
Verify one principal on session lifecycle logs+119/-0
Verify one principal on session lifecycle logs
• Adds a pgwire StartupMessage builder, synchronized log buffer, and duplicate-aware JSON token decoder. The regression test confirms both session-opened and deferred session-closed lines contain exactly one principal with the discovered user.
-
Code Review by Qodo
🐞 Bugs (0) 📘 Rule violations (1) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)
1. A deadline failure can hang the test 📘 Rule violation ☼ Reliability
Description
TestSessionLinesLogThePrincipalOnce ignores errors from Write, SetReadDeadline, ReadFull, and Close. If deadline setup fails or network I/O is partial, the test can block or continue after an incomplete exchange, obscuring whether the regression path ran.
Code
sidecar/proxy/proxy_test.go[R370-373]+ c.Write(pgStartup("alice")) + c.SetReadDeadline(time.Now().Add(2 * time.Second)) + io.ReadFull(c, make([]byte, len(pgStartup("alice")))) + c.Close()
Relevance
●●● StrongExplicit I/O error handling is a deterministic reliability fix, consistent with recent accepted test-safety feedback.
ⓘ Recommendations generated based on similar findings in past PRs
Evidence
Compliance rule 1807206 requires errors from OS, execution, and I/O calls to be handled or propagated. The added test invokes four network I/O operations without checking any returned error or documenting why it is safe to ignore them.
Rule 1807206: Do not ignore errors from OS/exec/IO calls; handle or propagate themsidecar/proxy/proxy_test.go[370-373]
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution ## Issue description The new regression test ignores errors returned by its connection write, deadline setup, response read, and close operations, allowing hangs or incomplete exchanges. ## Fix Focus Areas - sidecar/proxy/proxy_test.go[370-373] ## Recommended Fix Check each returned error and fail the test immediately with operation-specific context. Also verify the write and read byte counts, and treat any close error as a test failure unless explicitly documented as safe to ignore.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Context sources
80 rules⚖️ Balanced: This is a localized runtime logging fix with a focused regression test, but it changes session logger construction on a proxy path and merits a complete single-pass review.Tip of the day
💡 Did you know, you can reply 'qodo' on any finding to push back, ask questions, or dig deeper
All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.