util.go raw
1 /*
2 * Copyright 2017 Baidu, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11 * either express or implied. See the License for the specific language governing permissions
12 * and limitations under the License.
13 */
14
15 // util.go - define the package-level default logger and functions for easily use.
16
17 package log
18
19 import (
20 "fmt"
21 "os"
22 "strconv"
23 "strings"
24 )
25
26 // The global default logger object to perform logging in this package-level functions
27 var gDefaultLogger *logger
28
29 func init() {
30 gDefaultLogger = NewLogger()
31 }
32
33 // Helper functions
34 func getFileInfo(path string) (int64, bool) {
35 info, err := os.Stat(path)
36 if err != nil {
37 return -1, false
38 } else {
39 return info.Size(), true
40 }
41 }
42
43 func getSizeString(size int64) string {
44 if size < 0 {
45 return fmt.Sprintf("%d", size)
46 }
47 if size < (1 << 10) {
48 return fmt.Sprintf("%dB", size)
49 } else if size < (1 << 20) {
50 return fmt.Sprintf("%dkB", size>>10)
51 } else if size < (1 << 30) {
52 return fmt.Sprintf("%dMB", size>>20)
53 } else if size < (1 << 40) {
54 return fmt.Sprintf("%dGB", size>>30)
55 } else {
56 return "SUPER-LARGE"
57 }
58 }
59
60 func getNextFileName(nowFileName string) string {
61 pos1 := strings.Index(nowFileName, ".")
62 rest := nowFileName[pos1+1:]
63 pos2 := strings.Index(rest, ".")
64 num, _ := strconv.Atoi(rest[0:pos2])
65 return fmt.Sprintf("%s.%d.log", nowFileName[0:pos1], num+1)
66 }
67
68 func concat(msg ...interface{}) string {
69 buf := make([]string, 0, len(msg))
70 for _, m := range msg {
71 buf = append(buf, fmt.Sprintf("%v", m))
72 }
73 return strings.Join(buf, " ")
74 }
75
76 // Export package-level functions for logging messages by using the default logger. It supports 3
77 // kinds of interface which is similar to the standard package "fmt": with suffix of "ln", "f" or
78 // nothing.
79 func Debug(msg ...interface{}) {
80 gDefaultLogger.logging(DEBUG, "%s\n", concat(msg...))
81 }
82
83 func Debugln(msg ...interface{}) {
84 gDefaultLogger.logging(DEBUG, "%s\n", concat(msg...))
85 }
86
87 func Debugf(format string, msg ...interface{}) {
88 gDefaultLogger.logging(DEBUG, format+"\n", msg...)
89 }
90
91 func Info(msg ...interface{}) {
92 gDefaultLogger.logging(INFO, "%s\n", concat(msg...))
93 }
94
95 func Infoln(msg ...interface{}) {
96 gDefaultLogger.logging(INFO, "%s\n", concat(msg...))
97 }
98
99 func Infof(format string, msg ...interface{}) {
100 gDefaultLogger.logging(INFO, format+"\n", msg...)
101 }
102
103 func Warn(msg ...interface{}) {
104 gDefaultLogger.logging(WARN, "%s\n", concat(msg...))
105 }
106
107 func Warnln(msg ...interface{}) {
108 gDefaultLogger.logging(WARN, "%s\n", concat(msg...))
109 }
110
111 func Warnf(format string, msg ...interface{}) {
112 gDefaultLogger.logging(WARN, format+"\n", msg...)
113 }
114
115 func Error(msg ...interface{}) {
116 gDefaultLogger.logging(ERROR, "%s\n", concat(msg...))
117 }
118
119 func Errorln(msg ...interface{}) {
120 gDefaultLogger.logging(ERROR, "%s\n", concat(msg...))
121 }
122
123 func Errorf(format string, msg ...interface{}) {
124 gDefaultLogger.logging(ERROR, format+"\n", msg...)
125 }
126
127 func Fatal(msg ...interface{}) {
128 gDefaultLogger.logging(FATAL, "%s\n", concat(msg...))
129 }
130
131 func Fatalln(msg ...interface{}) {
132 gDefaultLogger.logging(FATAL, "%s\n", concat(msg...))
133 }
134
135 func Fatalf(format string, msg ...interface{}) {
136 gDefaultLogger.logging(FATAL, format+"\n", msg...)
137 }
138
139 func Panic(msg ...interface{}) {
140 record := concat(msg...)
141 gDefaultLogger.logging(PANIC, "%s\n", record)
142 panic(record)
143 }
144
145 func Panicln(msg ...interface{}) {
146 record := concat(msg...)
147 gDefaultLogger.logging(PANIC, "%s\n", record)
148 panic(record)
149 }
150
151 func Panicf(format string, msg ...interface{}) {
152 record := fmt.Sprintf(format, msg...)
153 gDefaultLogger.logging(PANIC, format+"\n", msg...)
154 panic(record)
155 }
156
157 func Close() {
158 gDefaultLogger.Close()
159 }
160
161 // SetLogHandler - set the handler of the logger
162 //
163 // PARAMS:
164 // - Handler: the handler defined in this package, now just support STDOUT, STDERR, FILE
165 func SetLogHandler(h Handler) {
166 gDefaultLogger.handler = h
167 }
168
169 // SetLogLevel - set the level threshold of the logger, only level equal to or bigger than this
170 // value will be logged.
171 //
172 // PARAMS:
173 // - Level: the level defined in this package, now support 6 levels.
174 func SetLogLevel(l Level) {
175 gDefaultLogger.levelThreshold = l
176 }
177
178 // SetLogFormat - set the log component of each record when logging it. The default log format is
179 // {FMT_LEVEL, FMT_LTIME, FMT_LOCATION, FMT_MSG}.
180 //
181 // PARAMS:
182 // - format: the format component array.
183 func SetLogFormat(format []string) {
184 gDefaultLogger.logFormat = format
185 }
186
187 // SetLogDir - set the logging directory if logging to file.
188 //
189 // PARAMS:
190 // - dir: the logging directory
191 // RETURNS:
192 // - error: check the directory and try to make it, otherwise return the error.
193 func SetLogDir(dir string) error {
194 if _, err := os.Stat(dir); err != nil {
195 if os.IsNotExist(err) {
196 if mkErr := os.Mkdir(dir, os.ModePerm); mkErr != nil {
197 return mkErr
198 }
199 } else {
200 return err
201 }
202 }
203 gDefaultLogger.logDir = dir
204 return nil
205 }
206
207 // SetRotateType - set the rotating strategy if logging to file.
208 //
209 // PARAMS:
210 // - RotateStrategy: the rotate strategy defined in this package, now support 5 strategy.
211 func SetRotateType(r RotateStrategy) {
212 gDefaultLogger.rotateType = r
213 }
214
215 // SetRotateSize - set the rotating size if logging to file and set the strategy of size.
216 //
217 // PARAMS:
218 // - size: the rotating size
219 // RETURNS:
220 // - error: check the value and return any error if error occurs.
221 func SetRotateSize(size int64) error {
222 if size <= 0 {
223 return fmt.Errorf("%s", "rotate size should not be negative")
224 }
225 gDefaultLogger.rotateSize = size
226 return nil
227 }
228