Skip to content

Add structured logging to services#273

Merged
inFocus7 merged 7 commits intoagentregistry-dev:mainfrom
inFocus7:infocus7/more-structured-logging
Mar 6, 2026
Merged

Add structured logging to services#273
inFocus7 merged 7 commits intoagentregistry-dev:mainfrom
inFocus7:infocus7/more-structured-logging

Conversation

@inFocus7
Copy link
Copy Markdown
Collaborator

@inFocus7 inFocus7 commented Mar 5, 2026

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. 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 #101

Example

Below is the logs from docker + an example of better json querying instead of needing to do find searches / grepping.

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"}
docker logs agentregistry-server | jq 'select(.level == "WARN")'
{
  "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

Use structured logs (JSON) for running services.

Additional Notes

@peterj
Copy link
Copy Markdown
Contributor

peterj commented Mar 5, 2026

@inFocus7 is this ready for review or still in progress?

@inFocus7
Copy link
Copy Markdown
Collaborator Author

inFocus7 commented Mar 6, 2026

It's ready but I was (originally) planning on waiting until morning to mark it

@inFocus7 inFocus7 marked this pull request as ready for review March 6, 2026 00:44
Copilot AI review requested due to automatic review settings March 6, 2026 00:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 slog handler in cmd/server/main.go as the process-wide default logger before any services are initialized
  • Migrates all log.Printf/log.Println/log.Fatalf calls across service, database, importer, seed, config, API, and validator packages to structured slog equivalents
  • Adds a logger *slog.Logger field (initialized via slog.Default().With("component", "<name>")) to registryServiceImpl, indexerImpl, and importer.Service structs 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.

@inFocus7 inFocus7 enabled auto-merge March 6, 2026 00:56
@inFocus7 inFocus7 added this pull request to the merge queue Mar 6, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 6, 2026
@peterj peterj added this pull request to the merge queue Mar 6, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 6, 2026
@peterj peterj added this pull request to the merge queue Mar 6, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 6, 2026
@inFocus7 inFocus7 enabled auto-merge March 6, 2026 18:24
@inFocus7 inFocus7 added this pull request to the merge queue Mar 6, 2026
Merged via the queue into agentregistry-dev:main with commit df8e317 Mar 6, 2026
6 checks passed
@inFocus7 inFocus7 deleted the infocus7/more-structured-logging branch March 6, 2026 18:38
christian-posta pushed a commit to christian-posta/agentregistry that referenced this pull request Mar 9, 2026
<!--
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]>
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.

Improve logging

3 participants