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

Code before:
//     "hello", "world",
//     "failure", errors.New("oh no"),
//     "count", 42,
//     "user", User{name: "alice"},
//  )
// is the equivalent of
//   coreLogger.With(
//     String("hello", "world"),
//     String("failure", "oh no"),
//     Int("count", 42),
//     Object("user", User{name: "alice"}),
//   )
//
// Note that the keys should be strings. In development, passing a non-string
// key panics. In production, the logger is more forgiving: a separate error is
// logged, but the key is coerced to a string with fmt.Sprint and execution
// continues. Passing an odd number of arguments triggers similar behavior:
// panics in development and errors in production.
func (s *SugaredLogger) With(args ...interface{}) *SugaredLogger {
	return &SugaredLogger{core: s.core.With(s.sweetenFields(args)...)}
}

// Debug uses fmt.Sprint to construct and log a message.
func (s *SugaredLogger) Debug(args ...interface{}) {
	s.log(DebugLevel, fmt.Sprint(args...), nil)
}

// Info uses fmt.Sprint to construct and log a message.
func (s *SugaredLogger) Info(args ...interface{}) {
	s.log(InfoLevel, fmt.Sprint(args...), nil)
}

// Warn uses fmt.Sprint to construct and log a message.
func (s *SugaredLogger) Warn(args ...interface{}) {
	s.log(WarnLevel, fmt.Sprint(args...), nil)
}

// Error uses fmt.Sprint to construct and log a message.
func (s *SugaredLogger) Error(args ...interface{}) {
	s.log(ErrorLevel, fmt.Sprint(args...), nil)
}

// DPanic uses fmt.Sprint to construct and log a message. In development, the
// logger then panics. (See DPanicLevel for details.)
func (s *SugaredLogger) DPanic(args ...interface{}) {
	s.log(DPanicLevel, fmt.Sprint(args...), nil)
}

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

Review comment (bug):
Did you mean to just slip this one into this PR? It seems like a whole different thing; also it's attached to a larger ball of wax:
- if we're going to cede that it's useful toe have a `FooFields` for `Foo=With`...
- ...why not also for `Foo` in `{Debug,Info,Warn,Error,DPanic,Panic,Fatal}`?
- At that point, why don't we just collapse `SugaredLogger` into `Logger`, and dispense with all the wrapping?
- The user story would then become something like: "most people use Foof / Foow, perf-conscious users use FooFields"; maybe even something like:
  - "Don't care about logging? Use Foow"
  - "Want structured logs? Use Foof"
  - "Really care about logs? Library author? Use FooFields"

Code after:
//     "hello", "world",
//     "failure", errors.New("oh no"),
//     "count", 42,
//     "user", User{name: "alice"},
//  )
// is the equivalent of
//   coreLogger.With(
//     String("hello", "world"),
//     String("failure", "oh no"),
//     Int("count", 42),
//     Object("user", User{name: "alice"}),
//   )
//
// Note that the keys should be strings. In development, passing a non-string
// key panics. In production, the logger is more forgiving: a separate error is
// logged, but the key is coerced to a string with fmt.Sprint and execution
// continues. Passing an odd number of arguments triggers similar behavior:
// panics in development and errors in production.
func (s *SugaredLogger) With(args ...interface{}) *SugaredLogger {
	return s.WithFields(s.sweetenFields(args)...)
}

// WithFields adds structured fields to the logging context, much like the
// base Logger. It allows the sugared logger to use more specialized
// fields (like Stack).
func (s *SugaredLogger) WithFields(fs ...zapcore.Field) *SugaredLogger {
	return &SugaredLogger{core: s.core.With(fs...)}
}

// Debug uses fmt.Sprint to construct and log a message.
func (s *SugaredLogger) Debug(args ...interface{}) {
	s.log(DebugLevel, fmt.Sprint(args...), nil)
}

// Info uses fmt.Sprint to construct and log a message.
func (s *SugaredLogger) Info(args ...interface{}) {
	s.log(InfoLevel, fmt.Sprint(args...), nil)
}

// Warn uses fmt.Sprint to construct and log a message.
func (s *SugaredLogger) Warn(args ...interface{}) {
	s.log(WarnLevel, fmt.Sprint(args...), nil)
}

// Error uses fmt.Sprint to construct and log a message.
func (s *SugaredLogger) Error(args ...interface{}) {
	s.log(ErrorLevel, fmt.Sprint(args...), nil)
}

// DPanic uses fmt.Sprint to construct and log a message. In development, the
// logger then panics. (See DPanicLevel for details.)