aboutsummaryrefslogtreecommitdiff
path: root/log/logger.go
blob: 2ece5f322917e4277722670fb6de0b6dd31690ec (plain)
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
package log

import (
	"fmt"
	"io"
	"log"
	"os"
	"strings"
)

type LogLevel int

const (
	TRACE LogLevel = 5
	DEBUG LogLevel = 10
	INFO  LogLevel = 20
	WARN  LogLevel = 30
	ERROR LogLevel = 40
)

var (
	trace    *log.Logger
	dbg      *log.Logger
	info     *log.Logger
	warn     *log.Logger
	err      *log.Logger
	minLevel LogLevel = TRACE
)

func Init(file *os.File, level LogLevel) {
	minLevel = level
	flags := log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile
	if file != nil {
		trace = log.New(file, "TRACE ", flags)
		dbg = log.New(file, "DEBUG ", flags)
		info = log.New(file, "INFO  ", flags)
		warn = log.New(file, "WARN  ", flags)
		err = log.New(file, "ERROR ", flags)
	}
}

func ParseLevel(value string) (LogLevel, error) {
	switch strings.ToLower(value) {
	case "trace":
		return TRACE, nil
	case "debug":
		return DEBUG, nil
	case "info":
		return INFO, nil
	case "warn", "warning":
		return WARN, nil
	case "err", "error":
		return ERROR, nil
	}
	return 0, fmt.Errorf("%s: invalid log level", value)
}

func ErrorLogger() *log.Logger {
	if err == nil {
		return log.New(io.Discard, "", log.LstdFlags)
	}
	return err
}

type Logger interface {
	Tracef(string, ...interface{})
	Debugf(string, ...interface{})
	Infof(string, ...interface{})
	Warnf(string, ...interface{})
	Errorf(string, ...interface{})
}

type logger struct {
	name      string
	calldepth int
}

func NewLogger(name string, calldepth int) Logger {
	return &logger{name: name, calldepth: calldepth}
}

func (l *logger) format(message string, args ...interface{}) string {
	if len(args) > 0 {
		message = fmt.Sprintf(message, args...)
	}
	if l.name != "" {
		message = fmt.Sprintf("[%s] %s", l.name, message)
	}
	return message
}

func (l *logger) Tracef(message string, args ...interface{}) {
	if trace == nil || minLevel > TRACE {
		return
	}
	message = l.format(message, args...)
	trace.Output(l.calldepth, message) //nolint:errcheck // we can't do anything with what we log
}

func (l *logger) Debugf(message string, args ...interface{}) {
	if dbg == nil || minLevel > DEBUG {
		return
	}
	message = l.format(message, args...)
	dbg.Output(l.calldepth, message) //nolint:errcheck // we can't do anything with what we log
}

func (l *logger) Infof(message string, args ...interface{}) {
	if info == nil || minLevel > INFO {
		return
	}
	message = l.format(message, args...)
	info.Output(l.calldepth, message) //nolint:errcheck // we can't do anything with what we log
}

func (l *logger) Warnf(message string, args ...interface{}) {
	if warn == nil || minLevel > WARN {
		return
	}
	message = l.format(message, args...)
	warn.Output(l.calldepth, message) //nolint:errcheck // we can't do anything with what we log
}

func (l *logger) Errorf(message string, args ...interface{}) {
	if err == nil || minLevel > ERROR {
		return
	}
	message = l.format(message, args...)
	err.Output(l.calldepth, message) //nolint:errcheck // we can't do anything with what we log
}

var root = logger{calldepth: 3}

func Tracef(message string, args ...interface{}) {
	root.Tracef(message, args...)
}

func Debugf(message string, args ...interface{}) {
	root.Debugf(message, args...)
}

func Infof(message string, args ...interface{}) {
	root.Infof(message, args...)
}

func Warnf(message string, args ...interface{}) {
	root.Warnf(message, args...)
}

func Errorf(message string, args ...interface{}) {
	root.Errorf(message, args...)
}