handler.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package logger
  2. import (
  3. "bytes"
  4. "context"
  5. "fmt"
  6. "log/slog"
  7. "sync"
  8. )
  9. type Handler struct {
  10. config HandlerConfig
  11. handler slog.Handler
  12. mu *sync.Mutex
  13. buf *bytes.Buffer
  14. }
  15. type HandlerConfig struct {
  16. // stdout config
  17. stdoutLogEnabled bool
  18. stdoutLogLevel slog.Level // INFO by default
  19. // file config
  20. fileLogEnabled bool
  21. fileLogLevel slog.Level // INFO by default
  22. // email config
  23. emailLogEnabled bool
  24. emailLogLevel slog.Level // INFO by default
  25. // common config
  26. minLogLevel slog.Level
  27. timeFormat string
  28. }
  29. func NewHandler(c Config) Handler {
  30. buf := &bytes.Buffer{}
  31. minLogLevel := getMinLogLevel(c)
  32. if len(c.timeFormat) == 0 {
  33. c.timeFormat = defaultTimeFormat
  34. }
  35. return Handler{
  36. buf: buf,
  37. mu: &sync.Mutex{},
  38. handler: slog.NewJSONHandler(buf, &slog.HandlerOptions{
  39. AddSource: c.addSource,
  40. Level: minLogLevel,
  41. }),
  42. config: HandlerConfig{
  43. stdoutLogEnabled: c.stdoutLogEnabled,
  44. fileLogEnabled: c.fileLogEnabled,
  45. emailLogEnabled: c.emailLogEnabled,
  46. stdoutLogLevel: c.stdoutLogLevel,
  47. fileLogLevel: c.fileLogLevel,
  48. emailLogLevel: c.emailLogLevel,
  49. minLogLevel: minLogLevel,
  50. timeFormat: c.timeFormat,
  51. },
  52. }
  53. }
  54. func (h *Handler) Handle(ctx context.Context, r slog.Record) error {
  55. message := r.Time.Format(h.config.timeFormat) + " " + r.Level.String() + " " + r.Message
  56. var attrs map[string]any
  57. r.Attrs(func(attr slog.Attr) bool {
  58. return true
  59. })
  60. if h.config.stdoutLogEnabled {
  61. fmt.Println(message)
  62. }
  63. return nil
  64. }
  65. func (h *Handler) Enabled(_ context.Context, l slog.Level) bool {
  66. return l >= h.config.minLogLevel
  67. }
  68. func (h *Handler) WithAttrs(attrs []slog.Attr) slog.Handler {
  69. return &Handler{handler: h.handler.WithAttrs(attrs), buf: h.buf, mu: h.mu, config: h.config}
  70. }
  71. func (h *Handler) WithGroup(name string) slog.Handler {
  72. return &Handler{handler: h.handler.WithGroup(name), buf: h.buf, mu: h.mu, config: h.config}
  73. }
  74. func getMinLogLevel(c Config) slog.Level {
  75. minLogLevel := slog.LevelError
  76. if c.stdoutLogEnabled && c.stdoutLogLevel < minLogLevel {
  77. minLogLevel = c.stdoutLogLevel
  78. }
  79. if c.fileLogEnabled && c.fileLogLevel < minLogLevel {
  80. minLogLevel = c.fileLogLevel
  81. }
  82. if c.emailLogEnabled && c.emailLogLevel < minLogLevel {
  83. minLogLevel = c.fileLogLevel
  84. }
  85. return minLogLevel
  86. }