FILE / ScuroNeko/SNekLog
logger.go
Исходный файл и его история в репозитории.
Golang lint / lint (push) Successful in 1m36s
- add threshold-aware LogLevel constructors - add Logger.SetThresholdMode and SameThreshold - preserve legacy SameLevel behavior for compatibility - extend tests for threshold mode and compatibility - update README and release notes for v2.2.0
186 lines
4.9 KiB
Go
186 lines
4.9 KiB
Go
package sneklog
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
)
|
|
|
|
// MethodTraceback describes a single stack frame attached to a log entry.
|
|
type MethodTraceback struct {
|
|
Method string `json:"method"`
|
|
Filename string `json:"filename"`
|
|
Line int `json:"line"`
|
|
Signature string `json:"signature"`
|
|
FullPath string `json:"fullPath"`
|
|
}
|
|
|
|
// Logger routes log records to one or more configured writers.
|
|
type Logger struct {
|
|
prefix string
|
|
level LogLevel
|
|
|
|
writers []LoggerWriter
|
|
replacers []replacer
|
|
|
|
jsonPretty bool
|
|
threshold bool
|
|
}
|
|
|
|
// CreateLogger creates a logger with default settings.
|
|
// Deprecated: use NewLogger. This method will be removed in v3.
|
|
func CreateLogger() *Logger {
|
|
return &Logger{
|
|
prefix: "LOG",
|
|
level: FATAL,
|
|
}
|
|
}
|
|
|
|
// NewLogger creates a logger with default settings.
|
|
func NewLogger() *Logger {
|
|
return &Logger{
|
|
prefix: "LOG",
|
|
level: FATAL,
|
|
}
|
|
}
|
|
|
|
// Prefix sets the record prefix and returns the logger for chaining.
|
|
// Deprecated: use SetName. This method will be removed in v3.
|
|
func (l *Logger) Prefix(prefix string) *Logger {
|
|
l.prefix = prefix
|
|
return l
|
|
}
|
|
|
|
// SetName sets the record prefix and returns the logger for chaining.
|
|
func (l *Logger) SetName(name string) *Logger {
|
|
l.prefix = name
|
|
return l
|
|
}
|
|
|
|
// Level sets the maximum enabled level and returns the logger for chaining.
|
|
// Deprecated: use SetLevel. This method will be removed in v3.
|
|
func (l *Logger) Level(level LogLevel) *Logger {
|
|
l.level = level
|
|
return l
|
|
}
|
|
|
|
// SetLevel sets the maximum enabled level and returns the logger for chaining.
|
|
func (l *Logger) SetLevel(level LogLevel) *Logger {
|
|
l.level = level
|
|
return l
|
|
}
|
|
|
|
// JsonPretty enables or disables indented JSON output for JSON writers created by the logger.
|
|
// Deprecated: use SetJSONPretty. This method will be removed in v3.
|
|
func (l *Logger) JsonPretty(b bool) *Logger {
|
|
l.jsonPretty = b
|
|
return l
|
|
}
|
|
|
|
// SetJSONPretty enables or disables indented output for JSON writers created by the logger.
|
|
func (l *Logger) SetJSONPretty(b bool) *Logger {
|
|
l.jsonPretty = b
|
|
return l
|
|
}
|
|
|
|
// SetThresholdMode switches Logger.Print filtering from legacy severity-index
|
|
// ordering to LogLevel threshold ordering.
|
|
func (l *Logger) SetThresholdMode(b bool) *Logger {
|
|
l.threshold = b
|
|
return l
|
|
}
|
|
|
|
// AddWriters appends multiple writers to the logger.
|
|
func (l *Logger) AddWriters(writers ...LoggerWriter) *Logger {
|
|
l.writers = append(l.writers, writers...)
|
|
return l
|
|
}
|
|
|
|
// AddWriter appends a single writer to the logger.
|
|
// Deprecated: use AddWriters. This method will be removed in v3.
|
|
func (l *Logger) AddWriter(writer LoggerWriter) *Logger {
|
|
l.writers = append(l.writers, writer)
|
|
return l
|
|
}
|
|
|
|
// AddReplacer appends a message replacer and returns the logger for chaining.
|
|
//
|
|
// Replacement rules are applied before records are passed to writers. Empty old
|
|
// values are ignored because replacing an empty string would insert the
|
|
// replacement between every UTF-8 sequence.
|
|
func (l *Logger) AddReplacer(old, new string) *Logger {
|
|
if old == "" {
|
|
return l
|
|
}
|
|
r := replacer{old: old, new: new}
|
|
l.replacers = append(l.replacers, r)
|
|
return l
|
|
}
|
|
|
|
// Close closes all owned writers and returns a joined error, if any.
|
|
func (l *Logger) Close() error {
|
|
var errs []error
|
|
for _, writer := range l.writers {
|
|
if writer == nil {
|
|
continue
|
|
}
|
|
err := writer.Close()
|
|
if err != nil {
|
|
errs = append(errs, err)
|
|
}
|
|
}
|
|
l.writers = nil
|
|
return errors.Join(errs...)
|
|
}
|
|
|
|
// CreateTextWriter wraps an external writer with the logger text settings.
|
|
func (l *Logger) CreateTextWriter(w io.Writer) *LoggerTextWriter { return CreateTextWriter(w) }
|
|
|
|
// CreateTextStdoutWriter creates a non-owning text writer for os.Stdout.
|
|
func (l *Logger) CreateTextStdoutWriter() *LoggerTextWriter { return CreateTextStdoutWriter() }
|
|
|
|
// CreateTextFileWriter creates an owning text writer for a file.
|
|
func (l *Logger) CreateTextFileWriter(filename string) (*LoggerTextWriter, error) {
|
|
return CreateTextFileWriter(filename)
|
|
}
|
|
|
|
// CreateJsonWriter wraps an external writer with the logger JSON settings.
|
|
func (l *Logger) CreateJsonWriter(w io.Writer) *LoggerJsonWriter {
|
|
return CreateJsonWriter(w, l.jsonPretty)
|
|
}
|
|
|
|
// CreateJsonStdoutWriter creates a non-owning JSON writer for os.Stdout.
|
|
func (l *Logger) CreateJsonStdoutWriter() *LoggerJsonWriter {
|
|
return CreateJsonStdoutWriter(l.jsonPretty)
|
|
}
|
|
|
|
// CreateJsonFileWriter creates an owning JSON writer for a file.
|
|
func (l *Logger) CreateJsonFileWriter(filename string) (*LoggerJsonWriter, error) {
|
|
return CreateJsonFileWriter(filename, l.jsonPretty)
|
|
}
|
|
|
|
type replacer struct {
|
|
old string
|
|
new string
|
|
}
|
|
|
|
func (r replacer) replace(s string) string { return strings.ReplaceAll(s, r.old, r.new) }
|
|
func (l *Logger) replace(s string) string {
|
|
out := s
|
|
for _, repl := range l.replacers {
|
|
out = repl.replace(out)
|
|
}
|
|
return out
|
|
}
|
|
func (l *Logger) replaceAll(messages ...any) []any {
|
|
if len(l.replacers) == 0 {
|
|
return messages
|
|
}
|
|
out := make([]any, len(messages))
|
|
for i, msg := range messages {
|
|
out[i] = l.replace(fmt.Sprint(msg))
|
|
}
|
|
return out
|
|
}
|