Skip to content

Commit c71a9d8

Browse files
authored
Merge pull request #2 from cbsinteractive/set-log-level
filter logs by minimum log level or regex
2 parents 9872184 + 23d87dd commit c71a9d8

File tree

2 files changed

+411
-15
lines changed

2 files changed

+411
-15
lines changed

log.go

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,39 @@
55
// This code may be copied and pasted into your microservice
66
// and modified to your liking. Put it in a package called
77
// log. A little copying is better than a little dependency.
8-
//
98
package log
109

1110
import (
1211
"encoding/json"
1312
"fmt"
1413
"io"
1514
"os"
15+
"regexp"
16+
"sync"
1617
"time"
1718
)
1819

1920
// Line allows a log line to be embedded somewhere
2021
type Line = line
2122

23+
type LevelInt int
24+
25+
type LogConfig struct {
26+
MinLevel LevelInt
27+
RegexPassthrough []string
28+
RegexEnabled bool
29+
DebugOn bool
30+
UpdatedAt time.Time
31+
}
32+
33+
const (
34+
LevelDebug LevelInt = iota + 1
35+
LevelInfo
36+
LevelWarn
37+
LevelError
38+
LevelFatal
39+
)
40+
2241
var (
2342
// Service name (can be set in main or elsewhere)
2443
Service = os.Getenv("SVC")
@@ -34,18 +53,27 @@ var (
3453

3554
// Default is the level used when calling Printf and Fatalf
3655
Default = Info
56+
57+
Config = LogConfig{
58+
MinLevel: LevelDebug,
59+
RegexPassthrough: []string{},
60+
RegexEnabled: false,
61+
DebugOn: false,
62+
UpdatedAt: time.Time{},
63+
}
64+
compiledRegex = []*regexp.Regexp{}
65+
setMutex = sync.Mutex{}
3766
)
3867

3968
var (
4069
// Info, Warn, and so forth are commonly encountered log "levels".
41-
Info = line{Level: "info"}
42-
Warn = line{Level: "warn"}
43-
Error = line{Level: "error"}
44-
Fatal = line{Level: "fatal"}
45-
46-
// Debug is a special level, it is only printed if DebugOn is true
47-
Debug = line{Level: "debug"}
48-
DebugOn = false
70+
Info = line{Level: "info", LevelInt: LevelInfo}
71+
Warn = line{Level: "warn", LevelInt: LevelWarn}
72+
Error = line{Level: "error", LevelInt: LevelError}
73+
Fatal = line{Level: "fatal", LevelInt: LevelFatal}
74+
75+
// Debug is a special level, it is only printed if Config.DebugOn is true
76+
Debug = line{Level: "debug", LevelInt: LevelDebug}
4977
)
5078

5179
var stderr = io.Writer(os.Stderr)
@@ -65,8 +93,9 @@ func SetOutput(w io.Writer) (old io.Writer) {
6593
type line struct {
6694
fn func(line) line
6795
fields
68-
Level string
69-
msg string
96+
Level string
97+
LevelInt LevelInt
98+
msg string
7099
}
71100

72101
// Printf attaches the formatted message to line and outputs
@@ -81,8 +110,15 @@ type line struct {
81110
//
82111
// Prefer log.Error.F() to log.Error.Printf() unless using Add
83112
func (l line) Printf(f string, v ...interface{}) {
84-
if l.Level == Debug.Level && !DebugOn {
85-
return
113+
// if msg is debug, checks if log msg should NOT be printed
114+
exitDebugMsg := l.Level == Debug.Level && !Config.DebugOn
115+
// for other levels, checks if log msg should NOT be printed based on min level
116+
exitMinLevelMsg := l.LevelInt < Config.MinLevel
117+
if exitDebugMsg || exitMinLevelMsg {
118+
// check to see if message matches any regex to allow message to be printed
119+
if !RegexPassthrough(f, v...) {
120+
return
121+
}
86122
}
87123
fmt.Fprintln(stderr, l.Msg(f, v...).String())
88124
if l.Level == "fatal" {
@@ -224,8 +260,8 @@ type trapme string
224260
// not affected. Trap calls os.Exit(1) if the panic occured from these
225261
// functions.
226262
//
227-
// func main(){
228-
// defer log.Trap()
263+
// func main(){
264+
// defer log.Trap()
229265
//
230266
// }
231267
func Trap() {
@@ -245,3 +281,33 @@ func zero(v interface{}) bool {
245281
}
246282
return len(t) == 0
247283
}
284+
285+
func SetLogConfig(config LogConfig) error {
286+
setMutex.Lock()
287+
defer setMutex.Unlock()
288+
Config = config
289+
// compile the regexes
290+
for _, exp := range config.RegexPassthrough {
291+
reg, err := regexp.Compile(exp)
292+
if err != nil {
293+
return err
294+
}
295+
compiledRegex = append(compiledRegex, reg)
296+
}
297+
return nil
298+
}
299+
300+
func RegexPassthrough(f string, v ...interface{}) bool {
301+
if !Config.RegexEnabled {
302+
return false
303+
}
304+
setMutex.Lock()
305+
defer setMutex.Unlock()
306+
msg := fmt.Sprintf(f, v...)
307+
for _, reg := range compiledRegex {
308+
if reg.MatchString(msg) {
309+
return true
310+
}
311+
}
312+
return false
313+
}

0 commit comments

Comments
 (0)