188 lines
5.1 KiB
Go
188 lines
5.1 KiB
Go
package logger
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"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, DefaultTextFormat, 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,
|
|
}
|
|
|
|
// 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 {
|
|
entry, _ := l.pool.Get().(*Entry)
|
|
entry.ctx = context.Background()
|
|
return entry
|
|
}
|
|
|
|
// Debug prints the provided arguments with the debug prefix
|
|
func (l *Logger) Debug(a ...interface{}) {
|
|
l.Log(DEBUG, a...)
|
|
}
|
|
|
|
// Debugf prints the provided format string and arguments with the debug prefix
|
|
func (l *Logger) Debugf(s string, a ...interface{}) {
|
|
l.Logf(DEBUG, s, a...)
|
|
}
|
|
|
|
// Info prints the provided arguments with the info prefix
|
|
func (l *Logger) Info(a ...interface{}) {
|
|
l.Log(INFO, a...)
|
|
}
|
|
|
|
// Infof prints the provided format string and arguments with the info prefix
|
|
func (l *Logger) Infof(s string, a ...interface{}) {
|
|
l.Logf(INFO, s, a...)
|
|
}
|
|
|
|
// Warn prints the provided arguments with the warn prefix
|
|
func (l *Logger) Warn(a ...interface{}) {
|
|
l.Log(WARN, a...)
|
|
}
|
|
|
|
// Warnf prints the provided format string and arguments with the warn prefix
|
|
func (l *Logger) Warnf(s string, a ...interface{}) {
|
|
l.Logf(WARN, s, a...)
|
|
}
|
|
|
|
// Error prints the provided arguments with the error prefix
|
|
func (l *Logger) Error(a ...interface{}) {
|
|
l.Log(ERROR, a...)
|
|
}
|
|
|
|
// Errorf prints the provided format string and arguments with the error prefix
|
|
func (l *Logger) Errorf(s string, a ...interface{}) {
|
|
l.Logf(ERROR, 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.Log(FATAL, 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.Logf(FATAL, s, a...)
|
|
}
|
|
|
|
// Log prints the provided arguments at the supplied log level
|
|
func (l *Logger) Log(lvl LEVEL, a ...interface{}) {
|
|
if lvl >= l.Level {
|
|
l.Entry().TimestampIf().Level(lvl).Hooks().Msg(a...)
|
|
}
|
|
}
|
|
|
|
// Logf prints the provided format string and arguments at the supplied log level
|
|
func (l *Logger) Logf(lvl LEVEL, s string, a ...interface{}) {
|
|
if lvl >= l.Level {
|
|
l.Entry().TimestampIf().Level(lvl).Hooks().Msgf(s, a...)
|
|
}
|
|
}
|
|
|
|
// LogFields prints the provided fields formatted as key-value pairs at the supplied log level
|
|
func (l *Logger) LogFields(lvl LEVEL, fields map[string]interface{}) {
|
|
if lvl >= l.Level {
|
|
l.Entry().TimestampIf().Level(lvl).Fields(fields).Hooks().Send()
|
|
}
|
|
}
|
|
|
|
// LogValues prints the provided values formatted as-so at the supplied log level
|
|
func (l *Logger) LogValues(lvl LEVEL, a ...interface{}) {
|
|
if lvl >= l.Level {
|
|
l.Entry().TimestampIf().Level(lvl).Values(a...).Hooks().Send()
|
|
}
|
|
}
|
|
|
|
// Print simply prints provided arguments
|
|
func (l *Logger) Print(a ...interface{}) {
|
|
e := l.Entry().TimestampIf()
|
|
fmt.Fprint(e.buf, a...)
|
|
e.Send()
|
|
}
|
|
|
|
// Printf simply prints provided the provided format string and arguments
|
|
func (l *Logger) Printf(s string, a ...interface{}) {
|
|
e := l.Entry().TimestampIf()
|
|
fmt.Fprintf(e.buf, s, a...)
|
|
e.Send()
|
|
}
|
|
|
|
// PrintFields prints the provided fields formatted as key-value pairs
|
|
func (l *Logger) PrintFields(fields map[string]interface{}) {
|
|
l.Entry().TimestampIf().Fields(fields).Send()
|
|
}
|
|
|
|
// PrintValues prints the provided values formatted as-so
|
|
func (l *Logger) PrintValues(a ...interface{}) {
|
|
l.Entry().TimestampIf().Values(a...).Send()
|
|
}
|