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

otelzap logger ignore WithOptions invocation #32

Closed
ezh opened this issue Jan 8, 2022 · 5 comments · Fixed by #33
Closed

otelzap logger ignore WithOptions invocation #32

ezh opened this issue Jan 8, 2022 · 5 comments · Fixed by #33
Labels
bug Something isn't working

Comments

@ezh
Copy link
Contributor

ezh commented Jan 8, 2022

Example

l := otelzap.Ctx(ctx).WithOptions(zap.Fields(zap.String("FOO", "BAR")))
l.Info("Hello")

I expect that there will be FOO:BAR field.

The field is added to the zap encoder, but only for *zap.Logger. skipCaller is ignored:
https://github.com/uptrace/opentelemetry-go-extra/blob/main/otelzap/otelzap.go#L31

type Logger struct {
	*zap.Logger
	skipCaller *zap.Logger

After that code is using skipCaller for log output (https://github.com/uptrace/opentelemetry-go-extra/blob/main/otelzap/otelzap.go#L262).

IMO someone forgot to add to func (l *Logger) WithOptions(opts ...zap.Option) *Logger

	clone.skipCaller = l.skipCaller.WithOptions(opts...)

https://github.com/uptrace/opentelemetry-go-extra/blob/main/otelzap/otelzap.go#L63

@vmihailenco
Copy link
Member

Yes, skipCaller must be updated - good catch.

But I guess WithOptions(zap.Fields(zap.String("FOO", "BAR")) won't fully work, because otelzap does not have any access to those fields and thus won't send it using OpenTelemetry protocol. You will only see those fields in your logs.

As a workaround, we could add an otelzap specific option so we have access to the fields:

l := otelzap.Ctx(ctx).WithFields(zap.String("FOO", "BAR"))

And then use WithOptions(zap.Fields(...)) to proxy those fields to Zap. What do you think?

@vmihailenco vmihailenco added the bug Something isn't working label Jan 9, 2022
@ezh
Copy link
Contributor Author

ezh commented Jan 9, 2022

Hey @vmihailenco . I don't think that introducing one more function to zap API would be a nice idea.

Why you wouldn't use otelzap WithOptions to collect extra fields? It is type-safe, has no reflection, and is transparent for the end-user. Please check https://github.com/ezh/opentelemetry-go-extra/commit/717c3dbeaca0b191e62cb6ff9352278f3cc6421c

func (l *Logger) WithOptions(opts ...zap.Option) *Logger {
	clone := *l
	extraFields := []zap.Field{}
	// zap.New side effect is extracting fields from .WithOptions(zap.Fields(...))
	zap.New(&fieldExtractorCore{extraFields: &extraFields}, opts...)
	print(fmt.Sprintf("%#v", extraFields))
	clone.Logger = l.Logger.WithOptions(opts...)

printf console output

DAP server listening at: 127.0.0.1:57568
[]zapcore.Field{zapcore.Field{Key:"foo", Type:0xf, Integer:0, String:"bar", Interface:interface {}(nil)}}
Detaching and terminating target process

If there will be other options, fieldExtractorCore will silently ignore them.

@vmihailenco
Copy link
Member

Sorcery 😮 Indeed, with that trick we don't need a separate API. Very nice.

Could you open a PR with https://github.com/ezh/opentelemetry-go-extra/commit/717c3dbeaca0b191e62cb6ff9352278f3cc6421c? I can cleanup it if needed.

@ezh
Copy link
Contributor Author

ezh commented Jan 11, 2022

Will do

@vmihailenco
Copy link
Member

@ezh gentle ping if you are still interested...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants