aboutsummaryrefslogtreecommitdiff
path: root/pkg/log/log.go
blob: 5df9aeee7e8c1d03d21d5928723b4fdb738d49b6 (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
// package log provides a simple logger with leveled log messages.
//
//   - DebugLevel (highest verbosity)
//   - InfoLevel
//   - WarningLevel
//   - ErrorLevel
//   - FatalLevel (lowest verbosity)
//
// Output is by default written to STDERR.
// A different output can be specified.
// Dates and terminal colors can be turned on.
package log

import (
	"io"
	"log"
	"os"
	"time"
)

type level int

const (
	DebugLevel   level = iota // DebugLevel logs all messages
	InfoLevel                 // InfoLevel logs info messages and and above
	WarningLevel              // WarningLevel logs warning messages and above
	ErrorLevel                // ErrorLevel logs error messages and above
	FatalLevel                // FatalLevel only logs fatal messages
)

const (
	colorDate    = "\033[37m"
	colorDebug   = "\033[95m"
	colorInfo    = "\033[94m"
	colorWarning = "\033[93m"
	colorError   = "\033[91m"
	colorFatal   = "\033[31m"
	colorReset   = "\033[0m"

	tagDebug   = "DEBU"
	tagInfo    = "INFO"
	tagWarning = "WARN"
	tagError   = "ERRO"
	tagFatal   = "FATA"
)

type logger struct {
	log.Logger		// Default writer: os.Stderr.

	lv    level		// Logging level. Default: InfoLevel.
	date  bool		// Logging dates or not: Default: true.
	color bool		// Using colors or not: Default: false.
}

var l logger

func init() {
	l = newLogger(InfoLevel, os.Stderr, true, false)
}

// SetLevel sets the logging level.  Available options: DebugLevel, InfoLevel,
// WarningLevel, ErrorLevel, FatalLevel.
func SetLevel(lv level) {
	l.lv = lv
}

// SetOutput sets the logging output to a particular writer.
func SetOutput(writer io.Writer) {
	l = newLogger(l.lv, writer, l.date, l.color)
}

// SetDate (un)sets date output.
func SetDate(ok bool) {
	l.date = ok
}

// SetColor (un)sets terminal colors.
func SetColor(ok bool) {
	l.color = ok
}

func Debug(format string, v ...interface{}) {
	if l.lv > DebugLevel {
		return
	}

	l.Printf(l.fmt(tagDebug, colorDebug)+format, v...)
}

func Info(format string, v ...interface{}) {
	if l.lv > InfoLevel {
		return
	}

	l.Printf(l.fmt(tagInfo, colorInfo)+format, v...)
}

func Warning(format string, v ...interface{}) {
	if l.lv > WarningLevel {
		return
	}

	l.Printf(l.fmt(tagWarning, colorWarning)+format, v...)
}

func Error(format string, v ...interface{}) {
	if l.lv > ErrorLevel {
		return
	}

	l.Printf(l.fmt(tagError, colorError)+format, v...)
}

func Fatal(format string, v ...interface{}) {
	l.Printf(l.fmt(tagFatal, colorFatal)+format, v...)
	os.Exit(1)
}

func newLogger(lv level, writer io.Writer, date, color bool) logger {
	return logger{
		Logger: *log.New(writer, "", 0),
		lv:     lv,
		date:   date,
		color:  color,
	}
}

func (l *logger) fmt(tag, colorTag string) string {
	date := ""
	if l.date {
		date = time.Now().Format(time.RFC1123) + " "
	}
	if l.color {
		date = colorDate + date + colorReset
		tag = colorTag + tag + colorReset
	}
	tag = "[" + tag + "] "
	return date + tag
}