You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
2.7 KiB
Go

package logger
import (
"fmt"
"log"
"os"
"sync"
)
// Level 日志级别
type Level int
const (
LevelDebug Level = iota
LevelInfo
LevelWarn
LevelError
LevelFatal
)
// Logger 日志接口
type Logger interface {
Debug(format string, args ...interface{})
Info(format string, args ...interface{})
Warn(format string, args ...interface{})
Error(format string, args ...interface{})
Fatal(format string, args ...interface{})
SetLevel(level Level)
}
// stdLogger 标准库日志实现
type stdLogger struct {
logger *log.Logger
level Level
mu sync.RWMutex
}
// New 创建标准库日志实例
func New(config *Config) Logger {
var output *os.File
switch config.Output {
case "stdout":
output = os.Stdout
case "stderr":
output = os.Stderr
default:
var err error
output, err = os.OpenFile(config.Output, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
output = os.Stdout
}
}
level := parseLevel(config.Level)
return &stdLogger{
logger: log.New(output, "", log.LstdFlags|log.Lshortfile),
level: level,
}
}
// parseLevel 解析日志级别
func parseLevel(level string) Level {
switch level {
case "debug":
return LevelDebug
case "info":
return LevelInfo
case "warn":
return LevelWarn
case "error":
return LevelError
case "fatal":
return LevelFatal
default:
return LevelInfo
}
}
// SetLevel 设置日志级别
func (l *stdLogger) SetLevel(level Level) {
l.mu.Lock()
defer l.mu.Unlock()
l.level = level
}
// Debug 输出调试日志
func (l *stdLogger) Debug(format string, args ...interface{}) {
if l.shouldLog(LevelDebug) {
l.log("DEBUG", format, args...)
}
}
// Info 输出信息日志
func (l *stdLogger) Info(format string, args ...interface{}) {
if l.shouldLog(LevelInfo) {
l.log("INFO", format, args...)
}
}
// Warn 输出警告日志
func (l *stdLogger) Warn(format string, args ...interface{}) {
if l.shouldLog(LevelWarn) {
l.log("WARN", format, args...)
}
}
// Error 输出错误日志
func (l *stdLogger) Error(format string, args ...interface{}) {
if l.shouldLog(LevelError) {
l.log("ERROR", format, args...)
}
}
// Fatal 输出致命错误日志并退出
func (l *stdLogger) Fatal(format string, args ...interface{}) {
if l.shouldLog(LevelFatal) {
l.log("FATAL", format, args...)
os.Exit(1)
}
}
// shouldLog 判断是否应该记录日志
func (l *stdLogger) shouldLog(level Level) bool {
l.mu.RLock()
defer l.mu.RUnlock()
return level >= l.level
}
// log 记录日志
func (l *stdLogger) log(level string, format string, args ...interface{}) {
message := fmt.Sprintf(format, args...)
l.logger.Printf("[%s] %s", level, message)
}
// Config 日志配置
type Config struct {
Level string
Format string
Output string
}