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
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
|
|
}
|