add file appender

This commit is contained in:
程广 2023-11-28 18:29:30 +08:00
parent 343bc3e4ea
commit 97ba3d3215
5 changed files with 202 additions and 29 deletions

3
.vscode/launch.json vendored
View File

@ -9,7 +9,8 @@
"type": "go", "type": "go",
"request": "launch", "request": "launch",
"mode": "auto", "mode": "auto",
"program": "${fileDirname}" "program": "${fileDirname}",
"cwd": "${workspaceFolder}",
} }
] ]
} }

View File

@ -6,14 +6,15 @@ import (
) )
const ( const (
ErrorTemplate = "\033[1;31;40m%s\033[0m\n" ErrorTemplate = "\033[1;31m%s\033[0m\n"
WarnTemplate = "\033[1;33;40m%s\033[0m\n" WarnTemplate = "\033[1;33m%s\033[0m\n"
InfoTemplate = "\033[1;32;40m%s\033[0m\n" InfoTemplate = "\033[1;32m%s\033[0m\n"
DebugTemplate = "\033[1;34;40m%s\033[0m\n" DebugTemplate = "\033[1;34m%s\033[0m\n"
TraceTemplate = "\033[1;35;40m%s\033[0m\n" TraceTemplate = "\033[1;35m%s\033[0m\n"
) )
type ConsoleAppender struct{} type ConsoleAppender struct {
}
func (c *ConsoleAppender) GetName() string { func (c *ConsoleAppender) GetName() string {
return "console" return "console"
@ -28,6 +29,8 @@ func (c *ConsoleAppender) Append(logEvent LogEvent) {
dmsg := fmt.Sprint(logEvent.Data) dmsg := fmt.Sprint(logEvent.Data)
dmsg = strings.TrimLeft(dmsg, "[") dmsg = strings.TrimLeft(dmsg, "[")
dmsg = strings.TrimRight(dmsg, "]") dmsg = strings.TrimRight(dmsg, "]")
data = append(data, "["+logEvent.Category+"] ")
data = append(data, dmsg) data = append(data, dmsg)
logMsg := fmt.Sprint(data...) logMsg := fmt.Sprint(data...)
switch logEvent.Level { switch logEvent.Level {
@ -43,3 +46,10 @@ func (c *ConsoleAppender) Append(logEvent LogEvent) {
fmt.Printf(TraceTemplate, logMsg) fmt.Printf(TraceTemplate, logMsg)
} }
} }
func makeConsoleAppender(appenderConfig LogAppenderConfig) LoggerAppender {
var appender LoggerAppender = &ConsoleAppender{}
return appender
}
func init() {
RegistAppender("console", makeConsoleAppender)
}

55
file.go Normal file
View File

@ -0,0 +1,55 @@
package gologger
import (
"fmt"
"os"
"path/filepath"
)
type FileAppender struct {
filePath string
file *os.File
}
func (f *FileAppender) GetName() string {
return "FileAppender:" + f.filePath
}
func (f *FileAppender) Append(logEvent LogEvent) {
if f.file == nil || int(f.file.Fd()) == -1 {
dirName := filepath.Dir(f.filePath)
_, err := os.Stat(dirName)
if err != nil && os.IsNotExist(err) {
os.MkdirAll(dirName, 0755)
}
f.file, _ = os.OpenFile(f.filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
}
data := []interface{}{
logEvent.Ts.Format("2006-01-02 15:04:05"),
" ",
}
data = append(data, "["+logEvent.Category+"] ")
dmsg := fmt.Sprint(logEvent.Data...)
data = append(data, dmsg)
logMsg := fmt.Sprint(data...)
f.file.WriteString(logMsg + "\n")
}
func makeFileAppender(appenderConfig LogAppenderConfig) LoggerAppender {
var logfile interface{}
var ok bool
logfile, ok = appenderConfig.Options["file"]
if !ok {
logfile = "default.log"
}
var ret LoggerAppender = &FileAppender{
filePath: logfile.(string),
}
return ret
}
func init() {
RegistAppender("file", makeFileAppender)
}

102
main.go
View File

@ -1,6 +1,7 @@
package gologger package gologger
import ( import (
"strings"
"time" "time"
) )
@ -13,22 +14,43 @@ const (
Trace Trace
) )
var logLevelMap map[string]int = map[string]int{
"off": NoLog,
"error": Error,
"warn": Warn,
"info": Info,
"debug": Debug,
"trace": Trace,
}
var loggerMap map[string]Logger = map[string]Logger{} var loggerMap map[string]Logger = map[string]Logger{}
var appenderFactoryMap map[string]func(LogAppenderConfig) LoggerAppender = map[string]func(LogAppenderConfig) LoggerAppender{}
var appenders map[string]LoggerAppender = map[string]LoggerAppender{}
var loggerConfig LoggersConfig
type LogAppenderConfig struct {
Type string `json:"type"`
Options map[string]interface{} `json:"options"`
}
type LogConfig struct { type LogConfig struct {
Name string Level string `json:"level"`
Level int Appenders []string `json:"appenders"`
Appender LoggerAppender }
type LoggersConfig struct {
Appenders map[string]LogAppenderConfig `json:"appenders"`
Categories map[string]LogConfig `json:"categories"`
} }
type Logger struct { type Logger struct {
LogConfig category string
level int
appenders []LoggerAppender
} }
type LogEvent struct { type LogEvent struct {
Category string
Ts time.Time Ts time.Time
Level int Level int
Data []interface{} Data []interface{}
ELogger *Logger
} }
type LoggerAppender interface { type LoggerAppender interface {
@ -37,17 +59,21 @@ type LoggerAppender interface {
} }
var consoleAppender LoggerAppender = &ConsoleAppender{} var consoleAppender LoggerAppender = &ConsoleAppender{}
var defaultLogger = &LogConfig{ var defaultLogger = &Logger{
Level: Error,
Appender: consoleAppender, level: Error,
appenders: []LoggerAppender{consoleAppender},
} }
func (l *Logger) log(Level int, msg []interface{}) { func (l *Logger) log(Level int, msg []interface{}) {
if Level <= l.Level { if Level <= l.level {
now := time.Now() now := time.Now()
logEvent := LogEvent{now, Level, msg, l} logEvent := LogEvent{l.category, now, Level, msg}
l.Appender.Append(logEvent) for _, appender := range l.appenders {
appender.Append(logEvent)
}
// l.Appender.Append(logEvent)
// fmt.Println(now.Format("2006-01-02 15:04:05"), " ", l.Name, ": ", msg) // fmt.Println(now.Format("2006-01-02 15:04:05"), " ", l.Name, ": ", msg)
} }
} }
@ -71,16 +97,54 @@ func (l *Logger) Debug(msg ...interface{}) {
func (l *Logger) Trace(msg ...interface{}) { func (l *Logger) Trace(msg ...interface{}) {
l.log(Trace, msg) l.log(Trace, msg)
} }
func GetLogger(logConfig LogConfig) Logger { func GetLogger(name string) Logger {
if logger, ok := loggerMap[logConfig.Name]; ok { if logger, ok := loggerMap[name]; ok {
return logger return logger
} else { } else {
logger := &Logger{logConfig} logConfig, ok := loggerConfig.Categories[name]
if logger.Appender == nil { if ok {
logger.Appender = defaultLogger.Appender return makeLogger(name, logConfig)
} }
loggerMap[logConfig.Name] = *logger if name == "default" {
return *logger return *defaultLogger
}
ret := GetLogger("default")
ret.category = name
return ret
} }
}
func makeLogger(name string, config LogConfig) Logger {
logger := &Logger{category: name}
levelstr := strings.ToLower(config.Level)
logger.level = logLevelMap[levelstr]
if config.Appenders == nil || len(config.Appenders) == 0 {
logger.appenders = []LoggerAppender{consoleAppender}
} else {
logger.appenders = make([]LoggerAppender, len(config.Appenders))
for i, appenderName := range config.Appenders {
logger.appenders[i] = appenders[appenderName]
}
}
loggerMap[name] = *logger
return *logger
}
func Configure(config LoggersConfig) {
loggerConfig = config
for name, appenderConfig := range loggerConfig.Appenders {
appenderFactory, ok := appenderFactoryMap[appenderConfig.Type]
if ok {
appenders[name] = appenderFactory(appenderConfig)
} else {
appenders[name] = &ConsoleAppender{}
}
}
for name, _ := range loggerConfig.Categories {
GetLogger(name)
}
}
func RegistAppender(typeName string, appenderCreatCb func(LogAppenderConfig) LoggerAppender) {
appenderFactoryMap[typeName] = appenderCreatCb
} }

43
test/main.go Normal file
View File

@ -0,0 +1,43 @@
package main
import (
logger "git.pyer.club/kingecg/gologger"
)
func main() {
logger.Configure(logger.LoggersConfig{
Categories: map[string]logger.LogConfig{
"default": {
Level: "debug",
Appenders: []string{
"console",
},
},
"fat": {
Level: "debug",
Appenders: []string{
"console",
"file",
},
},
},
Appenders: map[string]logger.LogAppenderConfig{
"console": {
Type: "console",
},
"file": {
Type: "file",
Options: map[string]interface{}{
"file": "./log/fat.log",
},
},
},
})
defaultLogger := logger.GetLogger("default")
defaultLogger.Debug("debug")
fatLogger := logger.GetLogger("fat")
fatLogger.Debug("debug")
defaultLogger.Debug("debug again")
fatLogger.Debug("debug again")
fatLogger.Error("This is error")
}