forked from grailbio/base
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlog.go
172 lines (152 loc) · 4.95 KB
/
log.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
// Copyright 2018 GRAIL, Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
// Package log provides simple level logging. Log output is
// implemented by an outputter, which by default outputs to Go's
// logging package. Alternative implementations (e.g., vlog, glog)
// can provide their own outputter implementation so that logging
// output is unified.
//
// The package can be used as a replacement for Go's standard logging
// package; the behavior of its toplevel functions are identical with
// the default configuration.
//
// If the application wishes to configure logging levels by standard
// flags, it should call log.AddFlags before flag.Parse.
// log.AddFlags.
//
// Note that this package is intended to bridge Go's standard log
// package with Vanadium's (vlog). As we transition away from vlog,
// we can simplify this package by removing the Outputter interface.
package log
import (
"fmt"
"os"
)
// An Outputter provides a destination for leveled log output.
type Outputter interface {
// Level returns the level at which the outputter is accepting
// messages.
Level() Level
// Output writes the provided message to the outputter at the
// provided calldepth and level. The message is dropped by
// the outputter if it is not logging at the desired level.
Output(calldepth int, level Level, s string) error
}
var out Outputter = gologOutputter{}
// SetOutputter provides a new outputter for use in the log package.
// SetOutputter should not be called concurrently with any log
// output, and is thus suitable to be called only upon program
// initialization. SetOutputter returns the old outputter.
func SetOutputter(newOut Outputter) Outputter {
old := out
out = newOut
return old
}
// At returns whether the logger is currently logging at the provided level.
func At(level Level) bool {
return level <= out.Level()
}
// Output outputs a log message to the current outputter at the provided
// level and call depth.
func Output(calldepth int, level Level, s string) error {
return out.Output(calldepth+1, level, s)
}
// A Level is a log verbosity level. Increasing levels decrease in
// priority and (usually) increase in verbosity: if the outputter is
// logging at level L, then all messages with level M <= L are
// outputted.
type Level int
const (
// Off never outputs messages.
Off = Level(-3)
// Error outputs error messages.
Error = Level(-2)
// Info outputs informational messages. This is the standard
// logging level.
Info = Level(0)
// Debug outputs messages intended for debugging and development,
// not for regular users.
Debug = Level(1)
)
// String returns the string representation of the level l.
func (l Level) String() string {
switch l {
case Off:
return "off"
case Error:
return "error"
case Info:
return "info"
case Debug:
return "debug"
default:
if l < 0 {
panic("invalid log level")
}
return fmt.Sprintf("debug%d", l)
}
}
// Print formats a message in the manner of fmt.Sprint and outputs it
// at level l to the current outputter.
func (l Level) Print(v ...interface{}) {
if At(l) {
out.Output(2, l, fmt.Sprint(v...))
}
}
// Printkln formats a message in the manner of fmt.Sprintln and outputs
// it at level l to the current outputter.
func (l Level) Println(v ...interface{}) {
if At(l) {
out.Output(2, l, fmt.Sprintln(v...))
}
}
// Printf formats a message in the manner of fmt.Sprintf and outputs
// it at level l to the current outputter.
func (l Level) Printf(format string, v ...interface{}) {
if At(l) {
out.Output(2, l, fmt.Sprintf(format, v...))
}
}
// Print formats a message in the manner of fmt.Sprint
// and outputs it at the Info level to the current outputter.
func Print(v ...interface{}) {
if At(Info) {
out.Output(2, Info, fmt.Sprint(v...))
}
}
// Printf formats a message in the manner of fmt.Sprintf
// and outputs it at the Info level to the current outputter.
func Printf(format string, v ...interface{}) {
if At(Info) {
out.Output(2, Info, fmt.Sprintf(format, v...))
}
}
// Fatal formats a message in the manner of fmt.Sprint, outputs it at
// the error level to the current outputter and then calls
// os.Exit(1).
func Fatal(v ...interface{}) {
out.Output(2, Error, fmt.Sprint(v...))
os.Exit(1)
}
// Fatalf formats a message in the manner of fmt.Sprintf, outputs it at
// the error level to the current outputter and then calls
// os.Exit(1).
func Fatalf(format string, v ...interface{}) {
out.Output(2, Error, fmt.Sprintf(format, v...))
os.Exit(1)
}
// Panic formats a message in the manner of fmt.Sprint, outputs it
// at the error level to the current outputter and then panics.
func Panic(v ...interface{}) {
s := fmt.Sprint(v...)
out.Output(2, Error, s)
panic(s)
}
// Panicf formats a message in the manner of fmt.Sprintf, outputs it
// at the error level to the current outputter and then panics.
func Panicf(format string, v ...interface{}) {
s := fmt.Sprintf(format, v...)
out.Output(2, Error, s)
panic(s)
}