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  }