trpc.group/trpc-go/trpc-go@v1.0.3/log/log.go (about)

     1  //
     2  //
     3  // Tencent is pleased to support the open source community by making tRPC available.
     4  //
     5  // Copyright (C) 2023 THL A29 Limited, a Tencent company.
     6  // All rights reserved.
     7  //
     8  // If you have downloaded a copy of the tRPC source code from Tencent,
     9  // please note that tRPC source code is licensed under the  Apache 2.0 License,
    10  // A copy of the Apache 2.0 License is included in this file.
    11  //
    12  //
    13  
    14  // Package log provides a log for the framework and applications.
    15  package log
    16  
    17  import (
    18  	"context"
    19  	"errors"
    20  	"os"
    21  
    22  	"go.uber.org/zap"
    23  	"go.uber.org/zap/zapcore"
    24  
    25  	"trpc.group/trpc-go/trpc-go/codec"
    26  	"trpc.group/trpc-go/trpc-go/internal/env"
    27  )
    28  
    29  var traceEnabled = traceEnableFromEnv()
    30  
    31  // traceEnableFromEnv checks whether trace is enabled by reading from environment.
    32  // Close trace if empty or zero, open trace if not zero, default as closed.
    33  func traceEnableFromEnv() bool {
    34  	switch os.Getenv(env.LogTrace) {
    35  	case "":
    36  		fallthrough
    37  	case "0":
    38  		return false
    39  	default:
    40  		return true
    41  	}
    42  }
    43  
    44  // EnableTrace enables trace.
    45  func EnableTrace() {
    46  	traceEnabled = true
    47  }
    48  
    49  // SetLevel sets log level for different output which may be "0", "1" or "2".
    50  func SetLevel(output string, level Level) {
    51  	GetDefaultLogger().SetLevel(output, level)
    52  }
    53  
    54  // GetLevel gets log level for different output.
    55  func GetLevel(output string) Level {
    56  	return GetDefaultLogger().GetLevel(output)
    57  }
    58  
    59  // With adds user defined fields to Logger. Field support multiple values.
    60  func With(fields ...Field) Logger {
    61  	if ol, ok := GetDefaultLogger().(OptionLogger); ok {
    62  		return ol.WithOptions(WithAdditionalCallerSkip(-1)).With(fields...)
    63  	}
    64  	return GetDefaultLogger().With(fields...)
    65  }
    66  
    67  // WithContext add user defined fields to the Logger of context. Fields support multiple values.
    68  func WithContext(ctx context.Context, fields ...Field) Logger {
    69  	logger, ok := codec.Message(ctx).Logger().(Logger)
    70  	if !ok {
    71  		return With(fields...)
    72  	}
    73  	if ol, ok := logger.(OptionLogger); ok {
    74  		return ol.WithOptions(WithAdditionalCallerSkip(-1)).With(fields...)
    75  	}
    76  	return logger.With(fields...)
    77  }
    78  
    79  // RedirectStdLog redirects std log to trpc logger as log level INFO.
    80  // After redirection, log flag is zero, the prefix is empty.
    81  // The returned function may be used to recover log flag and prefix, and redirect output to
    82  // os.Stderr.
    83  func RedirectStdLog(logger Logger) (func(), error) {
    84  	return RedirectStdLogAt(logger, zap.InfoLevel)
    85  }
    86  
    87  // RedirectStdLogAt redirects std log to trpc logger with a specific level.
    88  // After redirection, log flag is zero, the prefix is empty.
    89  // The returned function may be used to recover log flag and prefix, and redirect output to
    90  // os.Stderr.
    91  func RedirectStdLogAt(logger Logger, level zapcore.Level) (func(), error) {
    92  	if l, ok := logger.(*zapLog); ok {
    93  		return zap.RedirectStdLogAt(l.logger, level)
    94  	}
    95  
    96  	return nil, errors.New("log: only supports redirecting std logs to trpc zap logger")
    97  }
    98  
    99  // Trace logs to TRACE log. Arguments are handled in the manner of fmt.Println.
   100  func Trace(args ...interface{}) {
   101  	if traceEnabled {
   102  		GetDefaultLogger().Trace(args...)
   103  	}
   104  }
   105  
   106  // Tracef logs to TRACE log. Arguments are handled in the manner of fmt.Printf.
   107  func Tracef(format string, args ...interface{}) {
   108  	if traceEnabled {
   109  		GetDefaultLogger().Tracef(format, args...)
   110  	}
   111  }
   112  
   113  // TraceContext logs to TRACE log. Arguments are handled in the manner of fmt.Println.
   114  func TraceContext(ctx context.Context, args ...interface{}) {
   115  	if !traceEnabled {
   116  		return
   117  	}
   118  	if l, ok := codec.Message(ctx).Logger().(Logger); ok {
   119  		l.Trace(args...)
   120  		return
   121  	}
   122  	GetDefaultLogger().Trace(args...)
   123  }
   124  
   125  // TraceContextf logs to TRACE log. Arguments are handled in the manner of fmt.Printf.
   126  func TraceContextf(ctx context.Context, format string, args ...interface{}) {
   127  	if !traceEnabled {
   128  		return
   129  	}
   130  	if l, ok := codec.Message(ctx).Logger().(Logger); ok {
   131  		l.Tracef(format, args...)
   132  		return
   133  	}
   134  	GetDefaultLogger().Tracef(format, args...)
   135  }
   136  
   137  // Debug logs to DEBUG log. Arguments are handled in the manner of fmt.Println.
   138  func Debug(args ...interface{}) {
   139  	GetDefaultLogger().Debug(args...)
   140  }
   141  
   142  // Debugf logs to DEBUG log. Arguments are handled in the manner of fmt.Printf.
   143  func Debugf(format string, args ...interface{}) {
   144  	GetDefaultLogger().Debugf(format, args...)
   145  }
   146  
   147  // Info logs to INFO log. Arguments are handled in the manner of fmt.Println.
   148  func Info(args ...interface{}) {
   149  	GetDefaultLogger().Info(args...)
   150  }
   151  
   152  // Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf.
   153  func Infof(format string, args ...interface{}) {
   154  	GetDefaultLogger().Infof(format, args...)
   155  }
   156  
   157  // Warn logs to WARNING log. Arguments are handled in the manner of fmt.Println.
   158  func Warn(args ...interface{}) {
   159  	GetDefaultLogger().Warn(args...)
   160  }
   161  
   162  // Warnf logs to WARNING log. Arguments are handled in the manner of fmt.Printf.
   163  func Warnf(format string, args ...interface{}) {
   164  	GetDefaultLogger().Warnf(format, args...)
   165  }
   166  
   167  // Error logs to ERROR log. Arguments are handled in the manner of fmt.Println.
   168  func Error(args ...interface{}) {
   169  	GetDefaultLogger().Error(args...)
   170  }
   171  
   172  // Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
   173  func Errorf(format string, args ...interface{}) {
   174  	GetDefaultLogger().Errorf(format, args...)
   175  }
   176  
   177  // Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Println.
   178  // All Fatal logs will exit by calling os.Exit(1).
   179  // Implementations may also call os.Exit() with a non-zero exit code.
   180  func Fatal(args ...interface{}) {
   181  	GetDefaultLogger().Fatal(args...)
   182  }
   183  
   184  // Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
   185  func Fatalf(format string, args ...interface{}) {
   186  	GetDefaultLogger().Fatalf(format, args...)
   187  }
   188  
   189  // WithContextFields sets some user defined data to logs, such as uid, imei, etc.
   190  // Fields must be paired.
   191  // If ctx has already set a Msg, this function returns that ctx, otherwise, it returns a new one.
   192  func WithContextFields(ctx context.Context, fields ...string) context.Context {
   193  	tagCapacity := len(fields) / 2
   194  	tags := make([]Field, 0, tagCapacity)
   195  	for i := 0; i < tagCapacity; i++ {
   196  		tags = append(tags, Field{
   197  			Key:   fields[2*i],
   198  			Value: fields[2*i+1],
   199  		})
   200  	}
   201  
   202  	ctx, msg := codec.EnsureMessage(ctx)
   203  	logger, ok := msg.Logger().(Logger)
   204  	if ok && logger != nil {
   205  		logger = logger.With(tags...)
   206  	} else {
   207  		logger = GetDefaultLogger().With(tags...)
   208  	}
   209  
   210  	msg.WithLogger(logger)
   211  	return ctx
   212  }
   213  
   214  // DebugContext logs to DEBUG log. Arguments are handled in the manner of fmt.Println.
   215  func DebugContext(ctx context.Context, args ...interface{}) {
   216  	if l, ok := codec.Message(ctx).Logger().(Logger); ok {
   217  		l.Debug(args...)
   218  		return
   219  	}
   220  	GetDefaultLogger().Debug(args...)
   221  }
   222  
   223  // DebugContextf logs to DEBUG log. Arguments are handled in the manner of fmt.Printf.
   224  func DebugContextf(ctx context.Context, format string, args ...interface{}) {
   225  	if l, ok := codec.Message(ctx).Logger().(Logger); ok {
   226  		l.Debugf(format, args...)
   227  		return
   228  	}
   229  	GetDefaultLogger().Debugf(format, args...)
   230  }
   231  
   232  // InfoContext logs to INFO log. Arguments are handled in the manner of fmt.Println.
   233  func InfoContext(ctx context.Context, args ...interface{}) {
   234  	if l, ok := codec.Message(ctx).Logger().(Logger); ok {
   235  		l.Info(args...)
   236  		return
   237  	}
   238  	GetDefaultLogger().Info(args...)
   239  }
   240  
   241  // InfoContextf logs to INFO log. Arguments are handled in the manner of fmt.Printf.
   242  func InfoContextf(ctx context.Context, format string, args ...interface{}) {
   243  	if l, ok := codec.Message(ctx).Logger().(Logger); ok {
   244  		l.Infof(format, args...)
   245  		return
   246  	}
   247  	GetDefaultLogger().Infof(format, args...)
   248  }
   249  
   250  // WarnContext logs to WARNING log. Arguments are handled in the manner of fmt.Println.
   251  func WarnContext(ctx context.Context, args ...interface{}) {
   252  	if l, ok := codec.Message(ctx).Logger().(Logger); ok {
   253  		l.Warn(args...)
   254  		return
   255  	}
   256  	GetDefaultLogger().Warn(args...)
   257  }
   258  
   259  // WarnContextf logs to WARNING log. Arguments are handled in the manner of fmt.Printf.
   260  func WarnContextf(ctx context.Context, format string, args ...interface{}) {
   261  	if l, ok := codec.Message(ctx).Logger().(Logger); ok {
   262  		l.Warnf(format, args...)
   263  		return
   264  	}
   265  	GetDefaultLogger().Warnf(format, args...)
   266  
   267  }
   268  
   269  // ErrorContext logs to ERROR log. Arguments are handled in the manner of fmt.Println.
   270  func ErrorContext(ctx context.Context, args ...interface{}) {
   271  	if l, ok := codec.Message(ctx).Logger().(Logger); ok {
   272  		l.Error(args...)
   273  		return
   274  	}
   275  	GetDefaultLogger().Error(args...)
   276  }
   277  
   278  // ErrorContextf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
   279  func ErrorContextf(ctx context.Context, format string, args ...interface{}) {
   280  	if l, ok := codec.Message(ctx).Logger().(Logger); ok {
   281  		l.Errorf(format, args...)
   282  		return
   283  	}
   284  	GetDefaultLogger().Errorf(format, args...)
   285  }
   286  
   287  // FatalContext logs to ERROR log. Arguments are handled in the manner of fmt.Println.
   288  // All Fatal logs will exit by calling os.Exit(1).
   289  // Implementations may also call os.Exit() with a non-zero exit code.
   290  func FatalContext(ctx context.Context, args ...interface{}) {
   291  	if l, ok := codec.Message(ctx).Logger().(Logger); ok {
   292  		l.Fatal(args...)
   293  		return
   294  	}
   295  	GetDefaultLogger().Fatal(args...)
   296  }
   297  
   298  // FatalContextf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
   299  func FatalContextf(ctx context.Context, format string, args ...interface{}) {
   300  	if l, ok := codec.Message(ctx).Logger().(Logger); ok {
   301  		l.Fatalf(format, args...)
   302  		return
   303  	}
   304  	GetDefaultLogger().Fatalf(format, args...)
   305  }