1package log
2
3import (
4 "bytes"
5 "fmt"
6 "io"
7 "log"
8 "os"
9 "sync"
10 "sync/atomic"
11 "time"
12
13 "github.com/charmbracelet/colorprofile"
14)
15
16var (
17 // defaultLogger is the default global logger instance.
18 defaultLogger atomic.Pointer[Logger]
19 defaultLoggerOnce sync.Once
20)
21
22// Default returns the default logger. The default logger comes with timestamp enabled.
23func Default() *Logger {
24 dl := defaultLogger.Load()
25 if dl == nil {
26 defaultLoggerOnce.Do(func() {
27 defaultLogger.CompareAndSwap(
28 nil, NewWithOptions(os.Stderr, Options{ReportTimestamp: true}),
29 )
30 })
31 dl = defaultLogger.Load()
32 }
33 return dl
34}
35
36// SetDefault sets the default global logger.
37func SetDefault(logger *Logger) {
38 defaultLogger.Store(logger)
39}
40
41// New returns a new logger with the default options.
42func New(w io.Writer) *Logger {
43 return NewWithOptions(w, Options{})
44}
45
46// NewWithOptions returns a new logger using the provided options.
47func NewWithOptions(w io.Writer, o Options) *Logger {
48 l := &Logger{
49 b: bytes.Buffer{},
50 mu: &sync.RWMutex{},
51 helpers: &sync.Map{},
52 level: int64(o.Level),
53 reportTimestamp: o.ReportTimestamp,
54 reportCaller: o.ReportCaller,
55 prefix: o.Prefix,
56 timeFunc: o.TimeFunction,
57 timeFormat: o.TimeFormat,
58 formatter: o.Formatter,
59 fields: o.Fields,
60 callerFormatter: o.CallerFormatter,
61 callerOffset: o.CallerOffset,
62 }
63
64 l.SetOutput(w)
65 // Detect color profile from the writer and environment.
66 l.SetColorProfile(colorprofile.Detect(w, os.Environ()))
67 l.SetLevel(Level(l.level))
68 l.SetStyles(DefaultStyles())
69
70 if l.callerFormatter == nil {
71 l.callerFormatter = ShortCallerFormatter
72 }
73
74 if l.timeFunc == nil {
75 l.timeFunc = func(t time.Time) time.Time { return t }
76 }
77
78 if l.timeFormat == "" {
79 l.timeFormat = DefaultTimeFormat
80 }
81
82 return l
83}
84
85// SetReportTimestamp sets whether to report timestamp for the default logger.
86func SetReportTimestamp(report bool) {
87 Default().SetReportTimestamp(report)
88}
89
90// SetReportCaller sets whether to report caller location for the default logger.
91func SetReportCaller(report bool) {
92 Default().SetReportCaller(report)
93}
94
95// SetLevel sets the level for the default logger.
96func SetLevel(level Level) {
97 Default().SetLevel(level)
98}
99
100// GetLevel returns the level for the default logger.
101func GetLevel() Level {
102 return Default().GetLevel()
103}
104
105// SetTimeFormat sets the time format for the default logger.
106func SetTimeFormat(format string) {
107 Default().SetTimeFormat(format)
108}
109
110// SetTimeFunction sets the time function for the default logger.
111func SetTimeFunction(f TimeFunction) {
112 Default().SetTimeFunction(f)
113}
114
115// SetOutput sets the output for the default logger.
116func SetOutput(w io.Writer) {
117 Default().SetOutput(w)
118}
119
120// SetFormatter sets the formatter for the default logger.
121func SetFormatter(f Formatter) {
122 Default().SetFormatter(f)
123}
124
125// SetCallerFormatter sets the caller formatter for the default logger.
126func SetCallerFormatter(f CallerFormatter) {
127 Default().SetCallerFormatter(f)
128}
129
130// SetCallerOffset sets the caller offset for the default logger.
131func SetCallerOffset(offset int) {
132 Default().SetCallerOffset(offset)
133}
134
135// SetPrefix sets the prefix for the default logger.
136func SetPrefix(prefix string) {
137 Default().SetPrefix(prefix)
138}
139
140// SetColorProfile force sets the underlying color profile for the
141// TextFormatter.
142func SetColorProfile(profile colorprofile.Profile) {
143 Default().SetColorProfile(profile)
144}
145
146// SetStyles sets the logger styles for the TextFormatter.
147func SetStyles(s *Styles) {
148 Default().SetStyles(s)
149}
150
151// GetPrefix returns the prefix for the default logger.
152func GetPrefix() string {
153 return Default().GetPrefix()
154}
155
156// With returns a new logger with the given keyvals.
157func With(keyvals ...interface{}) *Logger {
158 return Default().With(keyvals...)
159}
160
161// WithPrefix returns a new logger with the given prefix.
162func WithPrefix(prefix string) *Logger {
163 return Default().WithPrefix(prefix)
164}
165
166// Helper marks the calling function as a helper
167// and skips it for source location information.
168// It's the equivalent of testing.TB.Helper().
169func Helper() {
170 Default().helper(1)
171}
172
173// Log logs a message with the given level.
174func Log(level Level, msg interface{}, keyvals ...interface{}) {
175 Default().Log(level, msg, keyvals...)
176}
177
178// Debug logs a debug message.
179func Debug(msg interface{}, keyvals ...interface{}) {
180 Default().Log(DebugLevel, msg, keyvals...)
181}
182
183// Info logs an info message.
184func Info(msg interface{}, keyvals ...interface{}) {
185 Default().Log(InfoLevel, msg, keyvals...)
186}
187
188// Warn logs a warning message.
189func Warn(msg interface{}, keyvals ...interface{}) {
190 Default().Log(WarnLevel, msg, keyvals...)
191}
192
193// Error logs an error message.
194func Error(msg interface{}, keyvals ...interface{}) {
195 Default().Log(ErrorLevel, msg, keyvals...)
196}
197
198// Fatal logs a fatal message and exit.
199func Fatal(msg interface{}, keyvals ...interface{}) {
200 Default().Log(FatalLevel, msg, keyvals...)
201 os.Exit(1)
202}
203
204// Print logs a message with no level.
205func Print(msg interface{}, keyvals ...interface{}) {
206 Default().Log(noLevel, msg, keyvals...)
207}
208
209// Logf logs a message with formatting and level.
210func Logf(level Level, format string, args ...interface{}) {
211 Default().Logf(level, format, args...)
212}
213
214// Debugf logs a debug message with formatting.
215func Debugf(format string, args ...interface{}) {
216 Default().Log(DebugLevel, fmt.Sprintf(format, args...))
217}
218
219// Infof logs an info message with formatting.
220func Infof(format string, args ...interface{}) {
221 Default().Log(InfoLevel, fmt.Sprintf(format, args...))
222}
223
224// Warnf logs a warning message with formatting.
225func Warnf(format string, args ...interface{}) {
226 Default().Log(WarnLevel, fmt.Sprintf(format, args...))
227}
228
229// Errorf logs an error message with formatting.
230func Errorf(format string, args ...interface{}) {
231 Default().Log(ErrorLevel, fmt.Sprintf(format, args...))
232}
233
234// Fatalf logs a fatal message with formatting and exit.
235func Fatalf(format string, args ...interface{}) {
236 Default().Log(FatalLevel, fmt.Sprintf(format, args...))
237 os.Exit(1)
238}
239
240// Printf logs a message with formatting and no level.
241func Printf(format string, args ...interface{}) {
242 Default().Log(noLevel, fmt.Sprintf(format, args...))
243}
244
245// StandardLog returns a standard logger from the default logger.
246func StandardLog(opts ...StandardLogOptions) *log.Logger {
247 return Default().StandardLog(opts...)
248}