logrus.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package log
  2. import (
  3. "context"
  4. "os"
  5. "github.com/sagernet/sing-box/option"
  6. "github.com/sagernet/sing/common"
  7. E "github.com/sagernet/sing/common/exceptions"
  8. F "github.com/sagernet/sing/common/format"
  9. "github.com/sirupsen/logrus"
  10. )
  11. var _ Logger = (*logrusLogger)(nil)
  12. type logrusLogger struct {
  13. abstractLogrusLogger
  14. outputPath string
  15. output *os.File
  16. }
  17. type abstractLogrusLogger interface {
  18. logrus.Ext1FieldLogger
  19. WithContext(ctx context.Context) *logrus.Entry
  20. }
  21. func NewLogrusLogger(options option.LogOption) (*logrusLogger, error) {
  22. logger := logrus.New()
  23. logger.SetLevel(logrus.TraceLevel)
  24. logger.SetFormatter(&LogrusTextFormatter{
  25. DisableColors: options.DisableColor || options.Output != "",
  26. DisableTimestamp: !options.Timestamp && options.Output != "",
  27. FullTimestamp: options.Timestamp,
  28. })
  29. logger.AddHook(new(logrusHook))
  30. var err error
  31. if options.Level != "" {
  32. logger.Level, err = logrus.ParseLevel(options.Level)
  33. if err != nil {
  34. return nil, err
  35. }
  36. }
  37. return &logrusLogger{logger, options.Output, nil}, nil
  38. }
  39. func (l *logrusLogger) Start() error {
  40. if l.outputPath != "" {
  41. output, err := os.OpenFile(l.outputPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
  42. if err != nil {
  43. return E.Cause(err, "open log output")
  44. }
  45. l.abstractLogrusLogger.(*logrus.Logger).SetOutput(output)
  46. }
  47. return nil
  48. }
  49. func (l *logrusLogger) Close() error {
  50. return common.Close(common.PtrOrNil(l.output))
  51. }
  52. func (l *logrusLogger) WithContext(ctx context.Context) Logger {
  53. return &logrusLogger{abstractLogrusLogger: l.abstractLogrusLogger.WithContext(ctx)}
  54. }
  55. func (l *logrusLogger) WithPrefix(prefix string) Logger {
  56. if entry, isEntry := l.abstractLogrusLogger.(*logrus.Entry); isEntry {
  57. loadedPrefix := entry.Data["prefix"]
  58. if loadedPrefix != "" {
  59. prefix = F.ToString(loadedPrefix, prefix)
  60. }
  61. }
  62. return &logrusLogger{abstractLogrusLogger: l.WithField("prefix", prefix)}
  63. }