embed: support multiple log outputs for structured logging
Zap support multi-writer by default. Signed-off-by: Gyuho Lee <gyuhox@gmail.com>
This commit is contained in:
@ -23,6 +23,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -394,7 +395,17 @@ func (cfg *Config) setupLogging() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "zap":
|
case "zap":
|
||||||
// TODO: make this more configurable
|
if cfg.LogOutput == "" {
|
||||||
|
cfg.LogOutput = DefaultLogOutput
|
||||||
|
}
|
||||||
|
outputs := strings.Split(cfg.LogOutput, ",")
|
||||||
|
for _, v := range outputs {
|
||||||
|
if v == DefaultLogOutput {
|
||||||
|
panic(fmt.Errorf("multi logoutput for %q is not supported yet", DefaultLogOutput))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use zapcore to support more features?
|
||||||
lcfg := zap.Config{
|
lcfg := zap.Config{
|
||||||
Level: zap.NewAtomicLevelAt(zap.InfoLevel),
|
Level: zap.NewAtomicLevelAt(zap.InfoLevel),
|
||||||
Development: false,
|
Development: false,
|
||||||
@ -404,35 +415,50 @@ func (cfg *Config) setupLogging() error {
|
|||||||
},
|
},
|
||||||
Encoding: "json",
|
Encoding: "json",
|
||||||
EncoderConfig: zap.NewProductionEncoderConfig(),
|
EncoderConfig: zap.NewProductionEncoderConfig(),
|
||||||
|
|
||||||
|
OutputPaths: make([]string, 0),
|
||||||
|
ErrorOutputPaths: make([]string, 0),
|
||||||
}
|
}
|
||||||
switch cfg.LogOutput {
|
outputPaths, errOutputPaths := make(map[string]struct{}), make(map[string]struct{})
|
||||||
case DefaultLogOutput:
|
for _, v := range outputs {
|
||||||
if syscall.Getppid() == 1 {
|
switch v {
|
||||||
// capnslog initially SetFormatter(NewDefaultFormatter(os.Stderr))
|
case DefaultLogOutput:
|
||||||
// where "NewDefaultFormatter" returns "NewJournaldFormatter"
|
if syscall.Getppid() == 1 {
|
||||||
// when syscall.Getppid() == 1, specify 'stdout' or 'stderr' to
|
// capnslog initially SetFormatter(NewDefaultFormatter(os.Stderr))
|
||||||
// skip journald logging even when running under systemd
|
// where "NewDefaultFormatter" returns "NewJournaldFormatter"
|
||||||
fmt.Println("running under init, which may be systemd!")
|
// when syscall.Getppid() == 1, specify 'stdout' or 'stderr' to
|
||||||
// TODO: capnlog.NewJournaldFormatter()
|
// skip journald logging even when running under systemd
|
||||||
lcfg.OutputPaths = []string{"stderr"}
|
// TODO: capnlog.NewJournaldFormatter()
|
||||||
lcfg.ErrorOutputPaths = []string{"stderr"}
|
fmt.Println("running under init, which may be systemd!")
|
||||||
} else {
|
outputPaths["stderr"] = struct{}{}
|
||||||
lcfg.OutputPaths = []string{"stderr"}
|
errOutputPaths["stderr"] = struct{}{}
|
||||||
lcfg.ErrorOutputPaths = []string{"stderr"}
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
outputPaths["stderr"] = struct{}{}
|
||||||
|
errOutputPaths["stderr"] = struct{}{}
|
||||||
|
|
||||||
|
case "stderr":
|
||||||
|
outputPaths["stderr"] = struct{}{}
|
||||||
|
errOutputPaths["stderr"] = struct{}{}
|
||||||
|
|
||||||
|
case "stdout":
|
||||||
|
outputPaths["stdout"] = struct{}{}
|
||||||
|
errOutputPaths["stdout"] = struct{}{}
|
||||||
|
|
||||||
|
default:
|
||||||
|
outputPaths[v] = struct{}{}
|
||||||
|
errOutputPaths[v] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
case "stderr":
|
|
||||||
lcfg.OutputPaths = []string{"stderr"}
|
|
||||||
lcfg.ErrorOutputPaths = []string{"stderr"}
|
|
||||||
|
|
||||||
case "stdout":
|
|
||||||
lcfg.OutputPaths = []string{"stdout"}
|
|
||||||
lcfg.ErrorOutputPaths = []string{"stdout"}
|
|
||||||
|
|
||||||
default:
|
|
||||||
lcfg.OutputPaths = []string{cfg.LogOutput}
|
|
||||||
lcfg.ErrorOutputPaths = []string{cfg.LogOutput}
|
|
||||||
}
|
}
|
||||||
|
for v := range outputPaths {
|
||||||
|
lcfg.OutputPaths = append(lcfg.OutputPaths, v)
|
||||||
|
}
|
||||||
|
for v := range errOutputPaths {
|
||||||
|
lcfg.ErrorOutputPaths = append(lcfg.ErrorOutputPaths, v)
|
||||||
|
}
|
||||||
|
sort.Strings(lcfg.OutputPaths)
|
||||||
|
sort.Strings(lcfg.ErrorOutputPaths)
|
||||||
|
|
||||||
if cfg.Debug {
|
if cfg.Debug {
|
||||||
lcfg.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
|
lcfg.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
|
||||||
|
Reference in New Issue
Block a user