Add structured logging to services#273
Conversation
Signed-off-by: Fabian Gonzalez <[email protected]>
…er, importer) Signed-off-by: Fabian Gonzalez <[email protected]>
|
@inFocus7 is this ready for review or still in progress? |
|
It's ready but I was (originally) planning on waiting until morning to mark it |
There was a problem hiding this comment.
Pull request overview
This PR standardizes structured JSON-based logging across the registry service by migrating all usages of the standard log package to Go's log/slog package. This addresses issue #101 and aligns with the project's AGENTS.md convention. The key benefit is queryable, machine-readable JSON log output (demonstrated in the PR description) and a consistent logging approach.
Changes:
- Sets up a JSON
sloghandler incmd/server/main.goas the process-wide default logger before any services are initialized - Migrates all
log.Printf/log.Println/log.Fatalfcalls across service, database, importer, seed, config, API, and validator packages to structuredslogequivalents - Adds a
logger *slog.Loggerfield (initialized viaslog.Default().With("component", "<name>")) toregistryServiceImpl,indexerImpl, andimporter.Servicestructs for component-scoped logging
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
cmd/server/main.go |
Configures slog.NewJSONHandler and sets it as the global default logger before invoking the app |
internal/registry/config/config.go |
Replaces log.Printf/log.Fatalf with slog.Info/slog.Error; adds os import for os.Exit |
internal/registry/registry_app.go |
Migrates all startup, shutdown, and operational log calls to slog |
internal/registry/api/server.go |
Migrates HTTP server start/stop log calls; adds "fmt" import for URL formatting |
internal/registry/database/postgres.go |
Replaces log.Printf for failed transaction rollback with slog.Error |
internal/registry/importer/importer.go |
Adds logger field to Service; migrates all log calls; consolidates validation summary into one structured log entry |
internal/registry/seed/builtin.go |
Replaces log calls with global slog calls |
internal/registry/service/registry_service.go |
Adds logger field; migrates all log.Printf calls to structured slog calls |
internal/registry/service/indexer.go |
Adds logger field; migrates all log.Printf calls to slog |
internal/registry/validators/registries/oci.go |
Replaces log.Printf with slog.Info for rate-limiting event |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Signed-off-by: Fabian Gonzalez <[email protected]>
Signed-off-by: Fabian Gonzalez <[email protected]>
Signed-off-by: Fabian Gonzalez <[email protected]>
<!-- Thanks for opening a PR! Please delete any sections that don't apply. --> # Description <!-- A concise explanation of the change. You may include: - **Motivation:** why this change is needed - **What changed:** key implementation details - **Related issues:** e.g., `Fixes agentregistry-dev#123` --> Setting up structured logging, namely json-based logging, to give us a standard on how to log (instead of our current mix of `log.` and `slog.`) plus make querying debugging easier by having a queriable(?) standard for logs. We already have an **AGENTS.md** that bring up using `slog`, so moving to using that throughout the services will also lessen any agentic confusion to avoid any "file says to use `slog`, but wait I see `log` used". Resolves agentregistry-dev#101 ## Example Below is the logs from docker + an example of better json querying instead of needing to do find searches / grepping. ```sh docker logs agentregistry-server ``` ``` 2026-03-05T22:40:15.775900636Z {"time":"2026-03-05T22:40:15.775801928Z","level":"INFO","msg":"using public authz provider"} 2026-03-05T22:40:15.784088969Z {"time":"2026-03-05T22:40:15.783974594Z","level":"INFO","msg":"No pending migrations"} 2026-03-05T22:40:15.784103094Z {"time":"2026-03-05T22:40:15.784005678Z","level":"INFO","msg":"starting agentregistry","version":"v0.0.0-32fa010","commit":"32fa010"} 2026-03-05T22:40:15.784263053Z {"time":"2026-03-05T22:40:15.784178969Z","level":"INFO","msg":"reconciling existing deployments at startup"} 2026-03-05T22:40:15.784817719Z {"time":"2026-03-05T22:40:15.784770469Z","level":"WARN","msg":"failed to reconcile deployments at startup","error":"failed to get deployments: failed to get deployments from DB: failed to query deployments: ERROR: column d.id does not exist (SQLSTATE 42703)"} 2026-03-05T22:40:15.784822678Z {"time":"2026-03-05T22:40:15.784790303Z","level":"WARN","msg":"server will continue starting, but deployments may not be in sync"} 2026-03-05T22:40:15.784824678Z {"time":"2026-03-05T22:40:15.784798969Z","level":"INFO","msg":"UI handler initialized; web interface will be available"} 2026-03-05T22:40:15.788176178Z {"time":"2026-03-05T22:40:15.788063386Z","level":"INFO","msg":"HTTP server starting","address":":8080"} 2026-03-05T22:40:15.788189719Z {"time":"2026-03-05T22:40:15.788085678Z","level":"INFO","msg":"web UI available","url":"http://localhost:8080/"} 2026-03-05T22:40:15.788191261Z {"time":"2026-03-05T22:40:15.788088386Z","level":"INFO","msg":"API documentation available","url":"http://localhost:8080/docs"} ``` ```sh docker logs agentregistry-server | jq 'select(.level == "WARN")' ``` ```json { "time": "2026-03-05T22:40:15.784770469Z", "level": "WARN", "msg": "failed to reconcile deployments at startup", "error": "failed to get deployments: failed to get deployments from DB: failed to query deployments: ERROR: column d.id does not exist (SQLSTATE 42703)" } { "time": "2026-03-05T22:40:15.784790303Z", "level": "WARN", "msg": "server will continue starting, but deployments may not be in sync" } ``` # Change Type ``` /kind cleanup ``` # Changelog ```release-note Use structured logs (JSON) for running services. ``` # Additional Notes --------- Signed-off-by: Fabian Gonzalez <[email protected]> Signed-off-by: Fabian Gonzalez <[email protected]>
Description
Setting up structured logging, namely json-based logging, to give us a standard on how to log (instead of our current mix of
log.andslog.) plus make querying debugging easier by having a queriable(?) standard for logs.We already have an AGENTS.md that bring up using
slog, so moving to using that throughout the services will also lessen any agentic confusion to avoid any "file says to useslog, but wait I seelogused".Resolves #101
Example
Below is the logs from docker + an example of better json querying instead of needing to do find searches / grepping.
{ "time": "2026-03-05T22:40:15.784770469Z", "level": "WARN", "msg": "failed to reconcile deployments at startup", "error": "failed to get deployments: failed to get deployments from DB: failed to query deployments: ERROR: column d.id does not exist (SQLSTATE 42703)" } { "time": "2026-03-05T22:40:15.784790303Z", "level": "WARN", "msg": "server will continue starting, but deployments may not be in sync" }Change Type
Changelog
Additional Notes