/
log.go
135 lines (114 loc) · 2.38 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
package log
import (
"fmt"
"os"
"sync"
)
const (
All = iota
LevelDebug
LevelInfo
LevelWarn
LevelError
LevelFatal
Off
)
const maxChannelSize int = 1000
type Logger struct {
level int
ch chan *LogNode
asyncToFile bool // 是否异步存入文件
filename string // 存储日志的文件,默认为 ./output.log
file *os.File
fileOnce sync.Once
enableFileLog bool // 是否记录日志到日志文件
outputToConsole bool // 是否输出到标准输出
}
func New() *Logger {
l := &Logger{
level:All,
ch:make(chan *LogNode, maxChannelSize),
asyncToFile:true,
filename:"./output.log",
enableFileLog:true,
outputToConsole:true,
}
go l.run()
return l
}
func (l *Logger) SetEnableFileLog(enable bool) {
l.enableFileLog = enable
}
func (l *Logger) SetOutputToConsole(outputToConsole bool) {
l.outputToConsole = outputToConsole
}
func (l *Logger) SetFileName(filename string) {
l.filename = filename
}
func (l *Logger) SetAsyncToFile(asyncToFile bool) {
l.asyncToFile = asyncToFile
}
func (l *Logger) SetLogLevel(level int) {
l.level = level
}
func (l *Logger) createFile() {
if l.file != nil || l.filename == "" {
return
}
file, err := os.OpenFile(l.filename, os.O_APPEND|os.O_CREATE, 0664)
if err != nil {
fmt.Printf("创建日志文件失败 %s", err)
return
}
l.file = file
}
func (l *Logger) _output(logNode *LogNode) {
if l.outputToConsole {
fmt.Print(logNode)
}
if !l.enableFileLog {
return
}
l.fileOnce.Do(l.createFile)
if l.file == nil {
return
}
_, err := l.file.WriteString(logNode.String())
if err != nil {
fmt.Printf("写入日志文件失败 %s", err)
}
}
func (l *Logger) run() {
for ln := range l.ch {
l._output(ln)
}
}
func (l *Logger) output(logNode *LogNode) {
if l.level >= logNode.level {
if l.asyncToFile {
l.ch <- logNode
} else {
l._output(logNode)
}
}
}
func (l *Logger) Debug(v ...interface{}) {
logNode := newLogNode(LevelDebug, v...)
l.output(logNode)
}
func (l *Logger) Info(v ...interface{}) {
logNode := newLogNode(LevelInfo, v...)
l.output(logNode)
}
func (l *Logger) Warnning(v ...interface{}) {
logNode := newLogNode(LevelWarn, v...)
l.output(logNode)
}
func (l *Logger) Error(v ...interface{}) {
logNode := newLogNode(LevelError, v...)
l.output(logNode)
}
func (l *Logger) Fatal(v ...interface{}) {
logNode := newLogNode(LevelFatal, v...)
l.output(logNode)
}