/
oldlog.go
177 lines (141 loc) · 4.31 KB
/
oldlog.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package log
import (
"errors"
"fmt"
"os"
"sync"
tracer "github.com/ipfs/go-log/tracer"
lwriter "github.com/ipfs/go-log/writer"
colorable "github.com/mattn/go-colorable"
opentrace "github.com/opentracing/opentracing-go"
logging "github.com/whyrusleeping/go-logging"
)
func init() {
SetupLogging()
}
var ansiGray = "\033[0;37m"
var ansiBlue = "\033[0;34m"
// LogFormats defines formats for logging (i.e. "color")
var LogFormats = map[string]string{
"nocolor": "%{time:2006-01-02 15:04:05.000000} %{level} %{module} %{shortfile}: %{message}",
"color": ansiGray + "%{time:15:04:05.000} %{color}%{level:5.5s} " + ansiBlue +
"%{module:10.10s}: %{color:reset}%{message} " + ansiGray + "%{shortfile}%{color:reset}",
}
var defaultLogFormat = "color"
// Logging environment variables
const (
// TODO these env names should be more general, IPFS is not the only project to
// use go-log
envLogging = "IPFS_LOGGING"
envLoggingFmt = "IPFS_LOGGING_FMT"
envLoggingFile = "GOLOG_FILE" // /path/to/file
envTracingFile = "GOLOG_TRACING_FILE" // /path/to/file
)
// ErrNoSuchLogger is returned when the util pkg is asked for a non existant logger
var ErrNoSuchLogger = errors.New("Error: No such logger")
// loggers is the set of loggers in the system
var loggerMutex sync.RWMutex
var loggers = map[string]*logging.Logger{}
// SetupLogging will initialize the logger backend and set the flags.
// TODO calling this in `init` pushes all configuration to env variables
// - move it out of `init`? then we need to change all the code (js-ipfs, go-ipfs) to call this explicitly
// - have it look for a config file? need to define what that is
func SetupLogging() {
// colorful or plain
lfmt := LogFormats[os.Getenv(envLoggingFmt)]
if lfmt == "" {
lfmt = LogFormats[defaultLogFormat]
}
// check if we log to a file
var lgbe []logging.Backend
if logfp := os.Getenv(envLoggingFile); len(logfp) > 0 {
f, err := os.Create(logfp)
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR go-log: %s: failed to set logging file backend\n", err)
} else {
lgbe = append(lgbe, logging.NewLogBackend(f, "", 0))
}
}
// logs written to stderr
lgbe = append(lgbe, logging.NewLogBackend(colorable.NewColorableStderr(), "", 0))
// set the backend(s)
logging.SetBackend(lgbe...)
logging.SetFormatter(logging.MustStringFormatter(lfmt))
lvl := logging.ERROR
if logenv := os.Getenv(envLogging); logenv != "" {
var err error
lvl, err = logging.LogLevel(logenv)
if err != nil {
fmt.Println("error setting log levels", err)
}
}
// TracerPlugins are instantiated after this, so use loggable tracer
// by default, if a TracerPlugin is added it will override this
lgblRecorder := tracer.NewLoggableRecorder()
lgblTracer := tracer.New(lgblRecorder)
opentrace.SetGlobalTracer(lgblTracer)
SetAllLoggers(lvl)
if tracingfp := os.Getenv(envTracingFile); len(tracingfp) > 0 {
f, err := os.Create(tracingfp)
if err != nil {
log.Error("failed to create tracing file: %s", tracingfp)
} else {
lwriter.WriterGroup.AddWriter(f)
}
}
}
// SetDebugLogging calls SetAllLoggers with logging.DEBUG
func SetDebugLogging() {
SetAllLoggers(logging.DEBUG)
}
// SetAllLoggers changes the logging.Level of all loggers to lvl
func SetAllLoggers(lvl logging.Level) {
logging.SetLevel(lvl, "")
loggerMutex.RLock()
defer loggerMutex.RUnlock()
for n := range loggers {
logging.SetLevel(lvl, n)
}
}
// SetLogLevel changes the log level of a specific subsystem
// name=="*" changes all subsystems
func SetLogLevel(name, level string) error {
lvl, err := logging.LogLevel(level)
if err != nil {
return err
}
// wildcard, change all
if name == "*" {
SetAllLoggers(lvl)
return nil
}
loggerMutex.RLock()
defer loggerMutex.RUnlock()
// Check if we have a logger by that name
if _, ok := loggers[name]; !ok {
return ErrNoSuchLogger
}
logging.SetLevel(lvl, name)
return nil
}
// GetSubsystems returns a slice containing the
// names of the current loggers
func GetSubsystems() []string {
loggerMutex.RLock()
defer loggerMutex.RUnlock()
subs := make([]string, 0, len(loggers))
for k := range loggers {
subs = append(subs, k)
}
return subs
}
func getLogger(name string) *logging.Logger {
loggerMutex.Lock()
defer loggerMutex.Unlock()
log := loggers[name]
if log == nil {
log = logging.MustGetLogger(name)
loggers[name] = log
}
return log
}