pkg/logger/logger.go

103 lines
2.0 KiB
Go

// Package logger provider std slog logger
package logger
import (
"io"
"log/slog"
"os"
"path/filepath"
"strconv"
"gopkg.in/natefinch/lumberjack.v2"
"git.ifooth.com/common/pkg/config"
)
// Init 初始化 slog
func Init() {
textHandler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
AddSource: true,
Level: slog.LevelInfo,
ReplaceAttr: ReplaceSourceAttr,
})
logger := slog.New(textHandler)
slog.SetDefault(logger)
}
// GetLevelByName human readable logger level
func GetLevelByName(name string) slog.Level {
switch name {
case "error":
return slog.LevelError
case "warn":
return slog.LevelWarn
case "info":
return slog.LevelInfo
case "debug":
return slog.LevelDebug
default:
return slog.LevelInfo
}
}
// NewLogger make a new logger
func NewLogger(opts *config.LogConf) *slog.Logger {
handler := NewHandler(opts)
logger := slog.New(handler)
return logger
}
// NewHandler make a new handler
func NewHandler(opts *config.LogConf) slog.Handler {
ioWriter := io.Discard
if opts.Stdout {
ioWriter = os.Stdout
}
if opts.FileName != "" {
fileWriter := &lumberjack.Logger{
Filename: opts.FileName,
MaxSize: opts.MaxSize,
MaxBackups: opts.MaxNum,
LocalTime: true,
Compress: false,
}
if ioWriter == io.Discard {
ioWriter = fileWriter
} else {
ioWriter = io.MultiWriter(ioWriter, fileWriter)
}
}
level := GetLevelByName(opts.Level)
slogOpt := &slog.HandlerOptions{
AddSource: true,
Level: level,
ReplaceAttr: ReplaceSourceAttr,
}
if opts.Format == "json" {
return slog.NewJSONHandler(ioWriter, slogOpt)
}
return slog.NewTextHandler(ioWriter, slogOpt)
}
// ReplaceSourceAttr source 格式化为 dir/file:line 格式
func ReplaceSourceAttr(groups []string, a slog.Attr) slog.Attr {
if a.Key != slog.SourceKey {
return a
}
src, ok := a.Value.Any().(*slog.Source)
if !ok {
return a
}
a.Value = slog.StringValue(filepath.Base(src.File) + ":" + strconv.Itoa(src.Line))
return a
}