integration.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package golog
  2. import (
  3. "context"
  4. "log/slog"
  5. )
  6. func integrade(logger any) Handler {
  7. switch v := logger.(type) {
  8. case *slog.Logger:
  9. return integradeSlog(v)
  10. case ExternalLogger:
  11. return integrateExternalLogger(v)
  12. case StdLogger:
  13. return integrateStdLogger(v)
  14. default:
  15. panic("not supported logger integration, please open a feature request at: https://github.com/kataras/golog/issues/new")
  16. }
  17. }
  18. /*
  19. func (*slog.Logger).Debug(msg string, args ...any)
  20. func (*slog.Logger).DebugContext(ctx context.Context, msg string, args ...any)
  21. func (*slog.Logger).Enabled(ctx context.Context, level slog.Level) bool
  22. func (*slog.Logger).Error(msg string, args ...any)
  23. func (*slog.Logger).ErrorContext(ctx context.Context, msg string, args ...any)
  24. func (*slog.Logger).Handler() slog.Handler
  25. func (*slog.Logger).Info(msg string, args ...any)
  26. func (*slog.Logger).InfoContext(ctx context.Context, msg string, args ...any)
  27. func (*slog.Logger).Log(ctx context.Context, level slog.Level, msg string, args ...any)
  28. func (*slog.Logger).LogAttrs(ctx context.Context, level slog.Level, msg string, attrs ...slog.Attr)
  29. func (*slog.Logger).Warn(msg string, args ...any)
  30. func (*slog.Logger).WarnContext(ctx context.Context, msg string, args ...any)
  31. func (*slog.Logger).With(args ...any) *slog.Logger
  32. func (*slog.Logger).WithGroup(name string) *slog.Logger
  33. */
  34. func integradeSlog(logger *slog.Logger) Handler {
  35. return func(log *Log) bool {
  36. // golog level to slog level.
  37. level := getSlogLevel(log.Level)
  38. // golog fields to slog attributes.
  39. if len(log.Fields) > 0 {
  40. attrs := make([]slog.Attr, 0, len(log.Fields))
  41. for k, v := range log.Fields {
  42. attrs = append(attrs, slog.Any(k, v))
  43. }
  44. // log the message with attrs.
  45. logger.LogAttrs(context.Background(), level, log.Message, attrs...)
  46. } else {
  47. logger.Log(context.Background(), level, log.Message)
  48. }
  49. return true
  50. }
  51. }
  52. // ExternalLogger is a typical logger interface.
  53. // Any logger or printer that completes this interface
  54. // can be used to intercept and handle the golog's messages.
  55. //
  56. // See `Logger#Install` and `Logger#Handle` for more.
  57. type ExternalLogger interface {
  58. Print(...interface{})
  59. Println(...interface{})
  60. Error(...interface{})
  61. Warn(...interface{})
  62. Info(...interface{})
  63. Debug(...interface{})
  64. }
  65. // integrateExternalLogger is a Handler which
  66. // intercepts all messages from print functions,
  67. // between print action and actual write to the output,
  68. // and sends these (messages) to the external "logger".
  69. //
  70. // In short terms, when this handler is passed via `Handle`
  71. // then, instead of printing from the logger's Printer
  72. // it prints from the given "logger".
  73. func integrateExternalLogger(logger ExternalLogger) Handler {
  74. return func(log *Log) bool {
  75. printFunc := getExternalPrintFunc(logger, log)
  76. printFunc(log.Message)
  77. return true
  78. }
  79. }
  80. func getSlogLevel(level Level) slog.Level {
  81. switch level {
  82. case ErrorLevel:
  83. return slog.LevelError
  84. case WarnLevel:
  85. return slog.LevelWarn
  86. case InfoLevel:
  87. return slog.LevelInfo
  88. case DebugLevel:
  89. return slog.LevelDebug
  90. }
  91. return slog.LevelDebug
  92. }
  93. func getExternalPrintFunc(logger ExternalLogger, log *Log) func(...interface{}) {
  94. switch log.Level {
  95. case ErrorLevel:
  96. return logger.Error
  97. case WarnLevel:
  98. return logger.Warn
  99. case InfoLevel:
  100. return logger.Info
  101. case DebugLevel:
  102. return logger.Debug
  103. }
  104. // disable level or use of golog#Print/Println functions:
  105. // passed with Println
  106. if log.NewLine {
  107. return logger.Println
  108. }
  109. return logger.Print
  110. }
  111. // StdLogger is the standard log.Logger interface.
  112. // Any logger or printer that completes this interface
  113. // can be used to intercept and handle the golog's messages.
  114. //
  115. // See `Logger#Install` and `Logger#Handle` for more.
  116. type StdLogger interface {
  117. Printf(format string, v ...interface{})
  118. Print(v ...interface{})
  119. Println(v ...interface{})
  120. }
  121. func integrateStdLogger(logger StdLogger) Handler {
  122. return func(log *Log) bool {
  123. printFunc := getStdPrintFunc(logger, log)
  124. printFunc(log.Message)
  125. return true
  126. }
  127. }
  128. func getStdPrintFunc(logger StdLogger, log *Log) func(...interface{}) {
  129. // no levels here
  130. // passed with Println
  131. if log.NewLine {
  132. return logger.Println
  133. }
  134. return logger.Print
  135. }