glog_logger_config.go 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. package glog
  7. import (
  8. "errors"
  9. "fmt"
  10. "github.com/gogf/gf/errors/gerror"
  11. "github.com/gogf/gf/internal/intlog"
  12. "github.com/gogf/gf/os/gfile"
  13. "github.com/gogf/gf/util/gconv"
  14. "github.com/gogf/gf/util/gutil"
  15. "io"
  16. "strings"
  17. "time"
  18. )
  19. // Config is the configuration object for logger.
  20. type Config struct {
  21. Writer io.Writer // Customized io.Writer.
  22. Flags int // Extra flags for logging output features.
  23. Path string // Logging directory path.
  24. File string // Format for logging file.
  25. Level int // Output level.
  26. Prefix string // Prefix string for every logging content.
  27. StSkip int // Skip count for stack.
  28. StStatus int // Stack status(1: enabled - default; 0: disabled)
  29. StFilter string // Stack string filter.
  30. CtxKeys []interface{} // Context keys for logging, which is used for value retrieving from context.
  31. HeaderPrint bool `c:"header"` // Print header or not(true in default).
  32. StdoutPrint bool `c:"stdout"` // Output to stdout or not(true in default).
  33. LevelPrefixes map[int]string // Logging level to its prefix string mapping.
  34. RotateSize int64 // Rotate the logging file if its size > 0 in bytes.
  35. RotateExpire time.Duration // Rotate the logging file if its mtime exceeds this duration.
  36. RotateBackupLimit int // Max backup for rotated files, default is 0, means no backups.
  37. RotateBackupExpire time.Duration // Max expire for rotated files, which is 0 in default, means no expiration.
  38. RotateBackupCompress int // Compress level for rotated files using gzip algorithm. It's 0 in default, means no compression.
  39. RotateCheckInterval time.Duration // Asynchronizely checks the backups and expiration at intervals. It's 1 hour in default.
  40. }
  41. // DefaultConfig returns the default configuration for logger.
  42. func DefaultConfig() Config {
  43. c := Config{
  44. File: defaultFileFormat,
  45. Flags: F_TIME_STD,
  46. Level: LEVEL_ALL,
  47. StStatus: 1,
  48. HeaderPrint: true,
  49. StdoutPrint: true,
  50. LevelPrefixes: make(map[int]string, len(defaultLevelPrefixes)),
  51. RotateCheckInterval: time.Hour,
  52. }
  53. for k, v := range defaultLevelPrefixes {
  54. c.LevelPrefixes[k] = v
  55. }
  56. if !defaultDebug {
  57. c.Level = c.Level & ^LEVEL_DEBU
  58. }
  59. return c
  60. }
  61. // SetConfig set configurations for the logger.
  62. func (l *Logger) SetConfig(config Config) error {
  63. l.config = config
  64. // Necessary validation.
  65. if config.Path != "" {
  66. if err := l.SetPath(config.Path); err != nil {
  67. intlog.Error(err)
  68. return err
  69. }
  70. }
  71. intlog.Printf("SetConfig: %+v", l.config)
  72. return nil
  73. }
  74. // SetConfigWithMap set configurations with map for the logger.
  75. func (l *Logger) SetConfigWithMap(m map[string]interface{}) error {
  76. if m == nil || len(m) == 0 {
  77. return errors.New("configuration cannot be empty")
  78. }
  79. // The m now is a shallow copy of m.
  80. // A little tricky, isn't it?
  81. m = gutil.MapCopy(m)
  82. // Change string configuration to int value for level.
  83. levelKey, levelValue := gutil.MapPossibleItemByKey(m, "Level")
  84. if levelValue != nil {
  85. if level, ok := levelStringMap[strings.ToUpper(gconv.String(levelValue))]; ok {
  86. m[levelKey] = level
  87. } else {
  88. return errors.New(fmt.Sprintf(`invalid level string: %v`, levelValue))
  89. }
  90. }
  91. // Change string configuration to int value for file rotation size.
  92. rotateSizeKey, rotateSizeValue := gutil.MapPossibleItemByKey(m, "RotateSize")
  93. if rotateSizeValue != nil {
  94. m[rotateSizeKey] = gfile.StrToSize(gconv.String(rotateSizeValue))
  95. if m[rotateSizeKey] == -1 {
  96. return errors.New(fmt.Sprintf(`invalid rotate size: %v`, rotateSizeValue))
  97. }
  98. }
  99. err := gconv.Struct(m, &l.config)
  100. if err != nil {
  101. return err
  102. }
  103. return l.SetConfig(l.config)
  104. }
  105. // SetDebug enables/disables the debug level for logger.
  106. // The debug level is enabled in default.
  107. func (l *Logger) SetDebug(debug bool) {
  108. if debug {
  109. l.config.Level = l.config.Level | LEVEL_DEBU
  110. } else {
  111. l.config.Level = l.config.Level & ^LEVEL_DEBU
  112. }
  113. }
  114. // SetAsync enables/disables async logging output feature.
  115. func (l *Logger) SetAsync(enabled bool) {
  116. if enabled {
  117. l.config.Flags = l.config.Flags | F_ASYNC
  118. } else {
  119. l.config.Flags = l.config.Flags & ^F_ASYNC
  120. }
  121. }
  122. // SetFlags sets extra flags for logging output features.
  123. func (l *Logger) SetFlags(flags int) {
  124. l.config.Flags = flags
  125. }
  126. // GetFlags returns the flags of logger.
  127. func (l *Logger) GetFlags() int {
  128. return l.config.Flags
  129. }
  130. // SetStack enables/disables the stack feature in failure logging outputs.
  131. func (l *Logger) SetStack(enabled bool) {
  132. if enabled {
  133. l.config.StStatus = 1
  134. } else {
  135. l.config.StStatus = 0
  136. }
  137. }
  138. // SetStackSkip sets the stack offset from the end point.
  139. func (l *Logger) SetStackSkip(skip int) {
  140. l.config.StSkip = skip
  141. }
  142. // SetStackFilter sets the stack filter from the end point.
  143. func (l *Logger) SetStackFilter(filter string) {
  144. l.config.StFilter = filter
  145. }
  146. // SetCtxKeys sets the context keys for logger. The keys is used for retrieving values
  147. // from context and printing them to logging content.
  148. //
  149. // Note that multiple calls of this function will overwrite the previous set context keys.
  150. func (l *Logger) SetCtxKeys(keys ...interface{}) {
  151. l.config.CtxKeys = keys
  152. }
  153. // GetCtxKeys retrieves and returns the context keys for logging.
  154. func (l *Logger) GetCtxKeys() []interface{} {
  155. return l.config.CtxKeys
  156. }
  157. // SetWriter sets the customized logging <writer> for logging.
  158. // The <writer> object should implements the io.Writer interface.
  159. // Developer can use customized logging <writer> to redirect logging output to another service,
  160. // eg: kafka, mysql, mongodb, etc.
  161. func (l *Logger) SetWriter(writer io.Writer) {
  162. l.config.Writer = writer
  163. }
  164. // GetWriter returns the customized writer object, which implements the io.Writer interface.
  165. // It returns nil if no writer previously set.
  166. func (l *Logger) GetWriter() io.Writer {
  167. return l.config.Writer
  168. }
  169. // SetPath sets the directory path for file logging.
  170. func (l *Logger) SetPath(path string) error {
  171. if path == "" {
  172. return errors.New("logging path is empty")
  173. }
  174. if !gfile.Exists(path) {
  175. if err := gfile.Mkdir(path); err != nil {
  176. //fmt.Fprintln(os.Stderr, fmt.Sprintf(`[glog] mkdir "%s" failed: %s`, path, err.Error()))
  177. return gerror.Wrapf(err, `Mkdir "%s" failed in Pwd "%s"`, path, gfile.Pwd())
  178. }
  179. }
  180. l.config.Path = strings.TrimRight(path, gfile.Separator)
  181. return nil
  182. }
  183. // GetPath returns the logging directory path for file logging.
  184. // It returns empty string if no directory path set.
  185. func (l *Logger) GetPath() string {
  186. return l.config.Path
  187. }
  188. // SetFile sets the file name <pattern> for file logging.
  189. // Datetime pattern can be used in <pattern>, eg: access-{Ymd}.log.
  190. // The default file name pattern is: Y-m-d.log, eg: 2018-01-01.log
  191. func (l *Logger) SetFile(pattern string) {
  192. l.config.File = pattern
  193. }
  194. // SetStdoutPrint sets whether output the logging contents to stdout, which is true in default.
  195. func (l *Logger) SetStdoutPrint(enabled bool) {
  196. l.config.StdoutPrint = enabled
  197. }
  198. // SetHeaderPrint sets whether output header of the logging contents, which is true in default.
  199. func (l *Logger) SetHeaderPrint(enabled bool) {
  200. l.config.HeaderPrint = enabled
  201. }
  202. // SetPrefix sets prefix string for every logging content.
  203. // Prefix is part of header, which means if header output is shut, no prefix will be output.
  204. func (l *Logger) SetPrefix(prefix string) {
  205. l.config.Prefix = prefix
  206. }