From 237f172ae5b4bdb5eff8aff98103de27e266dafe Mon Sep 17 00:00:00 2001 From: John Guo Date: Sat, 26 Jun 2021 11:18:44 +0800 Subject: [PATCH] add file configuration support for logger in ghttp.Server --- frame/gins/gins_server.go | 25 ++++++++++---- net/ghttp/ghttp.go | 12 +++---- net/ghttp/ghttp_server.go | 2 +- net/ghttp/ghttp_server_config.go | 7 ++-- net/ghttp/ghttp_server_config_logging.go | 13 ++++++++ net/ghttp/ghttp_server_handler.go | 19 ++++++++--- net/ghttp/ghttp_server_log.go | 10 ++---- os/glog/glog_logger.go | 6 ++-- os/glog/glog_logger_rotate.go | 42 ++++++++++++++++-------- 9 files changed, 90 insertions(+), 46 deletions(-) diff --git a/frame/gins/gins_server.go b/frame/gins/gins_server.go index 090835628..e73eadaa8 100644 --- a/frame/gins/gins_server.go +++ b/frame/gins/gins_server.go @@ -24,17 +24,30 @@ func Server(name ...interface{}) *ghttp.Server { s := ghttp.GetServer(name...) // To avoid file no found error while it's not necessary. if Config().Available() { - var m map[string]interface{} + var ( + serverConfigMap map[string]interface{} + serverLoggerConfigMap map[string]interface{} + ) nodeKey, _ := gutil.MapPossibleItemByKey(Config().GetMap("."), configNodeNameServer) if nodeKey == "" { nodeKey = configNodeNameServer } - m = Config().GetMap(fmt.Sprintf(`%s.%s`, nodeKey, s.GetName())) - if len(m) == 0 { - m = Config().GetMap(nodeKey) + // Server configuration. + serverConfigMap = Config().GetMap(fmt.Sprintf(`%s.%s`, nodeKey, s.GetName())) + if len(serverConfigMap) == 0 { + serverConfigMap = Config().GetMap(nodeKey) } - if len(m) > 0 { - if err := s.SetConfigWithMap(m); err != nil { + if len(serverConfigMap) > 0 { + if err := s.SetConfigWithMap(serverConfigMap); err != nil { + panic(err) + } + } + // Server logger configuration. + serverLoggerConfigMap = Config().GetMap( + fmt.Sprintf(`%s.%s.%s`, nodeKey, s.GetName(), configNodeNameLogger), + ) + if len(serverLoggerConfigMap) > 0 { + if err := s.Logger().SetConfigWithMap(serverLoggerConfigMap); err != nil { panic(err) } } diff --git a/net/ghttp/ghttp.go b/net/ghttp/ghttp.go index ec486b0ef..54e2a4bbd 100644 --- a/net/ghttp/ghttp.go +++ b/net/ghttp/ghttp.go @@ -19,11 +19,11 @@ import ( ) type ( - // Server wraps the http.Server and provides more feature. + // Server wraps the http.Server and provides more rich features. Server struct { name string // Unique name for instance management. config ServerConfig // Configuration. - plugins []Plugin // Plugin array. + plugins []Plugin // Plugin array to extends server functionality. servers []*gracefulServer // Underlying http.Server array. serverCount *gtype.Int // Underlying http.Server count. closeChan chan struct{} // Used for underlying server closing event notification. @@ -44,7 +44,7 @@ type ( Priority int // Just for reference. } - // Router item just for route dumps. + // RouterItem is just for route dumps. RouterItem struct { Server string // Server name. Address string // Listening address. @@ -98,7 +98,7 @@ type ( Stack() string } - // Request handler function. + // HandlerFunc is request handler function. HandlerFunc = func(r *Request) // Listening file descriptor mapping. @@ -107,10 +107,6 @@ type ( ) const ( - HOOK_BEFORE_SERVE = "HOOK_BEFORE_SERVE" // Deprecated, use HookBeforeServe instead. - HOOK_AFTER_SERVE = "HOOK_AFTER_SERVE" // Deprecated, use HookAfterServe instead. - HOOK_BEFORE_OUTPUT = "HOOK_BEFORE_OUTPUT" // Deprecated, use HookBeforeOutput instead. - HOOK_AFTER_OUTPUT = "HOOK_AFTER_OUTPUT" // Deprecated, use HookAfterOutput instead. HookBeforeServe = "HOOK_BEFORE_SERVE" HookAfterServe = "HOOK_AFTER_SERVE" HookBeforeOutput = "HOOK_BEFORE_OUTPUT" diff --git a/net/ghttp/ghttp_server.go b/net/ghttp/ghttp_server.go index 5896ace8c..2aa6b18cc 100644 --- a/net/ghttp/ghttp_server.go +++ b/net/ghttp/ghttp_server.go @@ -195,7 +195,7 @@ func (s *Server) Start() error { if gproc.IsChild() { gtimer.SetTimeout(time.Duration(s.config.GracefulTimeout)*time.Second, func() { if err := gproc.Send(gproc.PPid(), []byte("exit"), adminGProcCommGroup); err != nil { - //glog.Error("server error in process communication:", err) + intlog.Error("server error in process communication:", err) } }) } diff --git a/net/ghttp/ghttp_server_config.go b/net/ghttp/ghttp_server_config.go index e7b19c926..0d4888e45 100644 --- a/net/ghttp/ghttp_server_config.go +++ b/net/ghttp/ghttp_server_config.go @@ -223,13 +223,14 @@ type ServerConfig struct { GracefulTimeout uint8 `json:"gracefulTimeout"` } +// Config creates and returns a ServerConfig object with default configurations. // Deprecated. Use NewConfig instead. func Config() ServerConfig { return NewConfig() } // NewConfig creates and returns a ServerConfig object with default configurations. -// Note that, do not define this default configuration to local package variable, as there're +// Note that, do not define this default configuration to local package variable, as there are // some pointer attributes that may be shared in different servers. func NewConfig() ServerConfig { return ServerConfig{ @@ -331,7 +332,9 @@ func (s *Server) SetConfig(c ServerConfig) error { return err } } - s.config.Logger.SetLevelStr(s.config.LogLevel) + if err := s.config.Logger.SetLevelStr(s.config.LogLevel); err != nil { + intlog.Error(err) + } SetGraceful(c.Graceful) intlog.Printf("SetConfig: %+v", s.config) diff --git a/net/ghttp/ghttp_server_config_logging.go b/net/ghttp/ghttp_server_config_logging.go index 3ea28f0de..471ea876c 100644 --- a/net/ghttp/ghttp_server_config_logging.go +++ b/net/ghttp/ghttp_server_config_logging.go @@ -6,6 +6,8 @@ package ghttp +import "github.com/gogf/gf/os/glog" + // SetLogPath sets the log path for server. // It logs content to file only if the log path is set. func (s *Server) SetLogPath(path string) error { @@ -23,6 +25,17 @@ func (s *Server) SetLogPath(path string) error { return nil } +// SetLogger sets the logger for logging responsibility. +// Note that it cannot be set in runtime as there may be concurrent safety issue. +func (s *Server) SetLogger(logger *glog.Logger) { + s.config.Logger = logger +} + +// Logger is alias of GetLogger. +func (s *Server) Logger() *glog.Logger { + return s.config.Logger +} + // SetLogLevel sets logging level by level string. func (s *Server) SetLogLevel(level string) { s.config.LogLevel = level diff --git a/net/ghttp/ghttp_server_handler.go b/net/ghttp/ghttp_server_handler.go index bc2bb05d9..cf9fcfb0a 100644 --- a/net/ghttp/ghttp_server_handler.go +++ b/net/ghttp/ghttp_server_handler.go @@ -7,6 +7,7 @@ package ghttp import ( + "github.com/gogf/gf/internal/intlog" "net/http" "os" "sort" @@ -80,9 +81,15 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Close the request and response body // to release the file descriptor in time. - _ = request.Request.Body.Close() + err := request.Request.Body.Close() + if err != nil { + intlog.Error(err) + } if request.Request.Response != nil { - _ = request.Request.Response.Body.Close() + err = request.Request.Response.Body.Close() + if err != nil { + intlog.Error(err) + } } }() @@ -188,9 +195,11 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { // searchStaticFile searches the file with given URI. // It returns a file struct specifying the file information. func (s *Server) searchStaticFile(uri string) *staticFile { - var file *gres.File - var path string - var dir bool + var ( + file *gres.File + path string + dir bool + ) // Firstly search the StaticPaths mapping. if len(s.config.StaticPaths) > 0 { for _, item := range s.config.StaticPaths { diff --git a/net/ghttp/ghttp_server_log.go b/net/ghttp/ghttp_server_log.go index c8f0f5f8f..24ce77bcc 100644 --- a/net/ghttp/ghttp_server_log.go +++ b/net/ghttp/ghttp_server_log.go @@ -9,14 +9,8 @@ package ghttp import ( "fmt" "github.com/gogf/gf/errors/gerror" - "github.com/gogf/gf/os/glog" ) -// Logger returns the logger of the server. -func (s *Server) Logger() *glog.Logger { - return s.config.Logger -} - // handleAccessLog handles the access logging for server. func (s *Server) handleAccessLog(r *Request) { if !s.IsAccessLogEnabled() { @@ -26,7 +20,7 @@ func (s *Server) handleAccessLog(r *Request) { if r.TLS != nil { scheme = "https" } - s.Logger().File(s.config.AccessLogPattern). + s.Logger().Ctx(r.Context()).File(s.config.AccessLogPattern). Stdout(s.config.LogStdout). Printf( `%d "%s %s %s %s %s" %.3f, %s, "%s", "%s"`, @@ -63,7 +57,7 @@ func (s *Server) handleErrorLog(err error, r *Request) { } else { content += ", " + err.Error() } - s.config.Logger. + s.Logger().Ctx(r.Context()). File(s.config.ErrorLogPattern). Stdout(s.config.LogStdout). Print(content) diff --git a/os/glog/glog_logger.go b/os/glog/glog_logger.go index 44a704c6e..397a779bc 100644 --- a/os/glog/glog_logger.go +++ b/os/glog/glog_logger.go @@ -102,9 +102,9 @@ func (l *Logger) print(ctx context.Context, level int, values ...interface{}) { if p.parent != nil { p = p.parent } - if !p.init.Val() && p.init.Cas(false, true) { - // It just initializes once for each logger. - if p.config.RotateSize > 0 || p.config.RotateExpire > 0 { + // It just initializes once for each logger. + if p.config.RotateSize > 0 || p.config.RotateExpire > 0 { + if !p.init.Val() && p.init.Cas(false, true) { gtimer.AddOnce(p.config.RotateCheckInterval, p.rotateChecksTimely) intlog.Printf("logger rotation initialized: every %s", p.config.RotateCheckInterval.String()) } diff --git a/os/glog/glog_logger_rotate.go b/os/glog/glog_logger_rotate.go index e508b8006..8471e55f2 100644 --- a/os/glog/glog_logger_rotate.go +++ b/os/glog/glog_logger_rotate.go @@ -19,6 +19,10 @@ import ( "time" ) +const ( + memoryLockPrefixForRotating = "glog.rotateChecksTimely:" +) + // rotateFileBySize rotates the current logging file according to the // configured rotation size. func (l *Logger) rotateFileBySize(now time.Time) { @@ -91,6 +95,7 @@ func (l *Logger) doRotateFile(filePath string) error { // rotateChecksTimely timely checks the backups expiration and the compression. func (l *Logger) rotateChecksTimely() { defer gtimer.AddOnce(l.config.RotateCheckInterval, l.rotateChecksTimely) + // Checks whether file rotation not enabled. if l.config.RotateSize <= 0 && l.config.RotateExpire == 0 { intlog.Printf( @@ -101,17 +106,20 @@ func (l *Logger) rotateChecksTimely() { } // It here uses memory lock to guarantee the concurrent safety. - memoryLockKey := "glog.rotateChecksTimely:" + l.config.Path + memoryLockKey := memoryLockPrefixForRotating + l.config.Path if !gmlock.TryLock(memoryLockKey) { return } defer gmlock.Unlock(memoryLockKey) var ( - now = time.Now() - pattern = "*.log, *.gz" - files, _ = gfile.ScanDirFile(l.config.Path, pattern, true) + now = time.Now() + pattern = "*.log, *.gz" + files, err = gfile.ScanDirFile(l.config.Path, pattern, true) ) + if err != nil { + intlog.Error(err) + } intlog.Printf("logging rotation start checks: %+v", files) // ============================================================= // Rotation of expired file checks. @@ -141,7 +149,10 @@ func (l *Logger) rotateChecksTimely() { } if expireRotated { // Update the files array. - files, _ = gfile.ScanDirFile(l.config.Path, pattern, true) + files, err = gfile.ScanDirFile(l.config.Path, pattern, true) + if err != nil { + intlog.Error(err) + } } } @@ -175,7 +186,10 @@ func (l *Logger) rotateChecksTimely() { return true }) // Update the files array. - files, _ = gfile.ScanDirFile(l.config.Path, pattern, true) + files, err = gfile.ScanDirFile(l.config.Path, pattern, true) + if err != nil { + intlog.Error(err) + } } } @@ -192,10 +206,12 @@ func (l *Logger) rotateChecksTimely() { if backupFilesMap[originalLoggingFilePath] == nil { backupFilesMap[originalLoggingFilePath] = garray.NewSortedArray(func(a, b interface{}) int { // Sorted by rotated/backup file mtime. - // The old rotated/backup file is put in the head of array. - file1 := a.(string) - file2 := b.(string) - result := gfile.MTimestampMilli(file1) - gfile.MTimestampMilli(file2) + // The older rotated/backup file is put in the head of array. + var ( + file1 = a.(string) + file2 = b.(string) + result = gfile.MTimestampMilli(file1) - gfile.MTimestampMilli(file2) + ) if result <= 0 { return -1 } @@ -214,11 +230,11 @@ func (l *Logger) rotateChecksTimely() { path, _ := array.PopLeft() intlog.Printf(`remove exceeded backup limit file: %s`, path) if err := gfile.Remove(path.(string)); err != nil { - intlog.Print(err) + intlog.Error(err) } } } - // Backup expiration checks. + // Backups expiration checking. if l.config.RotateBackupExpire > 0 { var ( mtime time.Time @@ -235,7 +251,7 @@ func (l *Logger) rotateChecksTimely() { now, mtime, subDuration, l.config.RotateBackupExpire, path, ) if err := gfile.Remove(path); err != nil { - intlog.Print(err) + intlog.Error(err) } return true } else {