blob: ced6e0ce93a9172bc52f4d248fc292bbfef37a63 [file] [log] [blame]
Girish Gowdra631ef3d2020-06-15 10:45:52 -07001// Copyright (c) 2017 Uber Technologies, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package log
16
17import (
18 "bytes"
19 "fmt"
20 "log"
21 "sync"
22)
23
24// Logger provides an abstract interface for logging from Reporters.
25// Applications can provide their own implementation of this interface to adapt
26// reporters logging to whatever logging library they prefer (stdlib log,
27// logrus, go-logging, etc).
28type Logger interface {
29 // Error logs a message at error priority
30 Error(msg string)
31
32 // Infof logs a message at info priority
33 Infof(msg string, args ...interface{})
34}
35
36// StdLogger is implementation of the Logger interface that delegates to default `log` package
37var StdLogger = &stdLogger{}
38
39type stdLogger struct{}
40
41func (l *stdLogger) Error(msg string) {
42 log.Printf("ERROR: %s", msg)
43}
44
45// Infof logs a message at info priority
46func (l *stdLogger) Infof(msg string, args ...interface{}) {
47 log.Printf(msg, args...)
48}
49
50// Debugf logs a message at debug priority
51func (l *stdLogger) Debugf(msg string, args ...interface{}) {
52 log.Printf(fmt.Sprintf("DEBUG: %s", msg), args...)
53}
54
55// NullLogger is implementation of the Logger interface that is no-op
56var NullLogger = &nullLogger{}
57
58type nullLogger struct{}
59
60func (l *nullLogger) Error(msg string) {}
61func (l *nullLogger) Infof(msg string, args ...interface{}) {}
62func (l *nullLogger) Debugf(msg string, args ...interface{}) {}
63
64// BytesBufferLogger implements Logger backed by a bytes.Buffer.
65type BytesBufferLogger struct {
66 mux sync.Mutex
67 buf bytes.Buffer
68}
69
70// Error implements Logger.
71func (l *BytesBufferLogger) Error(msg string) {
72 l.mux.Lock()
73 l.buf.WriteString(fmt.Sprintf("ERROR: %s\n", msg))
74 l.mux.Unlock()
75}
76
77// Infof implements Logger.
78func (l *BytesBufferLogger) Infof(msg string, args ...interface{}) {
79 l.mux.Lock()
80 l.buf.WriteString("INFO: " + fmt.Sprintf(msg, args...) + "\n")
81 l.mux.Unlock()
82}
83
84// Debugf implements Logger.
85func (l *BytesBufferLogger) Debugf(msg string, args ...interface{}) {
86 l.mux.Lock()
87 l.buf.WriteString("DEBUG: " + fmt.Sprintf(msg, args...) + "\n")
88 l.mux.Unlock()
89}
90
91// String returns string representation of the underlying buffer.
92func (l *BytesBufferLogger) String() string {
93 l.mux.Lock()
94 defer l.mux.Unlock()
95 return l.buf.String()
96}
97
98// Flush empties the underlying buffer.
99func (l *BytesBufferLogger) Flush() {
100 l.mux.Lock()
101 defer l.mux.Unlock()
102 l.buf.Reset()
103}
104
105// DebugLogger is an interface which adds a debug logging level
106type DebugLogger interface {
107 Logger
108
109 // Debugf logs a message at debug priority
110 Debugf(msg string, args ...interface{})
111}
112
113// DebugLogAdapter is a log adapter that converts a Logger into a DebugLogger
114// If the provided Logger doesn't satisfy the interface, a logger with debug
115// disabled is returned
116func DebugLogAdapter(logger Logger) DebugLogger {
117 if logger == nil {
118 return nil
119 }
120 if debugLogger, ok := logger.(DebugLogger); ok {
121 return debugLogger
122 }
123 logger.Infof("debug logging disabled")
124 return debugDisabledLogAdapter{logger: logger}
125}
126
127type debugDisabledLogAdapter struct {
128 logger Logger
129}
130
131func (d debugDisabledLogAdapter) Error(msg string) {
132 d.logger.Error(msg)
133}
134
135func (d debugDisabledLogAdapter) Infof(msg string, args ...interface{}) {
136 d.logger.Infof(msg, args...)
137}
138
139// Debugf is a nop
140func (d debugDisabledLogAdapter) Debugf(msg string, args ...interface{}) {
141}