124 lines
2.4 KiB
Go
124 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"log/slog"
|
|
"os"
|
|
|
|
"github.com/urfave/cli/v2"
|
|
)
|
|
|
|
type logLevel string
|
|
|
|
const (
|
|
logLevelDebug logLevel = "debug"
|
|
logLevelInfo logLevel = "info"
|
|
logLevelWarn logLevel = "warn"
|
|
logLevelError logLevel = "error"
|
|
)
|
|
|
|
func (l logLevel) slogLevel() slog.Level {
|
|
switch l {
|
|
case logLevelDebug:
|
|
return slog.LevelDebug
|
|
case logLevelInfo:
|
|
return slog.LevelInfo
|
|
case logLevelWarn:
|
|
return slog.LevelWarn
|
|
case logLevelError:
|
|
return slog.LevelError
|
|
default:
|
|
panic("unknown log level: " + l)
|
|
}
|
|
}
|
|
|
|
func (l logLevel) String() string {
|
|
return string(l)
|
|
}
|
|
|
|
type logFormat string
|
|
|
|
const (
|
|
logFormatText logFormat = "text"
|
|
logFormatJSON logFormat = "json"
|
|
)
|
|
|
|
func (f logFormat) newHandler(w io.Writer, opts *slog.HandlerOptions) slog.Handler {
|
|
switch f {
|
|
case logFormatText:
|
|
return slog.NewTextHandler(w, opts)
|
|
case logFormatJSON:
|
|
return slog.NewJSONHandler(w, opts)
|
|
default:
|
|
panic("unknown log format: " + f)
|
|
}
|
|
}
|
|
|
|
func (f logFormat) String() string {
|
|
return string(f)
|
|
}
|
|
|
|
var (
|
|
logFlagLevel = &cli.GenericFlag{
|
|
Name: "log.level",
|
|
Value: &EnumValue{
|
|
Enum: []string{
|
|
logLevelDebug.String(),
|
|
logLevelInfo.String(),
|
|
logLevelWarn.String(),
|
|
logLevelError.String(),
|
|
},
|
|
Default: logLevelInfo.String(),
|
|
},
|
|
Usage: fmt.Sprintf("%s, %s, %s or %s", logLevelDebug, logLevelInfo, logLevelWarn, logLevelError),
|
|
EnvVars: []string{"LOG_LEVEL"},
|
|
}
|
|
logFlagFormat = &cli.GenericFlag{
|
|
Name: "log.format",
|
|
Value: &EnumValue{
|
|
Enum: []string{
|
|
logFormatJSON.String(),
|
|
logFormatText.String(),
|
|
},
|
|
Default: logFormatText.String(),
|
|
},
|
|
Usage: fmt.Sprintf("%s or %s", logFormatText, logFormatJSON),
|
|
EnvVars: []string{"LOG_FORMAT"},
|
|
}
|
|
logFlags = []cli.Flag{
|
|
logFlagLevel,
|
|
logFlagFormat,
|
|
}
|
|
)
|
|
|
|
func newLoggerFromFlags(c *cli.Context) *slog.Logger {
|
|
return newLogger(loggerConfig{
|
|
level: logLevel(c.String(logFlagLevel.Name)),
|
|
format: logFormat(c.String(logFlagFormat.Name)),
|
|
})
|
|
}
|
|
|
|
type loggerConfig struct {
|
|
level logLevel
|
|
format logFormat
|
|
}
|
|
|
|
func newLogger(cfg loggerConfig) *slog.Logger {
|
|
return slog.New(cfg.format.newHandler(os.Stderr, &slog.HandlerOptions{
|
|
Level: cfg.level.slogLevel(),
|
|
}))
|
|
}
|
|
|
|
type loggerCtxKey struct{}
|
|
|
|
func loggerToCtx(ctx context.Context, l *slog.Logger) context.Context {
|
|
return context.WithValue(ctx, loggerCtxKey{}, l)
|
|
}
|
|
|
|
func loggerFromCtx(ctx context.Context) *slog.Logger {
|
|
logger, _ := ctx.Value(loggerCtxKey{}).(*slog.Logger)
|
|
return logger
|
|
}
|