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 }