Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: add slogr #195

Closed
wants to merge 2 commits into from
Closed

WIP: add slogr #195

wants to merge 2 commits into from

Conversation

thockin
Copy link
Contributor

@thockin thockin commented Aug 2, 2023

Not sure if this should be in logr or in a new repo, but I wanted to get feedback. No tests yet, and I am not sure how much testing this warrants.

xref #171

@thockin thockin force-pushed the slogr branch 4 times, most recently from c66ecab to 9ee2c75 Compare August 2, 2023 19:27
slogr/slogr.go Outdated Show resolved Hide resolved
thockin added 2 commits August 3, 2023 11:45
Not sure if this should be in logr or in a new repo, but I wanted to get
feedback.  No tests yet, and I am not sure how much testing this
warrants.
I am not sure this belongs in the same package as slogr.

There are a few aspects of slog that logr has no equivalent for:
 - time passed in to the handler
 - passing in a PC rather than a call-depth
 - WithGroup()

We need to think about whether to extend logr to accommodate or just
ignore these.
Copy link

@jba jba left a comment

Choose a reason for hiding this comment

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

Thanks for doing this!

if record.Level >= slog.LevelError {
h.logger.Error(nil, record.Message, args...)
} else {
h.logger.V(int(-record.Level)).Info(record.Message, args...)
Copy link

Choose a reason for hiding this comment

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

Consider dividing by 4, so:

Info -> V(0)
Debug -> V(1)
Warn -> V(-1)

I don't know if that's better.

Copy link
Contributor

Choose a reason for hiding this comment

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

A direct mapping is better because Kubernetes uses V(4) for debug messages, which corresponds nicely with slog.LevelDebug = -4.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree - I don't see why we need to modify it - am I missing some trap?

func (h logrHandler) WithGroup(name string) slog.Handler {
//FIXME: I don't know how to implement this in logr, but it's an
//interesting idea
return h
Copy link

Choose a reason for hiding this comment

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

For "flat" formats like the one implemented by slog.TextHandler, I recommend prefixing the key with GROUP. You can store a string in the handler that is the dot-separated concatenation of all the groups you see here, then slap that on to each attribute you encounter.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

@thockin thockin Aug 3, 2023

Choose a reason for hiding this comment

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

This is unfortunate. It seems like it would be nicer to aggregate and produse one struct, but then I have to accumulate Attrs in calls to WithAttrs, and then send those plus the per-logline Attrs at the same time, which probably defeats pre-formatiing optimizations in handlers.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that prefixing keys is sub-optimal. It's acceptable when the underlying logr.LogSink would do something like that itself (klog text format), but not when it writes JSON (zapr). I did not put further effort into this because I prefer to avoid glue code like this entirely by using backends which support both slog and logr and only falling back to glue code when such support is missing.

The alternative is a major update of logr which brings it to feature parity with slog - that doesn't seem worthwhile.

@pohly
Copy link
Contributor

pohly commented Aug 3, 2023

@thockin: do you intend to continue with this PR or should we focus on #196 instead?


// NewSlogHandler returns a slog.Handler which logs through an arbitrary
// logr.Logger.
func NewSlogHandler(logger logr.Logger) slog.Handler {
Copy link

Choose a reason for hiding this comment

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

You should test this with the testing/slogtest package to make sure you get all the subtle rules right.

Copy link

Choose a reason for hiding this comment

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

...but that may not work if you punt on features like groups.

FTR I'm thrilled that there will be some level of interoperability and I'm fine if it's not perfect. If giving up on groups means that a PR will actually land, then that works for me. In that case just use testing/slogtest informally to find the bugs that are worthwhile fixing. Maybe have a permanent t.Skip in the test.

Copy link
Contributor

Choose a reason for hiding this comment

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

See golang/go#61758 (comment) for a comment about allowing to skip some of the testing/slogtest checks.

@thockin
Copy link
Contributor Author

thockin commented Aug 3, 2023

@pohly I did this to see how I would do it, without looking at yours. We are about 80% identitcal, which is good. Let's focus on yours, where I sent a bunch of comments to discuss.

@thockin thockin closed this Aug 3, 2023
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.

3 participants