From f0e58b66494a8ca77b66928636a6c26ef036c3e1 Mon Sep 17 00:00:00 2001 From: Kay Date: Tue, 9 Jul 2024 22:35:23 +0330 Subject: [PATCH] feat(logger): log level, targets and enable (#119) --- .github/PULL_REQUEST_TEMPLATE.md | 10 +-- config/config.go | 16 +++-- config/config.yaml | 4 ++ config/config_test.go | 2 - core/server/server.go | 21 +++---- utils/errors/errors.go | 6 +- utils/log/logger.go | 104 +++++++++++-------------------- 7 files changed, 64 insertions(+), 99 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index cba425d..28b80e4 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,15 +1,7 @@ ## Description -## Related Issue +## Related Issue(s) - Fixes #(issue number) - -## Types of changes -- [ ] Bug fix (non-breaking change that solves an issue) -- [ ] New feature (non-breaking change that adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) -- [ ] Documentation update (corrections, enhancements, or additions to documentation) -- [ ] Other (please describe): - diff --git a/config/config.go b/config/config.go index 9ff7a26..fd85db6 100644 --- a/config/config.go +++ b/config/config.go @@ -25,12 +25,14 @@ type Server struct { } type Log struct { - Path string `yaml:"path"` - Colorful bool `yaml:"colorful"` - Compress bool `yaml:"compress"` - MaxAge int `yaml:"max_age"` - MaxBackups int `yaml:"max_backups"` - MaxLogSize int `yaml:"max_log_size"` + Path string `yaml:"path"` + Targets []string `yaml:"targets"` + Level string `yaml:"level"` + Colorful bool `yaml:"colorful"` + Compress bool `yaml:"compress"` + MaxAge int `yaml:"max_age"` + MaxBackups int `yaml:"max_backups"` + MaxLogSize int `yaml:"max_log_size"` } type User struct { @@ -68,6 +70,8 @@ func DefaultConfig() *Config { Port: "7070", }, Log: Log{ + Targets: []string{"file", "console"}, + Level: "debug", Colorful: true, Compress: true, MaxAge: 1, diff --git a/config/config.yaml b/config/config.yaml index 69682c4..e90475c 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -6,6 +6,10 @@ server: log: path: log.ttrace + targets: + - file + - console + level: debug colorful: true compress: true max_age: 1 diff --git a/config/config_test.go b/config/config_test.go index e1d2bed..1ee5176 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -34,8 +34,6 @@ func TestDefaultConfig(t *testing.T) { defaultYaml = strings.ReplaceAll(defaultYaml, "\n\n", "\n") defaultFunctionStr = strings.ReplaceAll(defaultFunctionStr, "\n\n", "\n") - // fmt.Println(defaultFunction) - // fmt.Println(defaultYaml) assert.Equal(t, defaultFunctionStr, defaultYaml) } diff --git a/core/server/server.go b/core/server/server.go index c579701..d3aef7a 100644 --- a/core/server/server.go +++ b/core/server/server.go @@ -25,13 +25,11 @@ type Server struct { ActiveConnsMux sync.Mutex Config *config.Config - logger *ttlogger.SubLogger - db *database.Database + db *database.Database } func NewServer(cfg *config.Config, db *database.Database) *Server { lna := fmt.Sprintf("%v:%v", cfg.Server.IP, cfg.Server.Port) - sLogger := ttlogger.NewSubLogger("server") return &Server{ ListenAddress: lna, @@ -39,7 +37,6 @@ func NewServer(cfg *config.Config, db *database.Database) *Server { ActiveConnections: make(map[net.Conn]*config.User), db: db, Config: cfg, - logger: sLogger, } } @@ -51,14 +48,14 @@ func (s *Server) Start() error { s.Listener = listener - s.logger.Info("server started", "address", s.ListenAddress, "db-name", s.Config.Name) + ttlogger.Info("server started", "address", s.ListenAddress, "db-name", s.Config.Name) signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) go func() { sig := <-signalChan - s.logger.Info("Received signal, shutting down...", "signal", sig, "db-name", s.Config.Name) + ttlogger.Info("Received signal, shutting down...", "signal", sig, "db-name", s.Config.Name) close(s.QuitChan) s.Stop() @@ -84,20 +81,20 @@ func (s *Server) AcceptConnections() { conn, err := s.Listener.Accept() if err != nil { - s.logger.Error("error accepting connection", "error", err, "db-name", s.Config.Name) + ttlogger.Error("error accepting connection", "error", err, "db-name", s.Config.Name) continue } user, err := s.Authenticate(conn) if err != nil { - s.logger.Warn("invalid user try to connect", "db-name", s.Config.Name) + ttlogger.Warn("invalid user try to connect", "db-name", s.Config.Name) } else { s.ActiveConnsMux.Lock() s.ActiveConnections[conn] = user s.ActiveConnsMux.Unlock() - s.logger.Info("new connection", "remote address", conn.RemoteAddr().String(), "db-name", s.Config.Name) + ttlogger.Info("new connection", "remote address", conn.RemoteAddr().String(), "db-name", s.Config.Name) s.Wg.Add(1) go s.HandleConnection(conn) @@ -116,7 +113,7 @@ func (s *Server) HandleConnection(conn net.Conn) { n, err := conn.Read(buffer) if err != nil { - s.logger.Error("Connection closed", "remote address", conn.RemoteAddr().String(), "db-name", s.Config.Name) + ttlogger.Error("Connection closed", "remote address", conn.RemoteAddr().String(), "db-name", s.Config.Name) s.ActiveConnsMux.Lock() delete(s.ActiveConnections, conn) @@ -133,7 +130,7 @@ func (s *Server) HandleConnection(conn net.Conn) { _, err = conn.Write([]byte(result)) if err != nil { - s.logger.Error("Can't write on TCP connection", "error", err, "db-name", s.Config.Name) + ttlogger.Error("Can't write on TCP connection", "error", err, "db-name", s.Config.Name) } } else { _, _ = conn.Write([]byte(database.INVALID)) @@ -146,7 +143,7 @@ func (s *Server) Authenticate(conn net.Conn) (*config.User, error) { n, err := conn.Read(buffer) if err != nil { - s.logger.Error("error reading connection", "error", err, "db-name", s.Config.Name) + ttlogger.Error("error reading connection", "error", err, "db-name", s.Config.Name) _ = conn.Close() } diff --git a/utils/errors/errors.go b/utils/errors/errors.go index 39e955b..9d5b42c 100644 --- a/utils/errors/errors.go +++ b/utils/errors/errors.go @@ -3,15 +3,15 @@ package errors import "errors" var ( - // config. + // Config errors. ErrInavlidConfigPath = errors.New("invalid config path") ErrInvalidUsers = errors.New("invalid user(s)") ErrSpecificAndAllCommandSameAtTime = errors.New("can't have all cmds and specific cmd at same time") - // server. + // Server errors. ErrAuth = errors.New("authentication error") - // CLI. + // CLI errors. ErrInvalidUserOrPassword = errors.New("user or user information you provided is invalid") ErrInvalidCommand = errors.New("invalid command") ) diff --git a/utils/log/logger.go b/utils/log/logger.go index dfe0ab0..47e6d71 100644 --- a/utils/log/logger.go +++ b/utils/log/logger.go @@ -6,6 +6,8 @@ import ( "io" "os" "reflect" + "slices" + "strings" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -16,55 +18,39 @@ import ( var globalInst *logger type logger struct { - config *config.Log - subs map[string]*SubLogger writer io.Writer } -type SubLogger struct { - logger zerolog.Logger - name string -} - -func getLoggersInst() *logger { - if globalInst == nil { - conf := &config.Log{ - Colorful: true, - } - globalInst = &logger{ - config: conf, - subs: make(map[string]*SubLogger), - writer: zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: "15:04:05"}, - } - log.Logger = zerolog.New(globalInst.writer).With().Timestamp().Logger() - } - - return globalInst -} - func InitGlobalLogger(cfg *config.Log) { if globalInst == nil { writers := []io.Writer{} - if cfg.Colorful { - writers = append(writers, zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: "15:04:05"}) - } else { - writers = append(writers, os.Stderr) + + if slices.Contains(cfg.Targets, "file") { + // File writer. + fw := &lumberjack.Logger{ + Filename: cfg.Path, + MaxSize: cfg.MaxLogSize, + MaxBackups: cfg.MaxBackups, + Compress: cfg.Compress, + } + writers = append(writers, fw) } - fw := &lumberjack.Logger{ - Filename: cfg.Path, - MaxSize: cfg.MaxLogSize, - MaxBackups: cfg.MaxBackups, - Compress: cfg.Compress, - MaxAge: cfg.MaxAge, + if slices.Contains(cfg.Targets, "console") { + // Console writer. + writers = append(writers, zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: "15:04:05"}) } - writers = append(writers, fw) globalInst = &logger{ - config: cfg, - subs: make(map[string]*SubLogger), writer: io.MultiWriter(writers...), } + + level, err := zerolog.ParseLevel(strings.ToLower(cfg.Level)) + if err != nil { + level = zerolog.InfoLevel + } + + zerolog.SetGlobalLevel(level) log.Logger = zerolog.New(globalInst.writer).With().Timestamp().Logger() } } @@ -79,7 +65,7 @@ func addFields(event *zerolog.Event, keyvals ...interface{}) *zerolog.Event { if !ok { key = "!INVALID-KEY!" } - /// + value := keyvals[i+1] switch v := value.(type) { case fmt.Stringer: @@ -100,48 +86,32 @@ func addFields(event *zerolog.Event, keyvals ...interface{}) *zerolog.Event { return event } -func NewSubLogger(name string) *SubLogger { - inst := getLoggersInst() - sl := &SubLogger{ - logger: zerolog.New(inst.writer).With().Timestamp().Logger(), - name: name, - } - - inst.subs[name] = sl - - return sl -} - -func (sl *SubLogger) logObj(event *zerolog.Event, msg string, keyvals ...interface{}) { - addFields(event, keyvals...).Msg(msg) -} - -func (sl *SubLogger) Trace(msg string, keyvals ...interface{}) { - sl.logObj(sl.logger.Trace(), msg, keyvals...) +func Trace(msg string, keyvals ...interface{}) { + addFields(log.Trace(), keyvals...).Msg(msg) } -func (sl *SubLogger) Debug(msg string, keyvals ...interface{}) { - sl.logObj(sl.logger.Debug(), msg, keyvals...) +func Debug(msg string, keyvals ...interface{}) { + addFields(log.Debug(), keyvals...).Msg(msg) } -func (sl *SubLogger) Info(msg string, keyvals ...interface{}) { - sl.logObj(sl.logger.Info(), msg, keyvals...) +func Info(msg string, keyvals ...interface{}) { + addFields(log.Info(), keyvals...).Msg(msg) } -func (sl *SubLogger) Warn(msg string, keyvals ...interface{}) { - sl.logObj(sl.logger.Warn(), msg, keyvals...) +func Warn(msg string, keyvals ...interface{}) { + addFields(log.Warn(), keyvals...).Msg(msg) } -func (sl *SubLogger) Error(msg string, keyvals ...interface{}) { - sl.logObj(sl.logger.Error(), msg, keyvals...) +func Error(msg string, keyvals ...interface{}) { + addFields(log.Error(), keyvals...).Msg(msg) } -func (sl *SubLogger) Fatal(msg string, keyvals ...interface{}) { - sl.logObj(sl.logger.Fatal(), msg, keyvals...) +func Fatal(msg string, keyvals ...interface{}) { + addFields(log.Fatal(), keyvals...).Msg(msg) } -func (sl *SubLogger) Panic(msg string, keyvals ...interface{}) { - sl.logObj(sl.logger.Panic(), msg, keyvals...) +func Panic(msg string, keyvals ...interface{}) { + addFields(log.Panic(), keyvals...).Msg(msg) } func isNil(i interface{}) bool {