...
1 package log
2
3 import (
4 "context"
5 "os"
6
7 "github.com/jackc/pgx/v5/tracelog"
8 "github.com/rifflock/lfshook"
9 "github.com/sirupsen/logrus"
10 "gopkg.in/natefinch/lumberjack.v2"
11 )
12
13 type (
14
15 LoggerIface logrus.FieldLogger
16
17 LoggerHookerIface interface {
18 LoggerIface
19 AddHook(hook logrus.Hook)
20 AddSubscriber(msgCh MessageChanType)
21 RemoveSubscriber(msgCh MessageChanType)
22 }
23
24 loggerKey struct{}
25 )
26
27 type logger struct {
28 *logrus.Logger
29 *BrokerHook
30 }
31
32 func getLogFileWriter(opts CmdOpts) any {
33 if opts.LogFileRotate {
34 return &lumberjack.Logger{
35 Filename: opts.LogFile,
36 MaxSize: opts.LogFileSize,
37 MaxBackups: opts.LogFileNumber,
38 MaxAge: opts.LogFileAge,
39 }
40 }
41 return opts.LogFile
42 }
43
44 const (
45 disableColors = true
46 enableColors = false
47 )
48
49 func getLogFileFormatter(opts CmdOpts) logrus.Formatter {
50 if opts.LogFileFormat == "text" {
51 return newFormatter(disableColors)
52 }
53 return &logrus.JSONFormatter{}
54 }
55
56
57 func Init(opts CmdOpts) LoggerHookerIface {
58 var err error
59 l := logger{logrus.New(), NewBrokerHook(context.Background(), opts.LogLevel)}
60 l.AddHook(l.BrokerHook)
61 l.Out = os.Stdout
62 if opts.LogFile > "" {
63 l.AddHook(lfshook.NewHook(getLogFileWriter(opts), getLogFileFormatter(opts)))
64 }
65 l.Level, err = logrus.ParseLevel(opts.LogLevel)
66 if err != nil {
67 l.Level = logrus.InfoLevel
68 }
69 l.SetFormatter(newFormatter(enableColors))
70 l.SetBrokerFormatter(newFormatter(disableColors))
71 l.SetReportCaller(l.Level > logrus.InfoLevel)
72 return l
73 }
74
75
76 type PgxLogger struct {
77 l LoggerIface
78 }
79
80
81 func NewPgxLogger(l LoggerIface) *PgxLogger {
82 return &PgxLogger{l}
83 }
84
85
86 func (pgxlogger *PgxLogger) Log(ctx context.Context, level tracelog.LogLevel, msg string, data map[string]any) {
87 logger := GetLogger(ctx)
88 if logger == FallbackLogger {
89 logger = pgxlogger.l
90 }
91 if data != nil {
92 logger = logger.WithFields(data)
93 }
94 switch level {
95 case tracelog.LogLevelTrace:
96 logger.WithField("PGX_LOG_LEVEL", level).Debug(msg)
97 case tracelog.LogLevelDebug, tracelog.LogLevelInfo:
98 logger.Debug(msg)
99 case tracelog.LogLevelWarn:
100 logger.Warn(msg)
101 case tracelog.LogLevelError:
102 logger.Error(msg)
103 default:
104 logger.WithField("INVALID_PGX_LOG_LEVEL", level).Error(msg)
105 }
106 }
107
108
109
110 func WithLogger(ctx context.Context, logger LoggerIface) context.Context {
111 return context.WithValue(ctx, loggerKey{}, logger)
112 }
113
114
115 var FallbackLogger = Init(CmdOpts{})
116
117
118
119 func GetLogger(ctx context.Context) LoggerIface {
120 logger := ctx.Value(loggerKey{})
121 if logger == nil {
122 return FallbackLogger
123 }
124 return logger.(LoggerIface)
125 }
126