Skip to content

feat(log): Support scoped loggers#69

Open
robertgzr wants to merge 1 commit intoprod-stagingfrom
rgz/logscope
Open

feat(log): Support scoped loggers#69
robertgzr wants to merge 1 commit intoprod-stagingfrom
rgz/logscope

Conversation

@robertgzr
Copy link
Contributor

This patch adds a utility function to optionally embed a scope (and a
scope filter) in the logger. We use a zerolog.Hook to dynamically add
a scope field to log events (and filter by scopes).

A common application for this would be running multiple independent
systems in a single application, with the ability to debug with verbose
log output, while discarding logs of certain systems:

runSubsytemA(log.WithScopedLogger(ctx, "sys.a"))
runSubsytemB(log.WithScopedLogger(ctx, "sys.b"))

Future patches could extend this to also include functionality to set
log level per scoped logger.

Signed-off-by: Robert Günzler robert@unikraft.cloud

This patch adds a utility function to optionally embed a scope (and a
scope filter) in the logger. We use a `zerolog.Hook` to dynamically add
a scope field to log events (and filter by scopes).

A common application for this would be running multiple independent
systems in a single application, with the ability to debug with verbose
log output, while discarding logs of certain systems:

  runSubsytemA(log.WithScopedLogger(ctx, "sys.a"))
  runSubsytemB(log.WithScopedLogger(ctx, "sys.b"))

Future patches could extend this to also include functionality to set
log level per scoped logger.

Signed-off-by: Robert Günzler <robert@unikraft.cloud>
@robertgzr
Copy link
Contributor Author

This is an improved version of https://github.com/unikraft-cloud/agent/commit/72675188ed50d86a21c717060677c14a4a254b5c ported into x :)

With().
Timestamp().
Logger().
Hook(zerolog.HookFunc(scopeHook))
Copy link
Contributor Author

@robertgzr robertgzr Dec 15, 2025

Choose a reason for hiding this comment

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

this incurs a check for the scope context key on each logger, regardless of whether it uses scope or not. another design would be to inject the hook upon calling Scoped. that might be an unnecessary optimization though hehe

@robertgzr robertgzr marked this pull request as ready for review December 15, 2025 18:02
@jedevc
Copy link
Collaborator

jedevc commented Jan 22, 2026

Question - why not just use a field here? So use .With().Str("unikraft.scope", ...). Essentially as in https://github.com/unikraft-cloud/agent/commit/72675188ed50d86a21c717060677c14a4a254b5c.

This way, it just becomes part of the JSON we emit, and can filter on it from there. If we want to add filtering at our own CLI level, we just add a hook, and then set Level = zerolog.Discard, which discards the error.

There's also no extra cost to this.

@robertgzr
Copy link
Contributor Author

robertgzr commented Jan 22, 2026

@jedevc i wanted to support nested loggers overwriting the scope field they get passed by the parent. in the agent i just drop all the fields using Reset()...

func main()
    ...
    runServer(log.WithScopedLogger(ctx, "server"))
    ...
}

func runServer(ctx context.Context) {
    ...
    handleRequest(log.WithScopedLogger(ctx, "server.request"))
    ...
}

i'm not sure i follow your second part... you mean to use hooks to filter out these duplicated instances of the scope field?

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.

2 participants