-
Notifications
You must be signed in to change notification settings - Fork 1
/
stream.go
101 lines (90 loc) · 3.38 KB
/
stream.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
package logger
import (
"os"
"strings"
"time"
"github.com/gildas/go-core"
)
// Streamer is the interface a Logger writes to
type Streamer interface {
// Write writes the given Record
Write(record Record) error
// ShouldWrite tells if the given level should be written to this stream
ShouldWrite(level Level, topic, scope string) bool
// ShouldLogSourceInfo tells if the source info should be logged
ShouldLogSourceInfo() bool
// Flush flushes the stream (makes sure records are actually written)
Flush()
// Close closes the stream
Close()
// GetFilterLevels gets the FilterLevels
GetFilterLevels() LevelSet
}
// GetFlushFrequencyFromEnvironment fetches the flush frequency from the environment
//
// the frequency should be like https://golang.org/pkg/time/#ParseDuration or an ISO8601 duration.
//
// If not set, the frequency will be 5 minutes
func GetFlushFrequencyFromEnvironment() time.Duration {
return core.GetEnvAsDuration("LOG_FLUSHFREQUENCY", 5*time.Minute)
}
// CreateStreamWithDestination creates a new Streamer from a list of strings
//
// "stdout" will create a StdoutStream
//
// "stderr" will create a StderrStream
//
// "nil", "null" will create a NilStream
//
// "stackdriver" will create a StackDriverStream
//
// "gcp", "googlecloud", "google" will create a StdoutStream, unbuffered, with the StackDriverConverter
//
// "file:///path/to/file" or "path/to/file", "/path/to/file" will create a FileStream on the given location
//
// If more than one string is given, a MultiStream of all Streams from strings is created.
//
// If the environment variable DEBUG is set to 1, all Streams are created unbuffered.
//
// If the list is empty, the environment variable LOG_DESTINATION is used.
func CreateStream(levels LevelSet, destinations ...string) Streamer {
debug := levels.Get("any", "any") == DEBUG
unbuffered := debug
sourceInfo := core.GetEnvAsBool("LOG_SOURCEINFO", false)
if len(destinations) == 0 {
destination, ok := os.LookupEnv("LOG_DESTINATION")
if !ok || len(destination) == 0 {
return &StdoutStream{FilterLevels: levels, Unbuffered: unbuffered, SourceInfo: sourceInfo}
}
destinations = strings.Split(destination, ",")
}
streams := []Streamer{}
for _, destination := range destinations {
var stream Streamer
switch strings.ToLower(strings.TrimSpace(destination)) {
case "stdout":
stream = &StdoutStream{FilterLevels: levels, Unbuffered: unbuffered, SourceInfo: sourceInfo}
case "stderr":
stream = &StderrStream{FilterLevels: levels, SourceInfo: sourceInfo}
case "gcp", "google", "googlecloud":
stream = &StdoutStream{FilterLevels: levels, Unbuffered: true, SourceInfo: sourceInfo, Converter: &StackDriverConverter{}}
case "stackdriver":
stream = &StackDriverStream{FilterLevels: levels, SourceInfo: sourceInfo}
case "nil", "null", "void", "blackhole", "nether":
stream = &NilStream{}
default:
if strings.HasPrefix(destination, "file://") {
stream = &FileStream{FilterLevels: levels, Path: strings.TrimPrefix(destination, "file://"), Unbuffered: unbuffered}
} else if len(destination) > 0 {
stream = &FileStream{FilterLevels: levels, Path: destination, Unbuffered: unbuffered, SourceInfo: sourceInfo}
} else {
stream = &StdoutStream{FilterLevels: levels, Unbuffered: unbuffered, SourceInfo: sourceInfo}
}
}
streams = append(streams, stream)
}
if len(streams) == 1 {
return streams[0]
}
return &MultiStream{streams: streams}
}