gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

loggerv2.go (8331B)


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