1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
package logger
import (
"context"
"io"
"os"
"sync"
"sync/atomic"
"codeberg.org/gruf/go-bytes"
)
type Logger struct {
// Hooks defines a list of hooks which are called before an entry
// is written. This should NOT be modified while the Logger is in use
Hooks []Hook
// Level is the current log LEVEL, entries at level below the
// currently set level will not be output. This should NOT
// be modified while the Logger is in use
Level LEVEL
// Timestamp defines whether to automatically append timestamps
// to entries written via Logger convience methods and specifically
// Entry.TimestampIf(). This should NOT be modified while Logger in use
Timestamp bool
// Format is the log entry LogFormat to use. This should NOT
// be modified while the Logger is in use
Format LogFormat
// BufferSize is the Entry buffer size to use when allocating
// new Entry objects. This should be modified atomically
BufSize int64
// Output is the log's output writer. This should NOT be
// modified while the Logger is in use
Output io.Writer
// entry pool
pool sync.Pool
}
// New returns a new Logger instance with defaults
func New(out io.Writer) *Logger {
return NewWith(0 /* all */, true, NewLogFmt(false), 512, out)
}
// NewWith returns a new Logger instance with supplied configuration
func NewWith(lvl LEVEL, timestamp bool, fmt LogFormat, bufsize int64, out io.Writer) *Logger {
// Create new logger object
log := &Logger{
Level: lvl,
Timestamp: timestamp,
Format: fmt,
BufSize: bufsize,
Output: out,
pool: sync.Pool{},
}
// Ensure clock running
startClock()
// Set-up logger Entry pool
log.pool.New = func() interface{} {
return &Entry{
lvl: unset,
buf: &bytes.Buffer{B: make([]byte, 0, atomic.LoadInt64(&log.BufSize))},
log: log,
}
}
return log
}
// Entry returns a new Entry from the Logger's pool with background context
func (l *Logger) Entry() *Entry {
return l.pool.Get().(*Entry).WithContext(context.Background())
}
// Debug prints the provided arguments with the debug prefix
func (l *Logger) Debug(a ...interface{}) {
l.Entry().TimestampIf().Level(DEBUG).Hooks().Msg(a...)
}
// Debugf prints the provided format string and arguments with the debug prefix
func (l *Logger) Debugf(s string, a ...interface{}) {
l.Entry().TimestampIf().Level(DEBUG).Hooks().Msgf(s, a...)
}
// Info prints the provided arguments with the info prefix
func (l *Logger) Info(a ...interface{}) {
l.Entry().TimestampIf().Level(INFO).Hooks().Msg(a...)
}
// Infof prints the provided format string and arguments with the info prefix
func (l *Logger) Infof(s string, a ...interface{}) {
l.Entry().TimestampIf().Level(INFO).Hooks().Msgf(s, a...)
}
// Warn prints the provided arguments with the warn prefix
func (l *Logger) Warn(a ...interface{}) {
l.Entry().TimestampIf().Level(WARN).Hooks().Msg(a...)
}
// Warnf prints the provided format string and arguments with the warn prefix
func (l *Logger) Warnf(s string, a ...interface{}) {
l.Entry().TimestampIf().Level(WARN).Hooks().Msgf(s, a...)
}
// Error prints the provided arguments with the error prefix
func (l *Logger) Error(a ...interface{}) {
l.Entry().TimestampIf().Level(ERROR).Hooks().Msg(a...)
}
// Errorf prints the provided format string and arguments with the error prefix
func (l *Logger) Errorf(s string, a ...interface{}) {
l.Entry().TimestampIf().Level(ERROR).Hooks().Msgf(s, a...)
}
// Fatal prints provided arguments with the fatal prefix before exiting the program
// with os.Exit(1)
func (l *Logger) Fatal(a ...interface{}) {
defer os.Exit(1)
l.Entry().TimestampIf().Level(FATAL).Hooks().Msg(a...)
}
// Fatalf prints provided the provided format string and arguments with the fatal prefix
// before exiting the program with os.Exit(1)
func (l *Logger) Fatalf(s string, a ...interface{}) {
defer os.Exit(1)
l.Entry().TimestampIf().Level(FATAL).Hooks().Msgf(s, a...)
}
// Log prints the provided arguments with the supplied log level
func (l *Logger) Log(lvl LEVEL, a ...interface{}) {
l.Entry().TimestampIf().Hooks().Msg(a...)
}
// Logf prints the provided format string and arguments with the supplied log level
func (l *Logger) Logf(lvl LEVEL, s string, a ...interface{}) {
l.Entry().TimestampIf().Hooks().Msgf(s, a...)
}
// Print simply prints provided arguments
func (l *Logger) Print(a ...interface{}) {
l.Entry().Hooks().Msg(a...)
}
// Printf simply prints provided the provided format string and arguments
func (l *Logger) Printf(s string, a ...interface{}) {
l.Entry().Hooks().Msgf(s, a...)
}
|