log_plugin.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package logger
  2. import (
  3. "encoding/json"
  4. stringUtils "eta_mini_ht_api/common/utils"
  5. "fmt"
  6. "github.com/beego/beego/v2/core/logs"
  7. "log"
  8. "os"
  9. "path"
  10. )
  11. const (
  12. DefalutLogFilePath = "./etalogs"
  13. LogChannelLen = 10000
  14. )
  15. var (
  16. loggerHandler *CustomLogger
  17. )
  18. type logger struct {
  19. *logs.BeeLogger
  20. filter string
  21. }
  22. type CustomLogger struct {
  23. logs []*logger
  24. }
  25. // Logger interface
  26. type Logger interface {
  27. Info(msg string)
  28. Warn(msg string)
  29. Error(msg string)
  30. }
  31. func Info(msg string) {
  32. loggerHandler.Info(msg)
  33. }
  34. func Error(msg string) {
  35. loggerHandler.Error(msg)
  36. }
  37. func Warn(msg string) {
  38. loggerHandler.Warn(msg)
  39. }
  40. func (c *CustomLogger) Info(msg string) {
  41. for _, appender := range c.logs {
  42. if appender.GetLevel() >= logs.LevelInfo {
  43. appender.Info(msg)
  44. }
  45. }
  46. }
  47. func (c *CustomLogger) Error(msg string) {
  48. for _, logger := range c.logs {
  49. if logger.GetLevel() >= logs.LevelError {
  50. logger.Error(msg)
  51. }
  52. }
  53. }
  54. func (c *CustomLogger) Warn(msg string) {
  55. for _, logger := range c.logs {
  56. if logger.GetLevel() >= logs.LevelWarning {
  57. logger.Error(msg)
  58. }
  59. }
  60. }
  61. func init() {
  62. var logCfg logConfig
  63. configFile, err := os.ReadFile("conf/log/log_config.json")
  64. if err != nil {
  65. log.Fatalf("Failed to read log config: %v", err)
  66. }
  67. err = json.Unmarshal(configFile, &logCfg)
  68. if err != nil {
  69. log.Fatalf("Failed to parse log config: %v", err)
  70. }
  71. initLogger(logCfg)
  72. }
  73. var levelTrans = map[string]int{
  74. "emergency": logs.LevelEmergency,
  75. "alert": logs.LevelAlert,
  76. "critical": logs.LevelCritical,
  77. "error": logs.LevelError,
  78. "warn": logs.LevelWarning,
  79. "notice": logs.LevelNotice,
  80. "info": logs.LevelInformational,
  81. "debug": logs.LevelDebug,
  82. }
  83. var terminalType = map[string]string{
  84. "console": logs.AdapterConsole,
  85. "file": logs.AdapterFile,
  86. }
  87. func GetInstance() Logger {
  88. return loggerHandler
  89. }
  90. func initLogger(logCfg logConfig) {
  91. if loggerHandler == nil {
  92. loggerHandler = new(CustomLogger)
  93. }
  94. if stringUtils.IsEmptyOrNil(logCfg.FilePath) {
  95. logCfg.FilePath = DefalutLogFilePath
  96. }
  97. for _, appender := range logCfg.Appenders {
  98. terminalType, ok := terminalType[appender.Type]
  99. if !ok {
  100. fmt.Println("初始化日志执行器失败:{%s},终端类型不支持{type:%s}", appender.FileName, appender.Type)
  101. continue
  102. }
  103. var beeLogger *logs.BeeLogger
  104. if terminalType == logs.AdapterConsole {
  105. beeLogger = logs.NewLogger(LogChannelLen)
  106. err := beeLogger.SetLogger(logs.AdapterConsole)
  107. if err != nil {
  108. fmt.Println("创建日志执行器失败:{%s} %v", appender.FileName, err)
  109. continue
  110. }
  111. } else {
  112. logFile := appender.FileName
  113. os.MkdirAll(logCfg.FilePath, os.ModePerm)
  114. // 打开文件
  115. appender.FileName = path.Join(logCfg.FilePath, logFile)
  116. logProps, err := convertAppenderToLog(&appender)
  117. if err != nil {
  118. fmt.Println("初始化日志执行器失败:{%s} %v", appender.FileName, err)
  119. continue
  120. }
  121. b, _ := json.Marshal(logProps)
  122. beeLogger = logs.NewLogger(LogChannelLen)
  123. err = beeLogger.SetLogger(logs.AdapterFile, string(b))
  124. if err != nil {
  125. fmt.Println("设置日志执行器失败:{%s} %v", appender.FileName, err)
  126. continue
  127. }
  128. beeLogger.EnableFuncCallDepth(true)
  129. }
  130. loggerHandler.logs = append(loggerHandler.logs, &logger{BeeLogger: beeLogger,
  131. filter: appender.Filter})
  132. }
  133. }
  134. // ConvertAppenderToLog 将 appender 结构体转换为 log 结构体
  135. func convertAppenderToLog(a *appender) (*logProps, error) {
  136. lvl, ok := levelTrans[a.Level]
  137. if !ok {
  138. return nil, fmt.Errorf("unknown log level: %s", a.Level)
  139. }
  140. return &logProps{
  141. Prefix: a.Prefix,
  142. FileName: a.FileName,
  143. MaxLines: a.MaxLines,
  144. MaxSize: a.MaxSize,
  145. Daily: a.Daily,
  146. MaxDays: a.MaxDays,
  147. Rotate: a.Rotate,
  148. Level: lvl,
  149. Color: a.Color,
  150. }, nil
  151. }
  152. // logConfig 日志配置
  153. type logConfig struct {
  154. FilePath string `json:"filepath" description:"日志路径"`
  155. Appenders []appender `json:"appenders" description:"日志记录"`
  156. }
  157. // appender beeLogger JSON配置
  158. type appender struct {
  159. Filter string `json:"filter"`
  160. Prefix string `json:"perfix" description:"日志前缀"`
  161. Type string `json:"type" description:"终端类型"`
  162. FileName string `json:"filename" description:"保存的文件名"`
  163. MaxLines int `json:"maxlines" description:"每个文件保存的最大行数,默认值 1000000"`
  164. MaxSize int `json:"maxsize" description:"每个文件保存的最大尺寸,默认值是 1 << 28, //256 MB"`
  165. Daily bool `json:"daily" description:"是否按照每天 logrotate,默认是 true"`
  166. MaxDays int `json:"maxdays" description:"文件最多保存多少天,默认保存 7 天"`
  167. Rotate bool `json:"rotate" description:"是否开启 logrotate,默认是 true"`
  168. Level string `json:"level" description:"日志保存的时候的级别,默认是 Trace 级别"`
  169. Color bool `json:"color" description:"日志是否输出颜色"`
  170. }
  171. // logProps beeLogger 配置
  172. type logProps struct {
  173. Prefix string `json:"perfix" description:"日志前缀"`
  174. FileName string `json:"filename" description:"保存的文件名"`
  175. MaxLines int `json:"maxlines" description:"每个文件保存的最大行数,默认值 1000000"`
  176. MaxSize int `json:"maxsize" description:"每个文件保存的最大尺寸,默认值是 1 << 28, //256 MB"`
  177. Daily bool `json:"daily" description:"是否按照每天 logrotate,默认是 true"`
  178. MaxDays int `json:"maxdays" description:"文件最多保存多少天,默认保存 7 天"`
  179. Rotate bool `json:"rotate" description:"是否开启 logrotate,默认是 true"`
  180. Level int `json:"level" description:"日志保存的时候的级别,默认是 Trace 级别"`
  181. Color bool `json:"color" description:"日志是否输出颜色"`
  182. }