logrus.go 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package util
  2. import (
  3. "io"
  4. "os"
  5. "path"
  6. "time"
  7. rotatelogs "github.com/lestrrat/go-file-rotatelogs"
  8. "github.com/sirupsen/logrus"
  9. )
  10. func init() {
  11. // ========== 核心配置 ==========
  12. logDir := "./log"
  13. dirPerm := os.FileMode(0777) // 目录权限:pi可读写执行,同组可读执行
  14. filePerm := os.FileMode(0777) // 文件权限:pi可读写,其他可读
  15. today := time.Now().Format("20060102")
  16. todayLogFile := path.Join(logDir, "info."+today+".log")
  17. logFileTemplate := path.Join(logDir, "info.%Y%m%d.log")
  18. // ========== 1. 强制创建目录 + 修复目录归属/权限 ==========
  19. if err := os.MkdirAll(logDir, dirPerm); err != nil {
  20. logrus.Fatalf("[日志初始化] 创建日志目录失败: %v", err)
  21. }
  22. // 关键:强制将目录归属当前运行用户(pi),无论之前归属谁
  23. if err := os.Chown(logDir, os.Getuid(), os.Getgid()); err != nil {
  24. logrus.Warnf("[日志初始化] 修正目录归属失败(非致命): %v", err)
  25. }
  26. // 二次校验目录权限(确保不是只读)
  27. if err := os.Chmod(logDir, dirPerm); err != nil {
  28. logrus.Warnf("[日志初始化] 修正目录权限失败(非致命): %v", err)
  29. }
  30. // ========== 2. 强制创建今日日志文件 + 修复文件归属/权限 ==========
  31. // 打开文件(创建+追加+写入,确保文件存在且权限正确)
  32. f, err := os.OpenFile(todayLogFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, filePerm)
  33. if err != nil {
  34. logrus.Fatalf("[日志初始化] 创建日志文件失败: %v", err)
  35. }
  36. f.Close() // 关闭临时句柄
  37. // 强制将文件归属当前用户(核心:解决sudo残留的root归属问题)
  38. if err := os.Chown(todayLogFile, os.Getuid(), os.Getgid()); err != nil {
  39. logrus.Warnf("[日志初始化] 修正文件归属失败(非致命): %v", err)
  40. }
  41. // 二次校验文件权限
  42. if err := os.Chmod(todayLogFile, filePerm); err != nil {
  43. logrus.Warnf("[日志初始化] 修正文件权限失败(非致命): %v", err)
  44. }
  45. // ========== 3. 初始化日志切割(适配旧版本rotatelogs) ==========
  46. writer, err := rotatelogs.New(
  47. logFileTemplate,
  48. rotatelogs.WithMaxAge(5*24*time.Hour),
  49. rotatelogs.WithRotationTime(24*time.Hour),
  50. rotatelogs.WithLinkName(path.Join(logDir, "info.log")),
  51. )
  52. if err != nil {
  53. logrus.Fatalf("[日志初始化] 创建日志切割器失败: %v", err)
  54. }
  55. // ========== 4. 日志格式配置 ==========
  56. logrus.SetFormatter(&logrus.JSONFormatter{
  57. TimestampFormat: "2006-01-02 15:04:05", // 标准Go时间模板
  58. })
  59. logrus.SetLevel(logrus.DebugLevel)
  60. logrus.SetReportCaller(true)
  61. // 同时输出到控制台+文件
  62. logrus.SetOutput(io.MultiWriter(os.Stdout, writer))
  63. logrus.Info("[日志初始化] 日志配置完成,权限已强制适配pi用户")
  64. }