[go: nahoru, domu]

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

Support custom log levels/general logging. #680

Open
NathanZook opened this issue Feb 11, 2019 · 15 comments · Fixed by chiragtaunk13/zap#1
Open

Support custom log levels/general logging. #680

NathanZook opened this issue Feb 11, 2019 · 15 comments · Fixed by chiragtaunk13/zap#1

Comments

@NathanZook
Copy link

My company wants to implement a trace level log. Currently, this is problematic because zap.Logger.check is private.

Digging in, it would seem that a full implementation would extract https://github.com/uber-go/zap/blob/master/logger.go#L273-L282 into a method call. Of course, the natural target of the call is probably the levels themselves, which would be a problem. Making it a method on *zap.Logger would do, I think.

Ideally, we would probably want to change the zapcore.Level constants to variables, and implement a zap.Logger#Log method that takes a zapcore.Level as its second argument.

I know of one major user of Go that implements TRACE1, TRACE2, and TRACE3...

@iorlas
Copy link
iorlas commented Mar 20, 2019

+1 for custom levels. Maybe custom levels not argent right now, but at least adding Trace level would be soooo goood.

@lysu
Copy link
lysu commented Apr 8, 2019

+1 to add trace level

@kolkov
Copy link
kolkov commented May 12, 2020

Yes, it’s very good if there are more levels.

@mpfaff
Copy link
mpfaff commented May 25, 2020

Is anything ever going to be done about this? At a minimum, a trace log level is a must, but support for custom levels would be the ideal solution.

@prashantv
Copy link
Collaborator

It's not clear whether this can be done in a fully backwards compatible way (as existing cores and encoders may break). For example, the sampler panics when a negative level is passed in (#713). While the sampler can be fixed because it's part of the zap repository, there may be other implementations that would not support new levels.

We are open to PRs that implement custom levels in a backwards compatible way (ideally with an analysis of existing implementations of zap cores/encoders to ensure that it is not breaking). Unfortunately we can't accept any backwards incompatible changes to zap 1.0

@tv42
Copy link
tv42 commented Oct 9, 2020

Stackdriver has a few more levels on the severe end:

    // Alert means a person must take an action immediately.
    Alert = Severity(logtypepb.LogSeverity_ALERT)
    // Emergency means one or more systems are unusable.
    Emergency = Severity(logtypepb.LogSeverity_EMERGENCY)

https://godoc.org/cloud.google.com/go/logging#Severity

@alxn
Copy link
Member
alxn commented Oct 9, 2020

Stackdriver has a few more levels on the severe end:

    // Alert means a person must take an action immediately.
    Alert = Severity(logtypepb.LogSeverity_ALERT)
    // Emergency means one or more systems are unusable.
    Emergency = Severity(logtypepb.LogSeverity_EMERGENCY)

https://godoc.org/cloud.google.com/go/logging#Severity

these are just the syslog levels (https://tools.ietf.org/html/rfc3164#section-4.1.1 (Table 2.))

@tv42
Copy link
tv42 commented Oct 9, 2020

@alxn Good point (I didn't recognize them because of the presentation). However, it doesn't matter whether they're Stackdriver opinions or syslog opinions; they're log destination opinions that zap doesn't share, and they can't currently be added either.

Background: I'm writing an app using zap, sending log to stackdriver (similarly, syslog) via stdio, and just realized while writing the adapter that the models don't match exactly. At least it's a field I can't express in my program with zap, and not the other way around where I would have to lose information.

@prashantv
Copy link
Collaborator

Zap does have a few other levels (DPanic, Fatal, Panic). They do have different behaviours, but perhaps they can help.

samsondav added a commit to samsondav/zap that referenced this issue Apr 7, 2021
@tmeisel
Copy link
tmeisel commented Nov 12, 2022

Since this is still open, I'd like to chime in. My motivation to look into the possibility to use custom log levels with zap was to log (http, gRPC, ...) requests. E.g. zap.Log("request", "GET /users/<some-id>", zap.Int("status", httpStatus)). It would make it very easy to filter by these log lines (or exclude them), extract the error rate and of course you don't have to wonder if a 400 response is InfoLevel, ErrorLevel or ... .

It's basically like keeping request and error log in separate files (remember the times...?). I understand there are ways to work around that (e.g. log every request as info and use fields). But again, querying your logs would definitely be easier with this custom level. I also respect your previous comments about backward compatibility, yet it might be something for a v2?

@win5do
Copy link
win5do commented Jan 6, 2023

I extend the trace level like this and it works.

const TraceLevel = zapcore.DebugLevel - 1

func NewDevZapLogger(lvl zapcore.LevelEnabler) *zap.Logger {
	encCfg := zap.NewDevelopmentEncoderConfig()
	encCfg.EncodeLevel = capitalColorLevelEncoder
	zapCore := zapcore.NewCore(zapcore.NewConsoleEncoder(encCfg), zapcore.AddSync(os.Stderr), lvl)
	return zap.New(zapCore)
}

func capitalColorLevelEncoder(level zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
	if level == TraceLevel {
		enc.AppendString(color.CyanString("TRACE"))
		return
	}
	zapcore.CapitalColorLevelEncoder(level, enc)
}

func Use() {
	zap.ReplaceGlobals(NewDevZapLogger(zap.NewAtomicLevelAt(TraceLevel)))
}

@seaguest
Copy link
seaguest commented Apr 7, 2023

@win5do
How do you log a message with Trace level?
There is no Trace() method, and we can't specify level when log a message.

@win5do
Copy link
win5do commented Apr 9, 2023

@win5do How do you log a message with Trace level? There is no Trace() method, and we can't specify level when log a message.

zap.Logger provide Log API that you can pass log level,or make a wrapper func.

zap.L().Log(TraceLevel, "trace msg")

@seaguest
Copy link

@win5do
but it only support string, we need something like Tracef, Tracew, e.g #933
probably a fork of zap would be better.

@win5do
Copy link
win5do commented Apr 11, 2023

@win5do but it only support string, we need something like Tracef, Tracew, e.g #933 probably a fork of zap would be better.

It's easy to make a wrapper func:

func (s *logger) Tracef(format string, args ...interface{}) {
	s.zapLogger.Log(TraceLevel, fmt.Sprintf(format, args...))
}

Don't forget to handle caller skip.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.