This repository has been archived by the owner on Feb 21, 2024. It is now read-only.
/
logger.go
147 lines (117 loc) · 3.82 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
147
// Copyright 2017 Pilosa Corp.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package logger
import (
"fmt"
"io"
"log"
"time"
)
const RFC3339UsecTz0 = "2006-01-02T15:04:05.000000Z07:00"
// Ensure nopLogger implements interface.
var _ Logger = &nopLogger{}
// Logger represents an interface for a shared logger.
type Logger interface {
Printf(format string, v ...interface{})
Debugf(format string, v ...interface{})
}
// NopLogger represents a Logger that doesn't do anything.
var NopLogger Logger = &nopLogger{}
type nopLogger struct{}
// Printf is a no-op implementation of the Logger Printf method.
func (n *nopLogger) Printf(format string, v ...interface{}) {}
// Debugf is a no-op implementation of the Logger Debugf method.
func (n *nopLogger) Debugf(format string, v ...interface{}) {}
// standardLogger is a basic implementation of Logger based on log.Logger.
type standardLogger struct {
logger *log.Logger
}
// write in UTC with constant width and microsecond resolution.
type formatLog struct {
w io.Writer
}
func (fl formatLog) Write(bytes []byte) (int, error) {
return fmt.Fprintf(fl.w, "%v %v", time.Now().UTC().Format(RFC3339UsecTz0), string(bytes))
}
func NewStandardLogger(w io.Writer) *standardLogger {
logger := log.New(w, "", 0)
logger.SetOutput(formatLog{w: w})
return &standardLogger{
logger: logger,
}
}
func (s *standardLogger) Printf(format string, v ...interface{}) {
s.logger.Printf(format, v...)
}
func (s *standardLogger) Debugf(format string, v ...interface{}) {}
func (s *standardLogger) Logger() *log.Logger {
return s.logger
}
// verboseLogger is an implementation of Logger which includes debug messages.
type verboseLogger struct {
logger *log.Logger
}
func NewVerboseLogger(w io.Writer) *verboseLogger {
logger := log.New(w, "", 0)
logger.SetOutput(formatLog{w: w})
return &verboseLogger{
logger: logger,
}
}
func (vb *verboseLogger) Printf(format string, v ...interface{}) {
vb.logger.Printf(format, v...)
}
func (vb *verboseLogger) Debugf(format string, v ...interface{}) {
vb.logger.Printf(format, v...)
}
func (vb *verboseLogger) Logger() *log.Logger {
return vb.logger
}
// CaptureLogger is a logger that stores all the print and debug messages
// it sees, useful for testing.
type CaptureLogger struct {
Prints []string
Debugs []string
}
// NewCaptureLogger yields a CaptureLogger.
func NewCaptureLogger() *CaptureLogger {
return &CaptureLogger{}
}
// Printf formats a message and appends it to Prints.
func (cl *CaptureLogger) Printf(format string, v ...interface{}) {
cl.Prints = append(cl.Prints, fmt.Sprintf(format, v...))
}
// Debugf formats a message and appends it to Debugs.
func (cl *CaptureLogger) Debugf(format string, v ...interface{}) {
cl.Debugs = append(cl.Debugs, fmt.Sprintf(format, v...))
}
// Logfer is a thing that has only a Logf() method, like for instance,
// testing.T or testing.B.
type Logfer interface {
Logf(format string, v ...interface{})
}
// LogfLogger is a logger that wraps something that has a Logf interface
// and makes it act like our logger.
type LogfLogger struct {
wrapped Logfer
}
func (ll *LogfLogger) Printf(format string, v ...interface{}) {
ll.wrapped.Logf(format, v...)
}
func (ll *LogfLogger) Debugf(format string, v ...interface{}) {
ll.wrapped.Logf(format, v...)
}
func NewLogfLogger(l Logfer) *LogfLogger {
return &LogfLogger{wrapped: l}
}