forked from cybozu-go/well
/
log.go
108 lines (96 loc) · 2.51 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
package cmd
import (
"context"
"errors"
"flag"
"path/filepath"
"github.com/cybozu-go/log"
)
var (
// empty default values indicates unspecified condition.
logFilename = flag.String("logfile", "", "Log filename")
logLevel = flag.String("loglevel", "", "Log level [critical,error,warning,info,debug]")
logFormat = flag.String("logformat", "", "Log format [plain,logfmt,json]")
ignoreLogFilename bool
)
func init() {
// This is for child processes of graceful restarting server.
// See graceful.go
ignoreLogFilename = !isMaster()
}
// LogConfig configures cybozu-go/log's default logger.
//
// Filename, if not an empty string, specifies the output filename.
//
// Level is the log threshold level name.
// Valid levels are "critical", "error", "warning", "info", and "debug".
// Empty string is treated as "info".
//
// Format specifies log formatter to be used.
// Available formatters are "plain", "logfmt", and "json".
// Empty string is treated as "plain".
//
// For details, see https://godoc.org/github.com/cybozu-go/log .
type LogConfig struct {
Filename string `toml:"filename" json:"filename"`
Level string `toml:"level" json:"level"`
Format string `toml:"format" json:"format"`
}
// Apply applies configurations to the default logger.
//
// Command-line flags take precedence over the struct member values.
func (c LogConfig) Apply() error {
logger := log.DefaultLogger()
filename := c.Filename
if len(*logFilename) > 0 {
filename = *logFilename
}
if len(filename) > 0 && !ignoreLogFilename {
abspath, err := filepath.Abs(filename)
if err != nil {
return err
}
w, err := openLogFile(abspath)
if err != nil {
return err
}
logger.SetOutput(w)
}
level := c.Level
if len(*logLevel) > 0 {
level = *logLevel
}
if len(level) == 0 {
level = "info"
}
err := logger.SetThresholdByName(level)
if err != nil {
return err
}
format := c.Format
if len(*logFormat) > 0 {
format = *logFormat
}
switch format {
case "", "plain":
logger.SetFormatter(log.PlainFormat{})
case "logfmt":
logger.SetFormatter(log.Logfmt{})
case "json":
logger.SetFormatter(log.JSONFormat{})
default:
return errors.New("invalid format: " + format)
}
return nil
}
// FieldsFromContext returns a map of fields containing
// context information. Currently, request ID field is
// included, if any.
func FieldsFromContext(ctx context.Context) map[string]interface{} {
m := make(map[string]interface{})
v := ctx.Value(RequestIDContextKey)
if v != nil {
m[log.FnRequestID] = v.(string)
}
return m
}