-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlogger.go
128 lines (106 loc) · 2.96 KB
/
logger.go
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
package soba
import (
"context"
"fmt"
"regexp"
)
// IsLoggerNameValid verify that a Logger name has a valid format.
var IsLoggerNameValid = regexp.MustCompile(`^[a-z]+[a-z._0-9-]+[a-z0-9]+$`).MatchString
// A Logger provides fast, leveled, structured logging.
// All methods are safe for concurrent use.
type Logger struct {
name string
level Level
appenders []Appender
fields []Field
}
// New creates a new Logger using given name.
func New(ctx context.Context, name string) Logger {
val := ctx.Value(hCtxKey)
if val == nil {
panic("soba: must be initialized with soba.Load()")
}
handler, ok := val.(Handler)
if !ok {
panic("soba: must be initialized with soba.Load()")
}
return handler.New(name)
}
// NewLogger creates a new logger.
func NewLogger(name string, level Level, appenders []Appender) Logger {
if !IsLoggerNameValid(name) {
panic(fmt.Sprintf("soba: invalid logger name format: %s", name))
}
return Logger{
name: name,
level: level,
appenders: appenders,
fields: make([]Field, 0, 64),
}
}
// Name returns logger name.
func (logger Logger) Name() string {
return logger.name
}
// Level returns logger level.
func (logger Logger) Level() Level {
return logger.level
}
// Debug logs a message at DebugLevel.
func (logger Logger) Debug(message string, fields ...Field) {
if logger.level < DebugLevel || logger.level == NoLevel {
return
}
logger.write(DebugLevel, message, fields)
}
// Info logs a message at InfoLevel.
func (logger Logger) Info(message string, fields ...Field) {
if logger.level < InfoLevel || logger.level == NoLevel {
return
}
logger.write(InfoLevel, message, fields)
}
// Warn logs a message at WarnLevel.
func (logger Logger) Warn(message string, fields ...Field) {
if logger.level < WarnLevel || logger.level == NoLevel {
return
}
logger.write(WarnLevel, message, fields)
}
// Error logs a message at ErrorLevel.
func (logger Logger) Error(message string, fields ...Field) {
if logger.level < ErrorLevel || logger.level == NoLevel {
return
}
logger.write(ErrorLevel, message, fields)
}
// With appends given structured fields to it.
func (logger Logger) With(fields ...Field) Logger {
other := logger.copy()
other.fields = append(other.fields, fields...)
return other
}
func (logger Logger) write(level Level, message string, fields []Field) {
entry := NewEntry(logger.name, level, message, logger.fields, fields)
defer entry.Flush()
for i := range logger.appenders {
logger.appenders[i].Write(entry)
}
}
func (logger Logger) copyWithName(name string) Logger {
if !IsLoggerNameValid(name) {
panic(fmt.Sprintf("soba: invalid logger name format: %s", name))
}
other := logger.copy()
other.name = name
return other
}
func (logger Logger) copy() Logger {
other := Logger{}
other.name = logger.name
other.level = logger.level
other.appenders = logger.appenders
other.fields = make([]Field, len(logger.fields), cap(logger.fields))
copy(other.fields, logger.fields)
return other
}