Repository: uber-go/zap
File: sugar.go (Go)

Code before:

// Panicln uses fmt.Sprintln to construct and log a message, then panics.
func (s *SugaredLogger) Panicln(args ...interface{}) {
	s.logln(PanicLevel, "", args, nil)
}

// Fatalln uses fmt.Sprintln to construct and log a message, then calls os.Exit.
func (s *SugaredLogger) Fatalln(args ...interface{}) {
	s.logln(FatalLevel, "", args, nil)
}

// Sync flushes any buffered log entries.
func (s *SugaredLogger) Sync() error {
	return s.base.Sync()
}

// log message with Sprint, Sprintf, or neither.
func (s *SugaredLogger) log(lvl zapcore.Level, template string, fmtArgs []interface{}, context []interface{}) {
	// If logging at this level is completely disabled, skip the overhead of
	// string formatting.
	if lvl < DPanicLevel && !s.base.Core().Enabled(lvl) {
		return
	}

	msg := getMessage(template, fmtArgs)
	s.base.Log(lvl, msg, s.sweetenFields(context)...)
}

// logln message with Sprintln
func (s *SugaredLogger) logln(lvl zapcore.Level, template string, fmtArgs []interface{}, context []interface{}) {
	if lvl < DPanicLevel && !s.base.Core().Enabled(lvl) {
		return
	}

	msg := getMessageln(fmtArgs)
	s.base.Log(lvl, msg, s.sweetenFields(context)...)
}

// getMessage format with Sprint, Sprintf, or neither.
func getMessage(template string, fmtArgs []interface{}) string {
	if len(fmtArgs) == 0 {
		return template
	}

	if template != "" {
		return fmt.Sprintf(template, fmtArgs...)
	}

	if len(fmtArgs) == 1 {
		if str, ok := fmtArgs[0].(string); ok {
			return str

Review comment (suggestion):
I would revert this and the other change in this file.

The Check version has the advantage that we don't spend CPU on `sweetenFields` unless we're actually going to log the message. So if the log level is too low or the message gets sampled, we won't pay to serialize the fields.

Code after:

// Panicln uses fmt.Sprintln to construct and log a message, then panics.
func (s *SugaredLogger) Panicln(args ...interface{}) {
	s.logln(PanicLevel, "", args, nil)
}

// Fatalln uses fmt.Sprintln to construct and log a message, then calls os.Exit.
func (s *SugaredLogger) Fatalln(args ...interface{}) {
	s.logln(FatalLevel, "", args, nil)
}

// Sync flushes any buffered log entries.
func (s *SugaredLogger) Sync() error {
	return s.base.Sync()
}

// log message with Sprint, Sprintf, or neither.
func (s *SugaredLogger) log(lvl zapcore.Level, template string, fmtArgs []interface{}, context []interface{}) {
	// If logging at this level is completely disabled, skip the overhead of
	// string formatting.
	if lvl < DPanicLevel && !s.base.Core().Enabled(lvl) {
		return
	}

	msg := getMessage(template, fmtArgs)
	if ce := s.base.Check(lvl, msg); ce != nil {
		ce.Write(s.sweetenFields(context)...)
	}
}

// logln message with Sprintln
func (s *SugaredLogger) logln(lvl zapcore.Level, template string, fmtArgs []interface{}, context []interface{}) {
	if lvl < DPanicLevel && !s.base.Core().Enabled(lvl) {
		return
	}

	msg := getMessageln(fmtArgs)
	if ce := s.base.Check(lvl, msg); ce != nil {
		ce.Write(s.sweetenFields(context)...)
	}
}

// getMessage format with Sprint, Sprintf, or neither.
func getMessage(template string, fmtArgs []interface{}) string {
	if len(fmtArgs) == 0 {
		return template
	}

	if template != "" {
		return fmt.Sprintf(template, fmtArgs...)
	}