Skip to content

fix: replace log.Printf with structured slog logging in auth and ratelimit modules#63

Merged
aaronbrethorst merged 3 commits into
OneBusAway:mainfrom
Vedd-Patel:fix/auth-slog-cleanup
Jun 5, 2026
Merged

fix: replace log.Printf with structured slog logging in auth and ratelimit modules#63
aaronbrethorst merged 3 commits into
OneBusAway:mainfrom
Vedd-Patel:fix/auth-slog-cleanup

Conversation

@Vedd-Patel

@Vedd-Patel Vedd-Patel commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes #52

This PR addresses the minor housekeeping items identified during the authentication module review. It standardizes logging across the newly added auth files to match the rest of the codebase

Changes

  • auth.go: Replaced standard log.Printf calls with structured slog.Warn and slog.Error for login failures and token validation errors. Removed the standard log import.
  • ratelimit.go: Replaced standard log.Printf calls with structured slog.Warn for capacity warnings and rate limit triggers. Removed the standard log import.
  • main.go: Replaced the stale // TODO: protect with requireAuth once auth lands comment above the /api/v1/admin/status endpoint with // intentionally public for health monitoring, as requested.

Local Testing

  • Formatted code with go fmt ./...
  • Passed linter checks with go vet ./...
  • All tests pass locally (go test ./... -v)
  • Verified structured JSON logs are correctly emitted in the terminal output when testing rate limits and invalid logins.

Summary by CodeRabbit

  • Chores
    • Migrated application logging to structured format for consistent error and warning records.
    • Enhanced warning output to include key/value attributes (e.g., capacity, key) for clearer diagnostics.
    • Preserved existing HTTP responses, public interfaces, and observable API behavior.

@aaronbrethorst aaronbrethorst left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ved, good instinct to standardize the logging — the codebase should be consistent on slog, and cleaning up stale log.Printf calls is worthwhile. There are a few things that need fixing before this can land.

Critical Issues (1 found)

main.go change conflicts with merged PR #59 and reverses a security fix

This PR replaces the // TODO: protect with requireAuth once auth lands comment with // intentionally public for health monitoring and leaves the /api/v1/admin/status endpoint unprotected. However, PR #59 (merged today) already resolved this TODO correctly — it wraps the endpoint with authMiddleware(adminMiddleware(...)), requiring both authentication and admin role.

This PR has a merge conflict (CONFLICTING state on GitHub), and if resolved by keeping this PR's version, it would revert a security fix by removing the auth protection on the admin status endpoint.

Fix: Rebase onto latest main and drop the main.go change entirely. PR #59 already handled this correctly.

Important Issues (2 found)

1. Two log messages have wrong descriptions

