github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/grpclog/loggerv2.go (about) 1 /* 2 * 3 * Copyright 2017 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package grpclog 20 21 import ( 22 "encoding/json" 23 "fmt" 24 "io" 25 "io/ioutil" 26 "log" 27 "os" 28 "strconv" 29 "strings" 30 31 "github.com/hxx258456/ccgo/grpc/internal/grpclog" 32 ) 33 34 // LoggerV2 does underlying logging work for grpclog. 35 type LoggerV2 interface { 36 // Info logs to INFO log. Arguments are handled in the manner of fmt.Print. 37 Info(args ...interface{}) 38 // Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println. 39 Infoln(args ...interface{}) 40 // Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf. 41 Infof(format string, args ...interface{}) 42 // Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print. 43 Warning(args ...interface{}) 44 // Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println. 45 Warningln(args ...interface{}) 46 // Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf. 47 Warningf(format string, args ...interface{}) 48 // Error logs to ERROR log. Arguments are handled in the manner of fmt.Print. 49 Error(args ...interface{}) 50 // Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println. 51 Errorln(args ...interface{}) 52 // Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. 53 Errorf(format string, args ...interface{}) 54 // Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print. 55 // gRPC ensures that all Fatal logs will exit with os.Exit(1). 56 // Implementations may also call os.Exit() with a non-zero exit code. 57 Fatal(args ...interface{}) 58 // Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println. 59 // gRPC ensures that all Fatal logs will exit with os.Exit(1). 60 // Implementations may also call os.Exit() with a non-zero exit code. 61 Fatalln(args ...interface{}) 62 // Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf. 63 // gRPC ensures that all Fatal logs will exit with os.Exit(1). 64 // Implementations may also call os.Exit() with a non-zero exit code. 65 Fatalf(format string, args ...interface{}) 66 // V reports whether verbosity level l is at least the requested verbose level. 67 V(l int) bool 68 } 69 70 // SetLoggerV2 sets logger that is used in grpc to a V2 logger. 71 // Not mutex-protected, should be called before any gRPC functions. 72 func SetLoggerV2(l LoggerV2) { 73 if _, ok := l.(*componentData); ok { 74 panic("cannot use component logger as grpclog logger") 75 } 76 grpclog.Logger = l 77 grpclog.DepthLogger, _ = l.(grpclog.DepthLoggerV2) 78 } 79 80 const ( 81 // infoLog indicates Info severity. 82 infoLog int = iota 83 // warningLog indicates Warning severity. 84 warningLog 85 // errorLog indicates Error severity. 86 errorLog 87 // fatalLog indicates Fatal severity. 88 fatalLog 89 ) 90 91 // severityName contains the string representation of each severity. 92 var severityName = []string{ 93 infoLog: "INFO", 94 warningLog: "WARNING", 95 errorLog: "ERROR", 96 fatalLog: "FATAL", 97 } 98 99 // loggerT is the default logger used by grpclog. 100 type loggerT struct { 101 m []*log.Logger 102 v int 103 jsonFormat bool 104 } 105 106 // NewLoggerV2 creates a loggerV2 with the provided writers. 107 // Fatal logs will be written to errorW, warningW, infoW, followed by exit(1). 108 // Error logs will be written to errorW, warningW and infoW. 109 // Warning logs will be written to warningW and infoW. 110 // Info logs will be written to infoW. 111 func NewLoggerV2(infoW, warningW, errorW io.Writer) LoggerV2 { 112 return newLoggerV2WithConfig(infoW, warningW, errorW, loggerV2Config{}) 113 } 114 115 // NewLoggerV2WithVerbosity creates a loggerV2 with the provided writers and 116 // verbosity level. 117 func NewLoggerV2WithVerbosity(infoW, warningW, errorW io.Writer, v int) LoggerV2 { 118 return newLoggerV2WithConfig(infoW, warningW, errorW, loggerV2Config{verbose: v}) 119 } 120 121 type loggerV2Config struct { 122 verbose int 123 jsonFormat bool 124 } 125 126 func newLoggerV2WithConfig(infoW, warningW, errorW io.Writer, c loggerV2Config) LoggerV2 { 127 var m []*log.Logger 128 flag := log.LstdFlags 129 if c.jsonFormat { 130 flag = 0 131 } 132 m = append(m, log.New(infoW, "", flag)) 133 m = append(m, log.New(io.MultiWriter(infoW, warningW), "", flag)) 134 ew := io.MultiWriter(infoW, warningW, errorW) // ew will be used for error and fatal. 135 m = append(m, log.New(ew, "", flag)) 136 m = append(m, log.New(ew, "", flag)) 137 return &loggerT{m: m, v: c.verbose, jsonFormat: c.jsonFormat} 138 } 139 140 // newLoggerV2 creates a loggerV2 to be used as default logger. 141 // All logs are written to stderr. 142 func newLoggerV2() LoggerV2 { 143 errorW := ioutil.Discard 144 warningW := ioutil.Discard 145 infoW := ioutil.Discard 146 147 logLevel := os.Getenv("GRPC_GO_LOG_SEVERITY_LEVEL") 148 switch logLevel { 149 case "", "ERROR", "error": // If env is unset, set level to ERROR. 150 errorW = os.Stderr 151 case "WARNING", "warning": 152 warningW = os.Stderr 153 case "INFO", "info": 154 infoW = os.Stderr 155 } 156 157 var v int 158 vLevel := os.Getenv("GRPC_GO_LOG_VERBOSITY_LEVEL") 159 if vl, err := strconv.Atoi(vLevel); err == nil { 160 v = vl 161 } 162 163 jsonFormat := strings.EqualFold(os.Getenv("GRPC_GO_LOG_FORMATTER"), "json") 164 165 return newLoggerV2WithConfig(infoW, warningW, errorW, loggerV2Config{ 166 verbose: v, 167 jsonFormat: jsonFormat, 168 }) 169 } 170 171 func (g *loggerT) output(severity int, s string) { 172 sevStr := severityName[severity] 173 if !g.jsonFormat { 174 g.m[severity].Output(2, fmt.Sprintf("%v: %v", sevStr, s)) 175 return 176 } 177 // TODO: we can also include the logging component, but that needs more 178 // (API) changes. 179 b, _ := json.Marshal(map[string]string{ 180 "severity": sevStr, 181 "message": s, 182 }) 183 g.m[severity].Output(2, string(b)) 184 } 185 186 func (g *loggerT) Info(args ...interface{}) { 187 g.output(infoLog, fmt.Sprint(args...)) 188 } 189 190 func (g *loggerT) Infoln(args ...interface{}) { 191 g.output(infoLog, fmt.Sprintln(args...)) 192 } 193 194 func (g *loggerT) Infof(format string, args ...interface{}) { 195 g.output(infoLog, fmt.Sprintf(format, args...)) 196 } 197 198 func (g *loggerT) Warning(args ...interface{}) { 199 g.output(warningLog, fmt.Sprint(args...)) 200 } 201 202 func (g *loggerT) Warningln(args ...interface{}) { 203 g.output(warningLog, fmt.Sprintln(args...)) 204 } 205 206 func (g *loggerT) Warningf(format string, args ...interface{}) { 207 g.output(warningLog, fmt.Sprintf(format, args...)) 208 } 209 210 func (g *loggerT) Error(args ...interface{}) { 211 g.output(errorLog, fmt.Sprint(args...)) 212 } 213 214 func (g *loggerT) Errorln(args ...interface{}) { 215 g.output(errorLog, fmt.Sprintln(args...)) 216 } 217 218 func (g *loggerT) Errorf(format string, args ...interface{}) { 219 g.output(errorLog, fmt.Sprintf(format, args...)) 220 } 221 222 func (g *loggerT) Fatal(args ...interface{}) { 223 g.output(fatalLog, fmt.Sprint(args...)) 224 os.Exit(1) 225 } 226 227 func (g *loggerT) Fatalln(args ...interface{}) { 228 g.output(fatalLog, fmt.Sprintln(args...)) 229 os.Exit(1) 230 } 231 232 func (g *loggerT) Fatalf(format string, args ...interface{}) { 233 g.output(fatalLog, fmt.Sprintf(format, args...)) 234 os.Exit(1) 235 } 236 237 func (g *loggerT) V(l int) bool { 238 return l <= g.v 239 } 240 241 // DepthLoggerV2 logs at a specified call frame. If a LoggerV2 also implements 242 // DepthLoggerV2, the below functions will be called with the appropriate stack 243 // depth set for trivial functions the logger may ignore. 244 // 245 // Experimental 246 // 247 // Notice: This type is EXPERIMENTAL and may be changed or removed in a 248 // later release. 249 type DepthLoggerV2 interface { 250 LoggerV2 251 // InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Println. 252 InfoDepth(depth int, args ...interface{}) 253 // WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Println. 254 WarningDepth(depth int, args ...interface{}) 255 // ErrorDepth logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Println. 256 ErrorDepth(depth int, args ...interface{}) 257 // FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Println. 258 FatalDepth(depth int, args ...interface{}) 259 }