forked from naoina/kocha
-
Notifications
You must be signed in to change notification settings - Fork 0
/
log.go
149 lines (126 loc) · 3 KB
/
log.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package kocha
import (
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
)
const (
defaultLflag = log.Ldate | log.Ltime
)
func initLogger(logger *Logger) *Logger {
if logger == nil {
logger = &Logger{}
}
if logger.DEBUG == nil {
logger.DEBUG = Loggers{NullLogger()}
}
if logger.INFO == nil {
logger.INFO = Loggers{NullLogger()}
}
if logger.WARN == nil {
logger.WARN = Loggers{NullLogger()}
}
if logger.ERROR == nil {
logger.ERROR = Loggers{NullLogger()}
}
setPrefix := func(loggers Loggers, prefix string) {
for _, logger := range loggers {
logger.SetPrefix(prefix)
}
}
setPrefix(logger.DEBUG, "[DEBUG] ")
setPrefix(logger.INFO, "[INFO] ")
setPrefix(logger.WARN, "[WARN] ")
setPrefix(logger.ERROR, "[ERROR] ")
return logger
}
// logger is the interface that logger.
type logger interface {
Output(calldepth int, s string) error
SetPrefix(prefix string)
GoString() string
}
type nullLogger struct {
*log.Logger
}
func (l *nullLogger) GoString() string {
return "kocha.NullLogger()"
}
// NullLogger returns a new null logger.
func NullLogger() logger {
return &nullLogger{log.New(ioutil.Discard, "", 0)}
}
type consoleLogger struct {
*log.Logger
}
func (l *consoleLogger) GoString() string {
return fmt.Sprintf("kocha.ConsoleLogger(%d)", l.Flags())
}
// ConsoleLogger returns a new console logger.
func ConsoleLogger(flag int) logger {
if flag == -1 {
flag = defaultLflag
}
return &consoleLogger{log.New(os.Stdout, "", flag)}
}
type fileLogger struct {
*log.Logger
path string
}
func (l *fileLogger) GoString() string {
return fmt.Sprintf("kocha.FileLogger(%q, %d)", l.path, l.Flags())
}
// FileLogger returns a new file logger that writes to path.
func FileLogger(path string, flag int) logger {
if flag == -1 {
flag = defaultLflag
}
path, err := filepath.Abs(path)
if err != nil {
panic(err)
}
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
panic(err)
}
file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
panic(err)
}
return &fileLogger{log.New(file, "", flag), path}
}
type Loggers []logger
// Collection of builtin loggers.
type Logger struct {
// Loggers for debug.
DEBUG Loggers
// Loggers for info.
INFO Loggers
// Loggers for warning.
WARN Loggers
// Loggers for error.
ERROR Loggers
}
// Debug prints the log using DEBUG loggers.
func (l *Logger) Debug(format string, v ...interface{}) {
l.output(l.DEBUG, format, v...)
}
// Info prints the log using INFO loggers.
func (l *Logger) Info(format string, v ...interface{}) {
l.output(l.INFO, format, v...)
}
// Warn prints the log using WARN loggers.
func (l *Logger) Warn(format string, v ...interface{}) {
l.output(l.WARN, format, v...)
}
// Error prints the log using ERROR loggers.
func (l *Logger) Error(format string, v ...interface{}) {
l.output(l.ERROR, format, v...)
}
func (l *Logger) output(loggers Loggers, format string, v ...interface{}) {
output := fmt.Sprintf(format+"\n", v...)
for _, logger := range loggers {
logger.Output(2, output)
}
}