auth.go:74 logs "token validation failed" for what is actually a database error during GetUserByEmail. auth.go:85 logs the same "token validation failed" for what is actually a bcrypt internal error (not a password mismatch — that's handled on line 81). The original messages ("login: database error" and "login: bcrypt error") were more accurate.

When an engineer sees "token validation failed" in logs three times, they'll assume it's the same code path. But these are three different failure modes — a database error, a bcrypt library error, and an actual token validation failure — and they require different investigation steps.

Fix: Use descriptive messages that match the actual failure:

  • Line 74: slog.Error("login: database error", "error", err)
  • Line 85: slog.Error("login: bcrypt error", "error", err)
  • Line 137: slog.Warn("token validation failed", "error", err) (this one is correct)

2. Severity should be slog.Error for internal server errors, not slog.Warn

Lines 74 and 85 are error paths that return HTTP 500 — these represent genuine internal failures (database unreachable, bcrypt library malfunction). Similarly, line 92 ("token generation failed") returns 500. These should be slog.Error, not slog.Warn. Warnings are appropriate for client errors or degraded-but-functional states (like the rate limiter capacity warning in ratelimit.go, which is correct as slog.Warn).

The token validation failure on line 137 is correctly slog.Warn since it's a client-side error (bad token) returning 401, not a server failure.

Suggestions (0 found)

Strengths

  • The ratelimit.go change is clean and correct — structured logging with "capacity" and "key" fields is a nice improvement over the format string
  • Removing the "log" import in favor of "log/slog" is the right direction
  • Good local testing checklist in the PR description

Recommended Action

  1. Rebase onto latest main and drop the main.go change (already handled by PR #59)
  2. Fix the misleading log messages in auth.go to match their actual error conditions
  3. Use slog.Error instead of slog.Warn for paths that return HTTP 500

@Vedd-Patel Vedd-Patel force-pushed the fix/auth-slog-cleanup branch from 618b141 to 9e1986c Compare March 26, 2026 06:00
@aaronbrethorst

Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Apr 22, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

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.

@coderabbitai

coderabbitai Bot commented Apr 22, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 36e5516e-0025-4c9e-a8e2-f4a8f0cfd32d

📥 Commits

Reviewing files that changed from the base of the PR and between d9070fe and e29cf5d.

📒 Files selected for processing (1)
  • auth.go

📝 Walkthrough

Walkthrough

Replaced unstructured log.Printf calls with structured log/slog logging in authentication and rate-limiting code. handleLogin now emits slog.Error for DB, bcrypt, and JWT failures. requireAuth distinguishes jwt.Parse errors vs. invalid tokens and emits slog.Warn. Rate limiter warning uses slog.Warn with structured fields. No API or exported signatures changed.

Changes

Cohort / File(s) Summary
Auth logging
auth.go
Replaced log.Printf usage with slog.Error/slog.Warn. handleLogin logs DB lookup, bcrypt compare, and JWT generation failures with structured "error" fields. requireAuth now logs parse errors and invalid-token cases separately via slog.Warn. Removed log import.
Rate limiter logging
ratelimit.go
Replaced log.Printf with slog.Warn when tracked capacity is reached, emitting structured attributes (capacity, key). Removed log import usage.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: replacing log.Printf with structured slog logging across auth and ratelimit modules.
Linked Issues check ✅ Passed The PR addresses all coding requirements from issue #52: replaced log.Printf with slog in auth.go and ratelimit.go at specified locations, and resolved the stale TODO in main.go with an explicit intentional note.
Out of Scope Changes check ✅ Passed All changes directly align with issue #52 requirements: structured logging migration in auth.go and ratelimit.go, and the TODO resolution in main.go; no extraneous modifications detected.

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

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

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

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

🧹 Nitpick comments (1)
auth.go (1)

163-165: Optional: avoid emitting error=nil on invalid token path.

When token.Valid is false and err is nil, current logging records a null error field. Splitting branches makes logs clearer.

♻️ Proposed refinement
-			if err != nil || !token.Valid {
-				slog.Warn("token validation failed", "error", err)
-				writeJSON(w, http.StatusUnauthorized, map[string]string{"error": "invalid token"})
-				return
-			}
+			if err != nil {
+				slog.Warn("token validation failed", "error", err)
+				writeJSON(w, http.StatusUnauthorized, map[string]string{"error": "invalid token"})
+				return
+			}
+			if !token.Valid {
+				slog.Warn("token validation failed: token marked invalid")
+				writeJSON(w, http.StatusUnauthorized, map[string]string{"error": "invalid token"})
+				return
+			}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@auth.go` around lines 163 - 165, The log call should not emit a nil error
when token.Valid is false; in the token validation branch (where token.Valid and
err are checked) split the condition into two branches: if err != nil then call
slog.Warn (or slog.Error) including the error value, else if token.Valid is
false then call slog.Warn with a descriptive message but no "error" field; keep
the existing writeJSON(w, http.StatusUnauthorized, ...) response in both
branches so authentication failure behavior is unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@auth.go`:
- Around line 163-165: The log call should not emit a nil error when token.Valid
is false; in the token validation branch (where token.Valid and err are checked)
split the condition into two branches: if err != nil then call slog.Warn (or
slog.Error) including the error value, else if token.Valid is false then call
slog.Warn with a descriptive message but no "error" field; keep the existing
writeJSON(w, http.StatusUnauthorized, ...) response in both branches so
authentication failure behavior is unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ab76bfb7-5da0-466c-a0a8-8e0dcee72fc8

📥 Commits

Reviewing files that changed from the base of the PR and between 23e535b and 9e1986c.

📒 Files selected for processing (2)
  • auth.go
  • ratelimit.go

@Vedd-Patel Vedd-Patel changed the title Fix/auth slog cleanup fix: replace log.Printf with structured slog logging in auth and ratelimit modules Apr 22, 2026
@Vedd-Patel

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Apr 22, 2026

Copy link
Copy Markdown
✅ Actions performed

Full review triggered.

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@auth.go`:
- Around line 163-173: Remove the stray diff marker '+' characters at the start
of the token validation guard clauses so the Go statements compile; edit the
block that checks err and token.Valid (the lines that call slog.Warn(...),
writeJSON(...), and return) to remove the leading '+' on each line so the code
reads as valid Go (refer to the token validation block using variables err,
token.Valid, slog.Warn, writeJSON, and w).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 090025e3-d22f-453f-9377-40f2285fb9d7

📥 Commits

Reviewing files that changed from the base of the PR and between 9e1986c and d9070fe.

📒 Files selected for processing (1)
  • auth.go

Comment thread auth.go Outdated

@aaronbrethorst aaronbrethorst left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ved, this is exactly the follow-through I was hoping for. Every item from the last round is handled, and the diff is tighter for it.

Prior Feedback — All Addressed

Critical: main.go conflict / security revert — resolved

The main.go change is dropped entirely. The PR no longer touches that file, git diff main...HEAD -- main.go is empty, and GitHub now reports MERGEABLE / CLEAN (was CONFLICTING). PR #59's auth protection on /api/v1/admin/status stays intact.

Important #1: Misleading log messages — fixed

  • auth.go:73slog.Error("login: database error", "error", err)
  • auth.go:84slog.Error("login: bcrypt error", "error", err)
  • auth.go:164 / :170"token validation failed" (correct — these are the genuine token-validation paths)

Each message now matches its actual failure mode.

Important #2: Severity — fixed

The three HTTP 500 paths (:73, :84, :91) are now slog.Error. The two 401 client-error paths in requireAuth (:164, :170) correctly stay slog.Warn, as does the rate-limiter capacity warning. Severity now lines up with whether the failure is server-side or client-side.

Critical Issues (0 found)

Important Issues (0 found)

Suggestions (0 found)

Strengths

  • Splitting the old if err != nil || !token.Valid into two branches (:163 and :169) is a real readability win — the two failure modes now log distinctly instead of collapsing into one ambiguous line.
  • ratelimit.go structured logging with "capacity" and "key" attributes reads cleanly.
  • Dropping the "log" import in favor of "log/slog" is the right direction for codebase consistency.
  • Verified locally: go test ./... passes, go vet ./... clean, gofmt -l reports nothing.

Recommended Action

Ship it. No further changes needed.

@aaronbrethorst aaronbrethorst merged commit 689bde6 into OneBusAway:main Jun 5, 2026
3 checks passed
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.

Auth module: use slog consistently and resolve stale TODO

2 participants