github.com/GuanceCloud/cliutils@v1.1.21/logger/default_output.go (about) 1 // Unless explicitly stated otherwise all files in this repository are licensed 2 // under the MIT License. 3 // This product includes software developed at Guance Cloud (https://www.guance.com/). 4 // Copyright 2021-present Guance, Inc. 5 6 package logger 7 8 import ( 9 "net/url" 10 "os" 11 "runtime" 12 "strings" 13 14 "go.uber.org/zap" 15 "go.uber.org/zap/zapcore" 16 ) 17 18 const ( 19 STDOUT = "stdout" // log output to stdout 20 ) 21 22 func newNormalRootLogger(fpath, level string, options int) (*zap.Logger, error) { 23 cfg := &zap.Config{ 24 Encoding: `json`, 25 EncoderConfig: zapcore.EncoderConfig{ 26 NameKey: NameKeyMod, 27 MessageKey: NameKeyMsg, 28 LevelKey: NameKeyLevel, 29 TimeKey: NameKeyTime, 30 CallerKey: NameKeyPos, 31 32 EncodeLevel: zapcore.CapitalLevelEncoder, 33 EncodeTime: zapcore.ISO8601TimeEncoder, 34 EncodeCaller: zapcore.FullCallerEncoder, 35 }, 36 } 37 38 if fpath != "" { 39 cfg.OutputPaths = []string{fpath} 40 41 if runtime.GOOS == "windows" { // See: https://github.com/uber-go/zap/issues/621 42 if err := zap.RegisterSink("winfile", newWinFileSink); err != nil { 43 return nil, err 44 } 45 46 cfg.OutputPaths = []string{ 47 "winfile:///" + fpath, 48 } 49 } 50 } 51 52 switch strings.ToLower(level) { 53 case DEBUG: 54 cfg.Level = zap.NewAtomicLevelAt(zapcore.DebugLevel) 55 case INFO: 56 cfg.Level = zap.NewAtomicLevelAt(zapcore.InfoLevel) 57 case WARN: 58 cfg.Level = zap.NewAtomicLevelAt(zapcore.WarnLevel) 59 case ERROR: 60 cfg.Level = zap.NewAtomicLevelAt(zapcore.ErrorLevel) 61 case PANIC: 62 cfg.Level = zap.NewAtomicLevelAt(zapcore.PanicLevel) 63 case DPANIC: 64 cfg.Level = zap.NewAtomicLevelAt(zapcore.DPanicLevel) 65 case FATAL: 66 cfg.Level = zap.NewAtomicLevelAt(zapcore.FatalLevel) 67 default: 68 cfg.Level = zap.NewAtomicLevelAt(zapcore.DebugLevel) 69 } 70 71 if options&OPT_COLOR != 0 { 72 cfg.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder 73 } 74 75 if options&OPT_ENC_CONSOLE != 0 { 76 cfg.Encoding = "console" 77 } 78 79 if options&OPT_SHORT_CALLER != 0 { 80 cfg.EncoderConfig.EncodeCaller = zapcore.ShortCallerEncoder 81 } 82 83 if options&OPT_STDOUT != 0 || fpath == "" { // if no log file path set, default set to stdout 84 cfg.OutputPaths = append(cfg.OutputPaths, STDOUT) 85 } 86 87 l, err := cfg.Build() 88 if err != nil { 89 return nil, err 90 } 91 92 return l, nil 93 } 94 95 func newWinFileSink(u *url.URL) (zap.Sink, error) { 96 return os.OpenFile(u.Path[1:], os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o644) //nolint:gosec 97 }