15 "github.com/mattn/go-isatty"
16 "github.com/valyala/fasttemplate"
18 "github.com/labstack/gommon/color"
27 template *fasttemplate.Template
36 JSON map[string]interface{}
51 defaultHeader = `{"time":"${time_rfc3339_nano}","level":"${level}","prefix":"${prefix}",` +
52 `"file":"${short_file}","line":"${line}"}`
59 func New(prefix string) (l *Logger) {
64 template: l.newTemplate(defaultHeader),
66 bufferPool: sync.Pool{
67 New: func() interface{} {
68 return bytes.NewBuffer(make([]byte, 256))
77 func (l *Logger) initLevels() {
80 l.color.Blue("DEBUG"),
81 l.color.Green("INFO"),
82 l.color.Yellow("WARN"),
85 l.color.Yellow("PANIC", color.U),
86 l.color.Red("FATAL", color.U),
90 func (l *Logger) newTemplate(format string) *fasttemplate.Template {
91 return fasttemplate.New(format, "${", "}")
94 func (l *Logger) DisableColor() {
99 func (l *Logger) EnableColor() {
104 func (l *Logger) Prefix() string {
108 func (l *Logger) SetPrefix(p string) {
112 func (l *Logger) Level() Lvl {
116 func (l *Logger) SetLevel(v Lvl) {
120 func (l *Logger) Output() io.Writer {
124 func (l *Logger) SetOutput(w io.Writer) {
126 if w, ok := w.(*os.File); !ok || !isatty.IsTerminal(w.Fd()) {
131 func (l *Logger) Color() *color.Color {
135 func (l *Logger) SetHeader(h string) {
136 l.template = l.newTemplate(h)
139 func (l *Logger) Print(i ...interface{}) {
141 // fmt.Fprintln(l.output, i...)
144 func (l *Logger) Printf(format string, args ...interface{}) {
145 l.log(0, format, args...)
148 func (l *Logger) Printj(j JSON) {
152 func (l *Logger) Debug(i ...interface{}) {
153 l.log(DEBUG, "", i...)
156 func (l *Logger) Debugf(format string, args ...interface{}) {
157 l.log(DEBUG, format, args...)
160 func (l *Logger) Debugj(j JSON) {
161 l.log(DEBUG, "json", j)
164 func (l *Logger) Info(i ...interface{}) {
165 l.log(INFO, "", i...)
168 func (l *Logger) Infof(format string, args ...interface{}) {
169 l.log(INFO, format, args...)
172 func (l *Logger) Infoj(j JSON) {
173 l.log(INFO, "json", j)
176 func (l *Logger) Warn(i ...interface{}) {
177 l.log(WARN, "", i...)
180 func (l *Logger) Warnf(format string, args ...interface{}) {
181 l.log(WARN, format, args...)
184 func (l *Logger) Warnj(j JSON) {
185 l.log(WARN, "json", j)
188 func (l *Logger) Error(i ...interface{}) {
189 l.log(ERROR, "", i...)
192 func (l *Logger) Errorf(format string, args ...interface{}) {
193 l.log(ERROR, format, args...)
196 func (l *Logger) Errorj(j JSON) {
197 l.log(ERROR, "json", j)
200 func (l *Logger) Fatal(i ...interface{}) {
201 l.log(fatalLevel, "", i...)
205 func (l *Logger) Fatalf(format string, args ...interface{}) {
206 l.log(fatalLevel, format, args...)
210 func (l *Logger) Fatalj(j JSON) {
211 l.log(fatalLevel, "json", j)
215 func (l *Logger) Panic(i ...interface{}) {
216 l.log(panicLevel, "", i...)
217 panic(fmt.Sprint(i...))
220 func (l *Logger) Panicf(format string, args ...interface{}) {
221 l.log(panicLevel, format, args...)
222 panic(fmt.Sprintf(format, args...))
225 func (l *Logger) Panicj(j JSON) {
226 l.log(panicLevel, "json", j)
230 func DisableColor() {
231 global.DisableColor()
238 func Prefix() string {
239 return global.Prefix()
242 func SetPrefix(p string) {
247 return global.Level()
250 func SetLevel(v Lvl) {
254 func Output() io.Writer {
255 return global.Output()
258 func SetOutput(w io.Writer) {
262 func SetHeader(h string) {
266 func Print(i ...interface{}) {
270 func Printf(format string, args ...interface{}) {
271 global.Printf(format, args...)
274 func Printj(j JSON) {
278 func Debug(i ...interface{}) {
282 func Debugf(format string, args ...interface{}) {
283 global.Debugf(format, args...)
286 func Debugj(j JSON) {
290 func Info(i ...interface{}) {
294 func Infof(format string, args ...interface{}) {
295 global.Infof(format, args...)
302 func Warn(i ...interface{}) {
306 func Warnf(format string, args ...interface{}) {
307 global.Warnf(format, args...)
314 func Error(i ...interface{}) {
318 func Errorf(format string, args ...interface{}) {
319 global.Errorf(format, args...)
322 func Errorj(j JSON) {
326 func Fatal(i ...interface{}) {
330 func Fatalf(format string, args ...interface{}) {
331 global.Fatalf(format, args...)
334 func Fatalj(j JSON) {
338 func Panic(i ...interface{}) {
342 func Panicf(format string, args ...interface{}) {
343 global.Panicf(format, args...)
346 func Panicj(j JSON) {
350 func (l *Logger) log(v Lvl, format string, args ...interface{}) {
352 defer l.mutex.Unlock()
353 buf := l.bufferPool.Get().(*bytes.Buffer)
355 defer l.bufferPool.Put(buf)
356 _, file, line, _ := runtime.Caller(l.skip)
358 if v >= l.level || v == 0 {
361 message = fmt.Sprint(args...)
362 } else if format == "json" {
363 b, err := json.Marshal(args[0])
369 message = fmt.Sprintf(format, args...)
372 _, err := l.template.ExecuteFunc(buf, func(w io.Writer, tag string) (int, error) {
375 return w.Write([]byte(time.Now().Format(time.RFC3339)))
376 case "time_rfc3339_nano":
377 return w.Write([]byte(time.Now().Format(time.RFC3339Nano)))
379 return w.Write([]byte(l.levels[v]))
381 return w.Write([]byte(l.prefix))
383 return w.Write([]byte(file))
385 return w.Write([]byte(path.Base(file)))
387 return w.Write([]byte(strconv.Itoa(line)))
399 if format == "json" {
400 buf.WriteString(message[1:])
402 buf.WriteString(`"message":`)
403 buf.WriteString(strconv.Quote(message))
409 buf.WriteString(message)
412 l.output.Write(buf.Bytes())