diff --git a/README.md b/README.md index 3f70138..1b533a3 100644 --- a/README.md +++ b/README.md @@ -158,9 +158,10 @@ For more details, see the examples. ## Configuration ### Logging -The default format is generic JSON. The log format can be configured by setting the `LOG_FORMAT` environment variable. The supported formats are: -- "stackdriver" -- "console" +The log format can be configured by providing an `Option` on initialization. The supported formats are: +- JSON (default) +- Stackdriver +- Console ## Contributions diff --git a/logger.go b/logger.go index 9414ad6..46a23df 100644 --- a/logger.go +++ b/logger.go @@ -2,51 +2,24 @@ package svc import ( "os" - "strings" "time" - "github.com/blendle/zapdriver" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) -func newLogger(name, version string, level zapcore.Level) (*zap.Logger, zap.AtomicLevel) { - logFormat := strings.ToLower(os.Getenv("LOG_FORMAT")) - +func newLogger(level zapcore.Level, encoder zapcore.Encoder) (*zap.Logger, zap.AtomicLevel) { atom := zap.NewAtomicLevel() atom.SetLevel(level) - // stackdriver - if logFormat == "stackdriver" { - logger := zap.New(zapcore.NewSampler(zapcore.NewCore( - zapcore.NewJSONEncoder(zapdriver.NewProductionEncoderConfig()), - zapcore.Lock(os.Stdout), - atom, - ), time.Second, 100, 10), - zap.ErrorOutput(zapcore.Lock(os.Stderr)), - zap.AddCaller(), - ) - logger = logger.With(zapdriver.ServiceContext(name), zapdriver.Label("version", version)) - return logger, atom - } - - // console text logger or fallback to default generic JSON - var enc zapcore.Encoder - if logFormat == "console" { - config := zap.NewProductionEncoderConfig() - config.EncodeTime = zapcore.RFC3339TimeEncoder - enc = zapcore.NewConsoleEncoder(config) - } else { - enc = zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()) - } logger := zap.New(zapcore.NewSampler(zapcore.NewCore( - enc, + encoder, zapcore.Lock(os.Stdout), atom, ), time.Second, 100, 10), zap.ErrorOutput(zapcore.Lock(os.Stderr)), zap.AddCaller(), - zap.Fields(zap.String("app", name), zap.String("version", version)), ) + return logger, atom } diff --git a/options.go b/options.go index 34fb38d..f8cad6f 100644 --- a/options.go +++ b/options.go @@ -7,6 +7,7 @@ import ( "net/http/pprof" "time" + "github.com/blendle/zapdriver" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "go.uber.org/zap" @@ -35,11 +36,9 @@ func WithRouter(router *http.ServeMux) Option { } } -// WithProductionLogger is an option that uses a zap Logger with configurations -// set meant to be used for production. -func WithProductionLogger() Option { +// WithLogger is an option that allows you to provide your own customized logger. +func WithLogger(logger *zap.Logger, atom zap.AtomicLevel) Option { return func(s *SVC) error { - logger, atom := newLogger(s.Name, s.Version, zapcore.InfoLevel) return assignLogger(s, logger, atom) } } @@ -48,7 +47,55 @@ func WithProductionLogger() Option { // configurations set meant to be used for development. func WithDevelopmentLogger() Option { return func(s *SVC) error { - logger, atom := newLogger(s.Name, s.Version, zapcore.DebugLevel) + logger, atom := newLogger( + zapcore.DebugLevel, + zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), + ) + logger.With(zap.String("app", s.Name), zap.String("version", s.Version)) + return assignLogger(s, logger, atom) + } +} + +// WithProductionLogger is an option that uses a zap Logger with configurations +// set meant to be used for production. +func WithProductionLogger() Option { + return func(s *SVC) error { + logger, atom := newLogger( + zapcore.InfoLevel, + zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), + ) + logger.With(zap.String("app", s.Name), zap.String("version", s.Version)) + return assignLogger(s, logger, atom) + } +} + +// WithConsoleLogger is an option that uses a zap Logger with configurations +// set meant to be used for debugging in the console. +func WithConsoleLogger(level zapcore.Level) Option { + return func(s *SVC) error { + + config := zap.NewProductionEncoderConfig() + config.EncodeTime = zapcore.RFC3339TimeEncoder + + logger, atom := newLogger( + level, + zapcore.NewConsoleEncoder(config), + ) + logger.With(zap.String("app", s.Name), zap.String("version", s.Version)) + return assignLogger(s, logger, atom) + } +} + +// WithStackdriverLogger is an option that uses a zap Logger with configurations +// set meant to be used for production and is compliant with the GCP/Stackdriver format. +func WithStackdriverLogger(level zapcore.Level) Option { + return func(s *SVC) error { + + logger, atom := newLogger( + level, + zapcore.NewJSONEncoder(zapdriver.NewProductionEncoderConfig()), + ) + logger.With(zapdriver.ServiceContext(s.Name), zapdriver.Label("version", s.Version)) return assignLogger(s, logger, atom) } }