Skip to content

Migrate logging from stdlib log to log/slog#92

Open
weppos wants to merge 6 commits into
mainfrom
migrate-to-slog
Open

Migrate logging from stdlib log to log/slog#92
weppos wants to merge 6 commits into
mainfrom
migrate-to-slog

Conversation

@weppos
Copy link
Copy Markdown
Member

@weppos weppos commented Apr 22, 2026

Replaces stdlib log with the stdlib log/slog structured logger. Follows the template established by https://github.com/dnsimple/dnsimple-notifier/pull/443.

This PR:

  • Adds internal/logging with a bridge to use slog, and helpers like logging.Err
  • Replaces every log.Print* / log.Fatal with slog.Info / slog.Error; request data moves into structured attrs (http_method, http_url, event_id)
  • config.init() calls slog.SetDefault once; cmd/main uses run() error
  • LOG_LEVEL accepts debug|info|warn|error
  • Standardizes HTTP request attribute keys on the canonical http_* prefix (http_method, http_url, http_user_agent, http_referer, http_scheme, http_forwarded_for, client_ip, duration_ms); only existing logged fields were renamed, no new ones added

Log output uses slog JSON defaults: time (RFC 3339 nanoseconds), msg, uppercase level, plus a source group from AddSource: true. Error key is "error" via logging.Err.

Belongs to https://github.com/dnsimple/dnsimple-engineering/issues/286

📋 Deployment Pre/Post tasks

  • PRE: Add a Datadog Date Remapper for the time field
  • PRE: Add a Datadog Status Remapper for the level field
  • PRE: Add a Datadog Message Remapper for the msg field
  • PRE: (optional) Add a Datadog Attribute Remapper from http_* keys to DD's canonical @http.* facets if APM correlation or the User-Agent parser is desired

:shipit: Deployment Verification

  • Production: Log lines appear in Datadog with the new field shape and parse correctly
  • Sandbox: Log lines appear in Datadog with the new field shape and parse correctly

Replace stdlib log with log/slog. Introduce a self-contained internal/logging
package with New / ParseLevel, context helpers, a BugsnagLogger adapter (kept
for workspace template parity even though strillone does not use Bugsnag),
and an Err helper returning slog.Attr keyed on "error".

config.init() calls slog.SetDefault once. Every call site uses slog.Info /
slog.Error. cmd/main refactored to run() error shape.

LOG_LEVEL accepts "debug |info|warn|error".
@weppos weppos self-assigned this Apr 22, 2026
weppos added 5 commits April 22, 2026 20:33
This repo does not use github.com/bugsnag/bugsnag-go, so the
internal/logging.BugsnagLogger adapter was dead code carried forward from
the workspace template during the zerolog → slog migration.
Rename HTTP request logging keys to a canonical http_-prefixed set for
consistency across the workspace:
- request_url / url -> http_url
- request_method / method -> http_method
- user_agent -> http_user_agent (kept where already named so)
- forwarded_for -> http_forwarded_for
- ip -> client_ip
- scheme -> http_scheme
- request_time -> duration_ms

Only touches existing call sites — no new fields are introduced.
Go idiom prefers explicit bootstrap in main() over init() side effects:
tests don't carry the import-time setup burden, the execution sequence is
visible, and log output is fully consistent from the first line.

Matches the pattern already used in go-remote-control-internal and
nomad-deployer.
Wraps slog.SetDefault(logging.New(logging.ParseLevel(os.Getenv("LOG_LEVEL"))))
into a single call and emits a "Logger initialized" log line so the active
level is visible at startup. Each main() now starts with:

    logging.SetupDefault()

replacing the longer boilerplate and restoring the init-time confirmation
log that was lost when setup moved out of config.init().
Config loading was moved out of config.init() into main(), so tests
that depend on config.Config must load it themselves.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant