mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 02:16:28 +02:00
This also replaces instances where we manually write "return ctx.Err()" with "return context.Cause(ctx)" which is functionally identical, but will also correctly propagate cause errors if present.
171 lines
4.2 KiB
Go
171 lines
4.2 KiB
Go
// Package log provides a global logger for zerolog.
|
|
package log
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"os"
|
|
|
|
"github.com/rs/zerolog"
|
|
"github.com/rs/zerolog/log"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
|
|
"github.com/pomerium/pomerium/internal/atomicutil"
|
|
)
|
|
|
|
// Writer is where logs are written.
|
|
var Writer *MultiWriter
|
|
|
|
var (
|
|
zapLogger = atomicutil.NewValue(new(zap.Logger))
|
|
zapLevel zap.AtomicLevel
|
|
)
|
|
|
|
func init() {
|
|
Writer = &MultiWriter{}
|
|
Writer.Add(os.Stdout)
|
|
|
|
zapLevel = zap.NewAtomicLevel()
|
|
|
|
zapCfg := zap.NewProductionEncoderConfig()
|
|
zapCfg.TimeKey = "time"
|
|
zapCfg.EncodeTime = zapcore.RFC3339TimeEncoder
|
|
|
|
zapLogger.Store(zap.New(zapcore.NewCore(
|
|
zapcore.NewJSONEncoder(zapCfg),
|
|
zapcore.Lock(os.Stdout),
|
|
zapLevel,
|
|
)))
|
|
|
|
l := zerolog.New(Writer).With().Timestamp().Logger()
|
|
log.Logger = l
|
|
// set the default context logger
|
|
zerolog.DefaultContextLogger = &l
|
|
zapLevel.SetLevel(zapcore.InfoLevel)
|
|
}
|
|
|
|
// Logger returns the zerolog Logger.
|
|
func Logger() *zerolog.Logger {
|
|
return &log.Logger
|
|
}
|
|
|
|
// ZapLogger returns the global zap logger.
|
|
func ZapLogger() *zap.Logger {
|
|
if DebugDisableZapLogger.Load() {
|
|
return zap.NewNop()
|
|
}
|
|
return zapLogger.Load()
|
|
}
|
|
|
|
func GetLevel() zerolog.Level {
|
|
return zerolog.GlobalLevel()
|
|
}
|
|
|
|
// SetLevel sets the minimum global log level.
|
|
func SetLevel(level zerolog.Level) {
|
|
zerolog.SetGlobalLevel(level)
|
|
switch level {
|
|
case zerolog.DebugLevel, zerolog.TraceLevel:
|
|
zapLevel.SetLevel(zapcore.DebugLevel)
|
|
case zerolog.WarnLevel:
|
|
zapLevel.SetLevel(zapcore.WarnLevel)
|
|
case zerolog.ErrorLevel:
|
|
zapLevel.SetLevel(zapcore.ErrorLevel)
|
|
case zerolog.FatalLevel:
|
|
zapLevel.SetLevel(zapcore.FatalLevel)
|
|
case zerolog.PanicLevel:
|
|
zapLevel.SetLevel(zapcore.PanicLevel)
|
|
default:
|
|
zapLevel.SetLevel(zapcore.InfoLevel)
|
|
}
|
|
}
|
|
|
|
// With creates a child logger with the field added to its context.
|
|
func With() zerolog.Context {
|
|
return Logger().With()
|
|
}
|
|
|
|
// Debug starts a new message with debug level.
|
|
//
|
|
// You must call Msg on the returned event in order to send the event.
|
|
func Debug() *zerolog.Event {
|
|
return log.Debug()
|
|
}
|
|
|
|
// Info starts a new message with info level.
|
|
//
|
|
// You must call Msg on the returned event in order to send the event.
|
|
func Info() *zerolog.Event {
|
|
return log.Info()
|
|
}
|
|
|
|
// Error starts a new message with error level.
|
|
//
|
|
// You must call Msg on the returned event in order to send the event.
|
|
func Error() *zerolog.Event {
|
|
return log.Error()
|
|
}
|
|
|
|
// WithContext returns a context that has an associated logger and extra fields set via update
|
|
func WithContext(ctx context.Context, update func(c zerolog.Context) zerolog.Context) context.Context {
|
|
l := log.Ctx(ctx).With().Logger()
|
|
l.UpdateContext(update)
|
|
return l.WithContext(ctx)
|
|
}
|
|
|
|
// Fatal starts a new message with fatal level. The os.Exit(1) function
|
|
// is called by the Msg method.
|
|
//
|
|
// You must call Msg on the returned event in order to send the event.
|
|
func Fatal() *zerolog.Event {
|
|
return Logger().Fatal()
|
|
}
|
|
|
|
// Panic starts a new message with panic level. The message is also sent
|
|
// to the panic function.
|
|
//
|
|
// You must call Msg on the returned event in order to send the event.
|
|
func Panic() *zerolog.Event {
|
|
return Logger().Panic()
|
|
}
|
|
|
|
// Print sends a log event using debug level and no extra field.
|
|
// Arguments are handled in the manner of fmt.Print.
|
|
func Print(v ...any) {
|
|
Logger().Print(v...)
|
|
}
|
|
|
|
// Printf sends a log event using debug level and no extra field.
|
|
// Arguments are handled in the manner of fmt.Printf.
|
|
func Printf(format string, v ...any) {
|
|
Logger().Printf(format, v...)
|
|
}
|
|
|
|
// Ctx returns the Logger associated with the ctx. If no logger
|
|
// is associated, a disabled logger is returned.
|
|
func Ctx(ctx context.Context) *zerolog.Logger {
|
|
return zerolog.Ctx(ctx)
|
|
}
|
|
|
|
// FromRequest gets the logger in the request's context.
|
|
// This is a shortcut for log.Ctx(r.Context())
|
|
func FromRequest(r *http.Request) *zerolog.Logger {
|
|
return Ctx(r.Context())
|
|
}
|
|
|
|
// StdLogWrapper can be used to wrap logs originating from the from std
|
|
// library's ErrorFunction argument in http.Serve and httputil.ReverseProxy.
|
|
type StdLogWrapper struct {
|
|
*zerolog.Logger
|
|
}
|
|
|
|
func (l *StdLogWrapper) Write(p []byte) (n int, err error) {
|
|
n = len(p)
|
|
if n > 0 && p[n-1] == '\n' {
|
|
// Trim CR added by stdlog.
|
|
p = p[0 : n-1]
|
|
}
|
|
l.Error().Msg(string(p))
|
|
return len(p), nil
|
|
}
|