github.com/sagernet/quic-go@v0.43.1-beta.1/internal/utils/log.go (about)

     1  package utils
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  	"strings"
     8  	"time"
     9  )
    10  
    11  // LogLevel of quic-go
    12  type LogLevel uint8
    13  
    14  const (
    15  	// LogLevelNothing disables
    16  	LogLevelNothing LogLevel = iota
    17  	// LogLevelError enables err logs
    18  	LogLevelError
    19  	// LogLevelInfo enables info logs (e.g. packets)
    20  	LogLevelInfo
    21  	// LogLevelDebug enables debug logs (e.g. packet contents)
    22  	LogLevelDebug
    23  )
    24  
    25  const logEnv = "QUIC_GO_LOG_LEVEL"
    26  
    27  // A Logger logs.
    28  type Logger interface {
    29  	SetLogLevel(LogLevel)
    30  	SetLogTimeFormat(format string)
    31  	WithPrefix(prefix string) Logger
    32  	Debug() bool
    33  
    34  	Errorf(format string, args ...interface{})
    35  	Infof(format string, args ...interface{})
    36  	Debugf(format string, args ...interface{})
    37  }
    38  
    39  // DefaultLogger is used by quic-go for logging.
    40  var DefaultLogger Logger
    41  
    42  type defaultLogger struct {
    43  	prefix string
    44  
    45  	logLevel   LogLevel
    46  	timeFormat string
    47  }
    48  
    49  var _ Logger = &defaultLogger{}
    50  
    51  // SetLogLevel sets the log level
    52  func (l *defaultLogger) SetLogLevel(level LogLevel) {
    53  	l.logLevel = level
    54  }
    55  
    56  // SetLogTimeFormat sets the format of the timestamp
    57  // an empty string disables the logging of timestamps
    58  func (l *defaultLogger) SetLogTimeFormat(format string) {
    59  	log.SetFlags(0) // disable timestamp logging done by the log package
    60  	l.timeFormat = format
    61  }
    62  
    63  // Debugf logs something
    64  func (l *defaultLogger) Debugf(format string, args ...interface{}) {
    65  	if l.logLevel == LogLevelDebug {
    66  		l.logMessage(format, args...)
    67  	}
    68  }
    69  
    70  // Infof logs something
    71  func (l *defaultLogger) Infof(format string, args ...interface{}) {
    72  	if l.logLevel >= LogLevelInfo {
    73  		l.logMessage(format, args...)
    74  	}
    75  }
    76  
    77  // Errorf logs something
    78  func (l *defaultLogger) Errorf(format string, args ...interface{}) {
    79  	if l.logLevel >= LogLevelError {
    80  		l.logMessage(format, args...)
    81  	}
    82  }
    83  
    84  func (l *defaultLogger) logMessage(format string, args ...interface{}) {
    85  	var pre string
    86  
    87  	if len(l.timeFormat) > 0 {
    88  		pre = time.Now().Format(l.timeFormat) + " "
    89  	}
    90  	if len(l.prefix) > 0 {
    91  		pre += l.prefix + " "
    92  	}
    93  	log.Printf(pre+format, args...)
    94  }
    95  
    96  func (l *defaultLogger) WithPrefix(prefix string) Logger {
    97  	if len(l.prefix) > 0 {
    98  		prefix = l.prefix + " " + prefix
    99  	}
   100  	return &defaultLogger{
   101  		logLevel:   l.logLevel,
   102  		timeFormat: l.timeFormat,
   103  		prefix:     prefix,
   104  	}
   105  }
   106  
   107  // Debug returns true if the log level is LogLevelDebug
   108  func (l *defaultLogger) Debug() bool {
   109  	return l.logLevel == LogLevelDebug
   110  }
   111  
   112  func init() {
   113  	DefaultLogger = &defaultLogger{}
   114  	DefaultLogger.SetLogLevel(readLoggingEnv())
   115  }
   116  
   117  func readLoggingEnv() LogLevel {
   118  	switch strings.ToLower(os.Getenv(logEnv)) {
   119  	case "":
   120  		return LogLevelNothing
   121  	case "debug":
   122  		return LogLevelDebug
   123  	case "info":
   124  		return LogLevelInfo
   125  	case "error":
   126  		return LogLevelError
   127  	default:
   128  		fmt.Fprintln(os.Stderr, "invalid quic-go log level, see https://github.com/sagernet/quic-go/wiki/Logging")
   129  		return LogLevelNothing
   130  	}
   131  }