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  }