-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlogger.go
132 lines (112 loc) · 3.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
package tools
import (
"fmt"
"github.com/sirupsen/logrus"
"os"
"runtime"
"strings"
"time"
)
type Logger interface {
Info(msg ...interface{})
Infof(format string, a ...interface{})
Error(msg ...interface{})
Errorf(format string, a ...interface{})
Debug(msg ...interface{})
Debugf(format string, a ...interface{})
Warn(msg ...interface{})
Warnf(format string, a ...interface{})
}
// Logger logs messages in a structured format in prod and pretty colours in local.
type logrusLogger struct {
log *logrus.Logger
fields logrus.Fields
}
// Info should be used to log key application events.
func (l *logrusLogger) Info(msg ...interface{}) {
l.log.WithFields(withFileAndLine(l.fields)).Info(msg...)
}
// Infof logs key application events with a format (like fmt)
func (l *logrusLogger) Infof(format string, a ...interface{}) {
l.Info(fmt.Sprintf(format, a...))
}
// Error should be used to log events that need to be actioned on immediately.
func (l *logrusLogger) Error(msg ...interface{}) {
l.log.WithFields(withFileAndLine(l.fields)).Error(msg...)
}
// Errorf should be used to log events that need to be actioned on immediately
func (l *logrusLogger) Errorf(format string, a ...interface{}) {
l.Error(fmt.Sprintf(format, a...))
}
// Debug can be used to log events for local development.
func (l *logrusLogger) Debug(msg ...interface{}) {
l.log.WithFields(withFileAndLine(l.fields)).Debug(msg...)
}
// Debugf can be used to log events for local development.
func (l *logrusLogger) Debugf(format string, a ...interface{}) {
l.Debug(fmt.Sprintf(format, a...))
}
// Warn is for when something bad happened but doesnt need instant action.
func (l *logrusLogger) Warn(msg ...interface{}) {
l.log.WithFields(withFileAndLine(l.fields)).Warn(msg...)
}
// Warnf is for when something bad happened but doesnt need instant action.
func (l *logrusLogger) Warnf(format string, a ...interface{}) {
l.Warn(fmt.Sprintf(format, a...))
}
func withFileAndLine(fields logrus.Fields) logrus.Fields {
newFields := make(map[string]interface{})
_, file, line, ok := runtime.Caller(2)
for k, v := range fields {
newFields[k] = v
}
if ok {
newFields["file"] = file
newFields["line"] = line
} else {
newFields["file"] = "Unknown"
newFields["line"] = "Unknown"
}
return newFields
}
// NewLogger returns a new structured logger.
func NewLogger(isLocal bool) Logger {
logger := logrus.New()
if strings.ToLower(os.Getenv("LOG_LEVEL")) == "debug" {
logger.Level = logrus.DebugLevel
}
if strings.ToLower(os.Getenv("LOG_LEVEL")) == "info" {
logger.Level = logrus.InfoLevel
}
if strings.ToLower(os.Getenv("LOG_LEVEL")) == "warn" {
logger.Level = logrus.WarnLevel
}
if !isLocal {
logger.Formatter = &logrus.JSONFormatter{
TimestampFormat: time.RFC3339Nano,
FieldMap: logrus.FieldMap{
logrus.FieldKeyTime: "timestamp",
logrus.FieldKeyMsg: "message",
},
}
}
return &logrusLogger{
log: logger,
fields: logrus.Fields{
"component": getComponentName(),
"env": getEnv(),
},
}
}
func getComponentName() string {
if name := os.Getenv("COMPONENT_NAME"); len(name) > 0 {
return name
}
return "a-service-has-no-name"
}
func getEnv() string {
if env := os.Getenv("ENV_NAME"); len(env) > 0 {
return env
}
return "local"
}