-
Notifications
You must be signed in to change notification settings - Fork 27
/
logger.go
146 lines (125 loc) · 3.37 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package go2chef
/*
Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
*/
import (
"fmt"
"strings"
)
type ExtraLoggingFields struct {
StepName string
StepType string
StepCount int
ElapsedTime int
}
// Event provides a more structured way to log information from
// go2chef plugins.
type Event struct {
Event string
Component string
Message string
ExtraFields *ExtraLoggingFields
}
// NewEvent returns a new event using the provided parameters
func NewEventWithExtraFields(event, component, message string, extrafields *ExtraLoggingFields) *Event {
return &Event{
Event: event,
Component: component,
Message: message,
ExtraFields: extrafields,
}
}
// NewEvent returns a new event using the provided parameters
func NewEvent(event, component, message string) *Event {
return &Event{
Event: event,
Component: component,
Message: message,
}
}
// Log level constants
const (
LogLevelError = iota
LogLevelInfo
LogLevelDebug
)
// StringToLogLevel translates a string to a log level
func StringToLogLevel(s string) (int, error) {
switch strings.ToLower(s) {
case "debug":
return LogLevelDebug, nil
case "info":
return LogLevelInfo, nil
case "error":
return LogLevelError, nil
default:
return LogLevelDebug, fmt.Errorf("log level %s does not exist", s)
}
}
// LogLevelToString translates a log level value to a string
func LogLevelToString(l int) (string, error) {
switch l {
case LogLevelDebug:
return "DEBUG", nil
case LogLevelInfo:
return "INFO", nil
case LogLevelError:
return "ERROR", nil
default:
return "", fmt.Errorf("log level %d is not valid", l)
}
}
// Logger defines the interface for logging components.
type Logger interface {
Component
SetLevel(lvl int)
SetDebug(dbg int)
Debugf(dbg int, fmt string, args ...interface{})
Infof(fmt string, args ...interface{})
Errorf(fmt string, args ...interface{})
// WriteEvent writes an event object to this logger
WriteEvent(e *Event)
// Shutdown allows go2chef to wait for loggers to finish writes
// if necessary (i.e. to remote endpoints)
Shutdown()
}
// LoggerLoader defines the call signature for functions which
// return fully configured Logger instances
type LoggerLoader func(map[string]interface{}) (Logger, error)
var (
logRegistry = make(map[string]LoggerLoader)
)
// RegisterLogger registers a new logging plugin
func RegisterLogger(name string, l LoggerLoader) {
if _, ok := logRegistry[name]; ok {
panic("log plugin " + name + " is already registered")
}
logRegistry[name] = l
}
// GetLogger gets a new instance of the Logger type specified by `name` and
// returns it configured as with config map[string]interface{}
func GetLogger(name string, config map[string]interface{}) (Logger, error) {
if l, ok := logRegistry[name]; ok {
return l(config)
}
return nil, &ErrComponentDoesNotExist{Component: name}
}
// GLOBAL LOGGER FUNCTIONALITY
//
// Provide a single central point-of-logging
var globalLogger Logger
// GetGlobalLogger gets an instance of the global logger
func GetGlobalLogger() Logger {
if globalLogger == nil {
return NewMultiLogger([]Logger{})
}
return globalLogger
}
// InitGlobalLogger initializes the global logger
func InitGlobalLogger(loggers []Logger) {
globalLogger = NewMultiLogger(loggers)
}
// ShutdownGlobalLogger shuts down the global logger
func ShutdownGlobalLogger() {
globalLogger.Shutdown()
}