log_hub.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package log_helper
  2. import (
  3. "fmt"
  4. "github.com/allanpk716/ChineseSubFinder/internal/pkg/global_value"
  5. "github.com/sirupsen/logrus"
  6. easy "github.com/t-tomalak/logrus-easy-formatter"
  7. "os"
  8. "path/filepath"
  9. "time"
  10. )
  11. /*
  12. 这里独立出来一个按扫描次为单位的日志模块,暂时没有打算替换原有的日志模块
  13. 仅仅是为了更好地获取、展示日志,也方便后续的问题反馈提交
  14. 考虑到这里,暂定这里的日志都需要存储到硬盘中,且有两种方式获取:
  15. 1. 从 http 接口查询完成的多次的日志
  16. 2. 从 ws 接口中获取当前正在进行扫描的日志
  17. 既然是没有替换的打算,那么就使用 logrus 的 hook 接口去完成额外日志的记录即可,也就是在“每次”扫描的开始和结束进行标记,然后拆分成多次的日志好了
  18. */
  19. type LoggerHub struct {
  20. onceLogger *logrus.Logger // 一次扫描日志的实例
  21. onceStart bool
  22. }
  23. func NewLoggerHub() *LoggerHub {
  24. return &LoggerHub{}
  25. }
  26. func (lh *LoggerHub) Levels() []logrus.Level {
  27. // 记录全级别
  28. return []logrus.Level{
  29. logrus.TraceLevel,
  30. logrus.DebugLevel,
  31. logrus.InfoLevel,
  32. logrus.WarnLevel,
  33. logrus.ErrorLevel,
  34. logrus.FatalLevel,
  35. logrus.PanicLevel,
  36. }
  37. }
  38. func (lh *LoggerHub) Fire(entry *logrus.Entry) error {
  39. if entry.Message == OnceSubsScanStart {
  40. // 收到日志的标志位,需要新开一个
  41. if lh.onceStart == false {
  42. lh.onceLogger = newOnceLogger()
  43. lh.onceStart = true
  44. }
  45. return nil
  46. } else if entry.Message == OnceSubsScanEnd {
  47. // “一次”扫描的结束标志位
  48. lh.onceStart = false
  49. if onceLoggerFile != nil {
  50. _ = onceLoggerFile.Close()
  51. onceLoggerFile = nil
  52. }
  53. return nil
  54. }
  55. if lh.onceStart == false {
  56. // 如果没有发现开启一次扫描的记录标志位,那么就不进行日志的写入
  57. return nil
  58. }
  59. switch entry.Level {
  60. case logrus.TraceLevel:
  61. lh.onceLogger.Traceln(entry.Message)
  62. case logrus.DebugLevel:
  63. lh.onceLogger.Debugln(entry.Message)
  64. case logrus.InfoLevel:
  65. lh.onceLogger.Infoln(entry.Message)
  66. case logrus.WarnLevel:
  67. lh.onceLogger.Warningln(entry.Message)
  68. case logrus.ErrorLevel:
  69. lh.onceLogger.Errorln(entry.Message)
  70. case logrus.FatalLevel:
  71. lh.onceLogger.Fatalln(entry.Message)
  72. case logrus.PanicLevel:
  73. lh.onceLogger.Panicln(entry.Message)
  74. }
  75. return nil
  76. }
  77. func newOnceLogger() *logrus.Logger {
  78. var err error
  79. Logger := logrus.New()
  80. Logger.Formatter = &easy.Formatter{
  81. TimestampFormat: "2006-01-02 15:04:05",
  82. LogFormat: "[%lvl%]: %time% - %msg%\n",
  83. }
  84. nowTime := time.Now()
  85. pathRoot := filepath.Join(global_value.ConfigRootDirFPath, "Logs")
  86. fileName := fmt.Sprintf(onceLogPrefix+"%v.log", nowTime.Unix())
  87. fileAbsPath := filepath.Join(pathRoot, fileName)
  88. if onceLoggerFile != nil {
  89. _ = onceLoggerFile.Close()
  90. onceLoggerFile = nil
  91. }
  92. onceLoggerFile, err = os.OpenFile(fileAbsPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, os.ModePerm)
  93. if err != nil {
  94. GetLogger().Panicln("newOnceLogger.OpenFile", err)
  95. }
  96. Logger.SetOutput(onceLoggerFile)
  97. // 扫描当前日志存储目录下有多少个符合要求的 Once- 日志
  98. // 确保有且仅有最近的 20 次扫描日志记录存在即可
  99. matches, err := filepath.Glob(filepath.Join(pathRoot, onceLogPrefix+"*.log"))
  100. if len(matches) > onceLogMaxCount {
  101. // 需要清理多余的
  102. // 保存的文件名是 Once-unixTime.log 做为前提
  103. // 这里假定查询出来的都是正序排序
  104. for i := 0; i <= len(matches)-1-onceLogMaxCount; i++ {
  105. _, err := os.Stat(matches[i])
  106. if err != nil {
  107. continue
  108. }
  109. _ = os.Remove(matches[i])
  110. }
  111. }
  112. return Logger
  113. }
  114. var (
  115. onceLoggerFile *os.File
  116. )
  117. const (
  118. onceLogMaxCount = 5
  119. onceLogPrefix = "Once-"
  120. OnceSubsScanStart = "OneTimeSubtitleScanStart"
  121. OnceSubsScanEnd = "OneTimeSubtitleScanEnd"
  122. )