add config

This commit is contained in:
kingecg 2023-11-28 21:42:07 +08:00
parent 307317bb08
commit 10c818e063
9 changed files with 286 additions and 40 deletions

47
config/config.go Normal file
View File

@ -0,0 +1,47 @@
package config
import (
"encoding/json"
"os"
"git.pyer.club/kingecg/gologger"
)
type ServerConfig struct {
Host string `json:"host"`
Port int `json:"port"`
Logging gologger.LoggersConfig `json:"logging"`
}
var config ServerConfig = ServerConfig{
Host: "0.0.0.0",
Port: 8080,
Logging: gologger.LoggersConfig{
Appenders: map[string]gologger.LogAppenderConfig{
"out": gologger.LogAppenderConfig{
Type: "console",
},
},
Categories: map[string]gologger.LogConfig{
"default": {
Level: "debug",
Appenders: []string{"out"},
}},
},
}
func LoadConfig(configFile string) {
// read config gile content and parse it as json
configContent, err := os.ReadFile(configFile)
if err != nil {
panic(err)
}
err = json.Unmarshal(configContent, &config)
if err != nil {
panic(err)
}
}
func GetConfig() *ServerConfig {
return &config
}

74
config/config_test.go Normal file
View File

@ -0,0 +1,74 @@
package config
import (
"os"
"reflect"
"testing"
)
func setup() {
configFile := "./testconf.json"
config := `{
"host": "127.0.0.1",
"port": 8080,
"logging": {
"categories": {
"default": {
"level": "error",
"appenders": ["out"]
}
},
"appenders": {
"out": {
"type": "console"
}
}
}
}`
os.WriteFile(configFile, []byte(config), 0644)
}
func teardown() {
configFile := "./testconf.json"
os.Remove(configFile)
}
func TestLoadConfig(t *testing.T) {
setup()
type args struct {
configFile string
}
tests := []struct {
name string
args args
}{
{
name: "testload",
args: args{
configFile: "./testconf.json",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
LoadConfig(tt.args.configFile)
})
}
teardown()
}
func TestGetConfig(t *testing.T) {
tests := []struct {
name string
want *ServerConfig
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := GetConfig(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetConfig() = %v, want %v", got, tt.want)
}
})
}
}

7
go.mod
View File

@ -3,8 +3,11 @@ module git.pyer.club/kingecg/gosocketio
go 1.19 go 1.19
require ( require (
git.pyer.club/kingecg/gologger v0.0.0-20230311134033-343bc3e4eac0 // indirect git.pyer.club/kingecg/gologger v0.0.0-20231128103222-d94313028a67
github.com/spf13/cobra v1.8.0
)
require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
) )

4
go.sum
View File

@ -1,5 +1,5 @@
git.pyer.club/kingecg/gologger v0.0.0-20230311134033-343bc3e4eac0 h1:UfHJJj63oEq7BIvmyEIZ1PAI2XP8k31Z3sJeKG5qu10= git.pyer.club/kingecg/gologger v0.0.0-20231128103222-d94313028a67 h1:K/t9vBiexldPduAzBRzP4YVzCR89wLh0LZaCGv2RXy8=
git.pyer.club/kingecg/gologger v0.0.0-20230311134033-343bc3e4eac0/go.mod h1:SNSl2jRHPzIpHSzdKOoVG798rtYMjPDPFyxUrEgivkY= git.pyer.club/kingecg/gologger v0.0.0-20231128103222-d94313028a67/go.mod h1:SNSl2jRHPzIpHSzdKOoVG798rtYMjPDPFyxUrEgivkY=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=

View File

@ -2,14 +2,8 @@ package main
import ( import (
"git.pyer.club/kingecg/gosocketio/cli" "git.pyer.club/kingecg/gosocketio/cli"
"git.pyer.club/kingecg/gologger"
) )
func main() { func main() {
logger := gologger.GetLogger(gologger.LogConfig{
Level: gologger.Debug,
Name: "main"})
logger.Debug("hello world")
cli.Execute() cli.Execute()
} }

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"
@ -22,12 +23,13 @@ func (c *ConsoleAppender) GetName() string {
func (c *ConsoleAppender) Append(logEvent LogEvent) { func (c *ConsoleAppender) Append(logEvent LogEvent) {
data := []interface{}{ data := []interface{}{
logEvent.Ts.Format("2006-01-02 15:04:05"), logEvent.Ts.Format("2006-01-02 15:04:05"),
"[" + logEvent.ELogger.Name + "]",
" ", " ",
} }
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 +45,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)
}

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

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)
}
if name == "default" {
return *defaultLogger
}
ret := GetLogger("default")
ret.category = name
return ret
} }
loggerMap[logConfig.Name] = *logger
return *logger
} }
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
} }

2
vendor/modules.txt vendored
View File

@ -1,4 +1,4 @@
# git.pyer.club/kingecg/gologger v0.0.0-20230311134033-343bc3e4eac0 # git.pyer.club/kingecg/gologger v0.0.0-20231128103222-d94313028a67
## explicit; go 1.19 ## explicit; go 1.19
git.pyer.club/kingecg/gologger git.pyer.club/kingecg/gologger
# github.com/inconshreveable/mousetrap v1.1.0 # github.com/inconshreveable/mousetrap v1.1.0