github.com/pavlo67/common@v0.5.3/common/logger/logger_zap/zap.go (about) 1 package logger_zap 2 3 import ( 4 "fmt" 5 "os" 6 "strings" 7 "time" 8 9 "go.uber.org/zap" 10 "go.uber.org/zap/zapcore" 11 12 "github.com/pavlo67/common/common" 13 "github.com/pavlo67/common/common/filelib" 14 "github.com/pavlo67/common/common/logger" 15 "github.com/pavlo67/common/common/pnglib" 16 ) 17 18 type loggerZap struct { 19 zap.SugaredLogger 20 logger.Config 21 } 22 23 func (op loggerZap) Comment(text string) { 24 for _, commentPath := range append(op.Config.OutputPaths, op.Config.ErrorPaths...) { 25 if commentPath == "stdout" { 26 fmt.Fprintf(os.Stdout, "\n%s\n", text) 27 } else if commentPath == "stderr" { 28 fmt.Fprintf(os.Stderr, "\n%s\n", text) 29 } else { 30 f, err := os.OpenFile(commentPath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) 31 if err != nil { 32 op.Errorf("CAN'T OPEN PATH (%s) TO COMMENT: %s", commentPath, err) 33 continue 34 } 35 defer f.Close() 36 if _, err = f.WriteString(text); err != nil { 37 op.Errorf("CAN'T WRITE COMMENT TO %s: %s", commentPath, err) 38 } 39 } 40 } 41 } 42 43 func (op *loggerZap) SetPath(basePath string) { 44 if op == nil { 45 return 46 } 47 if basePath = strings.TrimSpace(basePath); basePath == "" { 48 op.Config.BasePath = "" 49 return 50 } 51 52 var err error 53 if basePath, err = filelib.Dir(basePath); err != nil { 54 op.Errorf("can't create basePath (%s): %s / on logger.SetPath()", basePath, err) 55 return 56 } 57 58 op.Config.BasePath = basePath 59 } 60 61 func (op loggerZap) File(path string, data []byte) { 62 if op.Config.SaveFiles { 63 basedPaths, err := logger.ModifyPaths([]string{path}, op.Config.BasePath) 64 if err != nil { 65 op.Error(err) 66 } else if err := os.WriteFile(basedPaths[0], data, 0644); err != nil { 67 op.Errorf("CAN'T WRITE TO FILE %s: %s", path, err) 68 } else { 69 op.Infof("FILE IS WRITTEN %s", basedPaths[0]) 70 } 71 } 72 } 73 74 func (op loggerZap) Image(path string, getImage logger.GetImage, opts common.Map) { 75 if op.Config.SaveFiles { 76 img, info, err := getImage.Image(opts) 77 if info != "" { 78 op.File(path+".info", []byte(info)) 79 80 //_, filename, line, _ := runtime.Caller(1) 81 //op.Infof("from %s:%d: "+info, filename, line) 82 } 83 if img != nil { 84 basedPaths, err := logger.ModifyPaths([]string{path}, op.Config.BasePath) 85 if err != nil { 86 op.Error(err) 87 } else if err = pnglib.Save(img, basedPaths[0]); err != nil { 88 op.Error(err) 89 } 90 } 91 if err != nil { 92 op.Error(err) 93 } 94 } 95 } 96 97 func (op *loggerZap) SetKey(key string) { 98 if op == nil { 99 return 100 } 101 op.Config.Key = key 102 } 103 104 func (op loggerZap) Key() string { 105 return op.Config.Key 106 } 107 108 var _ logger.Operator = &loggerZap{} 109 110 func New(cfg logger.Config) (logger.Operator, error) { 111 c := zap.NewProductionConfig() 112 c.DisableStacktrace = true 113 c.Level.SetLevel(zapLevel(cfg.LogLevel)) 114 115 var err error 116 117 if len(cfg.OutputPaths) < 1 { 118 c.OutputPaths = []string{"stdout"} 119 } else { 120 c.OutputPaths, err = logger.ModifyPaths(cfg.OutputPaths, cfg.BasePath) 121 if err != nil { 122 return nil, err 123 } 124 } 125 126 if len(cfg.ErrorPaths) < 1 { 127 c.ErrorOutputPaths = []string{"stderr"} 128 } else { 129 c.ErrorOutputPaths, err = logger.ModifyPaths(cfg.ErrorPaths, cfg.BasePath) 130 if err != nil { 131 return nil, err 132 } 133 134 } 135 136 c.Encoding = cfg.Encoding 137 if c.Encoding == "" { 138 c.Encoding = "console" 139 } 140 c.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder 141 c.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder 142 143 l, err := c.Build() 144 if err != nil { 145 return nil, fmt.Errorf("can't create logger (%#v --> %#v), got %s", cfg, c, err) 146 } 147 148 if cfg.Key == "" { 149 cfg.Key = time.Now().Format(time.RFC3339)[:19] 150 } 151 152 return &loggerZap{SugaredLogger: *l.Sugar(), Config: cfg}, nil 153 } 154 155 func zapLevel(level logger.Level) zapcore.Level { 156 switch level { 157 case logger.TraceLevel: 158 return zapcore.DebugLevel 159 case logger.DebugLevel: 160 return zapcore.DebugLevel 161 case logger.InfoLevel: 162 return zapcore.InfoLevel 163 case logger.WarnLevel: 164 return zapcore.WarnLevel 165 case logger.ErrorLevel: 166 return zapcore.ErrorLevel 167 //case PanicLevel: 168 // return zapcore.PanicLevel 169 case logger.FatalLevel: 170 return zapcore.FatalLevel 171 default: 172 return zapcore.InfoLevel 173 } 174 }