-
Notifications
You must be signed in to change notification settings - Fork 3
/
logger.go
255 lines (222 loc) · 5.22 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
package logger
import (
"bytes"
"encoding/json"
"fmt"
"log"
"os"
"strconv"
"sync"
"time"
)
const (
_VER string = "1.0.0"
)
type UNIT int64
const (
_ = iota
KB UNIT = 1 << (iota * 10)
MB
GB
TB
)
const (
LOG int = iota
DEBUG
INFO
WARN
ERROR
FATAL
)
const (
OS_LINUX = iota
OS_X
OS_WIN
OS_OTHERS
)
// 日志结构对象
var logObj *LogFile
var logLevel = 1
var maxFileSize int64
var maxFileCount int32
var dailyFlag bool
var consoleAppender = false
var serviceName = ""
const (
//TimeDayFormat 日期格式化到日
TimeDayFormat = "2006-01-02"
//TimeFormat 日期格式化到秒
TimeFormat = "2006-01-02 15:04:05"
//TimeFormat2 毫秒时间
TimeFormat2 = "2006-01-02T15:04:05.000"
)
var logFormat = "%s %s:%d %s %s"
var logObjFormat = "%s %s:%d %s %s %s %s"
var consoleFormat = "%s:%d %s %s"
// SetConsole 设置终端是否显示
func SetConsole(isConsole bool) {
consoleAppender = isConsole
}
// SetLevel 设置日子级别
func SetLevel(_level int) {
logLevel = _level
}
// SetServiceName 设置服务名称
func SetServiceName(name string) {
serviceName = name
}
// RollingLogger 生成按文件大小及数量分割日子类
func RollingLogger(fileDir, fileName string, maxNumber int32, maxSize int64, _unit UNIT) {
rollingLogger(fileDir, fileName, maxNumber, maxSize, _unit)
}
// SetRollingFile 生成按文件大小及数量分割日子类
func SetRollingFile(fileDir, fileName string, maxNumber int32, maxSize int64, _unit UNIT) {
rollingLogger(fileDir, fileName, maxNumber, maxSize, _unit)
}
func rollingLogger(fileDir, fileName string, maxNumber int32, maxSize int64, _unit UNIT) {
maxFileCount = maxNumber
maxFileSize = maxSize * int64(_unit)
dailyFlag = false
logObj = &LogFile{dir: fileDir, filename: fileName, mu: new(sync.Mutex)}
logObj.mu.Lock()
defer logObj.mu.Unlock()
logObj.logfile, _ = os.OpenFile(fileDir+"/"+fileName, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0777)
fi, err := logObj.logfile.Stat()
if err != nil {
log.Println(err.Error())
return
}
logObj.filesize = fi.Size()
}
// DailyLogger new按日期分割日子类
func DailyLogger(fileDir, filename string) {
dailyLogger(fileDir, filename)
}
func dailyLogger(fileDir, fileName string) {
dailyFlag = true
t, _ := time.Parse(TimeDayFormat, time.Now().Format(TimeDayFormat))
logObj = &LogFile{dir: fileDir, filename: fileName, _date: &t, mu: new(sync.Mutex)}
logObj.mu.Lock()
defer logObj.mu.Unlock()
if !logObj.isMustRename() {
var err error
logObj.logfile, err = os.OpenFile(fileDir+"/"+fileName, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0777)
if err != nil {
log.Println(err.Error())
}
} else {
logObj.rename()
}
}
func concat(delimiter string, input ...interface{}) string {
buffer := bytes.Buffer{}
l := len(input)
for i := 0; i < l; i++ {
buffer.WriteString(fmt.Sprint(input[i]))
if i < l-1 {
buffer.WriteString(delimiter)
}
}
return buffer.String()
}
func console(msg string) {
if logObj == nil || logObj.logfile == nil || consoleAppender {
log.Print(msg)
}
}
func buildJSONMessage(level int, l *LogObj, msg string) string {
file, line := getTraceFileLine()
logInfo := map[string]interface{}{
"timestamp": time.Now().Format(TimeFormat2),
"service": serviceName,
"file": file + " " + strconv.Itoa(line),
"level": getTraceLevelName(level),
"message": msg,
}
if l != nil {
logInfo["guid"] = l.Logid()
logInfo["action"] = l.GetTag()
if l.GetData() != nil {
logInfo["data"] = l.GetData()
}
}
resb, err := json.Marshal(logInfo)
if err != nil {
log.Println(err.Error())
return ""
}
return string(resb) + getOsEol()
}
func buildLogMessage(level int, l *LogObj, msg string) string {
file, line := getTraceFileLine()
logInfo := ""
if l == nil {
logInfo = fmt.Sprintf(logFormat+getOsEol(), time.Now().Format(TimeFormat), file, line, getTraceLevelName(level), msg)
} else {
logInfo = fmt.Sprintf(logObjFormat+getOsEol(), time.Now().Format(TimeFormat), file, line, l.logid, l.tag, getTraceLevelName(level), msg)
}
return logInfo
}
func catchError() {
if err := recover(); err != nil {
log.Println("err", err)
}
}
// JSON 设置日志格式
func JSON(js bool) {
if js {
logObj.SetJSON()
} else {
logObj.UnSetJSON()
}
}
// Trace write
func Trace(level int, l *LogObj, v ...interface{}) bool {
defer catchError()
if logObj != nil {
logObj.mu.Lock()
defer logObj.mu.Unlock()
}
msg := concat(" ", v...)
logStr := ""
if (logObj != nil && logObj.json) || (l != nil && l.json) {
logStr = buildJSONMessage(level, l, msg)
} else {
logStr = buildLogMessage(level, l, msg)
}
console(logStr)
if level >= logLevel && !consoleAppender {
if logObj != nil {
_, err := logObj.write([]byte(logStr))
if err != nil {
log.Println(err.Error())
return false
}
}
}
return true
}
// Log LOG
func Log(v ...interface{}) bool {
return Trace(LOG, nil, v...)
}
// Debug DEBUG
func Debug(v ...interface{}) bool {
return Trace(DEBUG, nil, v...)
}
// Info INFO
func Info(v ...interface{}) bool {
return Trace(INFO, nil, v...)
}
// Warn WARN
func Warn(v ...interface{}) bool {
return Trace(WARN, nil, v...)
}
// Error ERROR
func Error(v ...interface{}) bool {
return Trace(ERROR, nil, v...)
}
// Fatal FATAL
func Fatal(v ...interface{}) bool {
return Trace(FATAL, nil, v...)
}