github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/lib/log/serverlogger/api.go (about) 1 package serverlogger 2 3 import ( 4 "flag" 5 "fmt" 6 "io" 7 "log" 8 "regexp" 9 "sync" 10 11 "github.com/Cloud-Foundations/Dominator/lib/logbuf" 12 "github.com/Cloud-Foundations/Dominator/lib/srpc" 13 ) 14 15 var ( 16 initialLogDebugLevel = flag.Int("initialLogDebugLevel", -1, 17 "initial debug log level") 18 logSubseconds = flag.Bool("logSubseconds", false, 19 "if true, datestamps will have subsecond resolution") 20 ) 21 22 type Logger struct { 23 accessChecker func(method string, authInfo *srpc.AuthInformation) bool 24 circularBuffer *logbuf.LogBuffer 25 flags int 26 level int16 27 maxLevel int16 28 mutex sync.Mutex // Lock everything below. 29 streamers map[*streamerType]struct{} 30 } 31 32 type streamerType struct { 33 debugLevel int16 34 excludeRegex *regexp.Regexp // nil: nothing excluded. Processed after incl. 35 includeRegex *regexp.Regexp // nil: everything included. 36 output chan<- []byte 37 } 38 39 // New will create a Logger which has an internal log buffer (see the 40 // lib/logbuf package). It implements the log.DebugLogger interface. 41 // By default, the max debug level is -1, meaning all debug logs are dropped 42 // (ignored). 43 // The name of the new logger is given by name. This name is used to remotely 44 // identify the logger for SRPC methods such as Logger.SetDebugLevel. The first 45 // or primary logger should be created with name "" (the empty string). 46 func New(name string) *Logger { 47 flags := log.LstdFlags 48 if *logSubseconds { 49 flags |= log.Lmicroseconds 50 } 51 return newLogger(name, logbuf.GetStandardOptions(), flags) 52 } 53 54 // NewWithFlags will create a Logger which has an internal log buffer (see the 55 // lib/logbuf package). It implements the log.DebugLogger interface. 56 // By default, the max debug level is -1, meaning all debug logs are dropped 57 // (ignored). 58 // The name of the new logger is given by name. This name is used to remotely 59 // identify the logger for RPC methods such as Logger.SetDebugLevel. The first 60 // or primary logger should be created with name "" (the empty string). 61 func NewWithFlags(name string, flags int) *Logger { 62 return newLogger(name, logbuf.GetStandardOptions(), flags) 63 } 64 65 // NewWithOptions will create a Logger which has an internal log buffer (see the 66 // lib/logbuf package). It implements the log.DebugLogger interface. 67 // By default, the max debug level is -1, meaning all debug logs are dropped 68 // (ignored). 69 // The name of the new logger is given by name. This name is used to remotely 70 // identify the logger for RPC methods such as Logger.SetDebugLevel. The first 71 // or primary logger should be created with name "" (the empty string). 72 func NewWithOptions(name string, options logbuf.Options, flags int) *Logger { 73 return newLogger(name, options, flags) 74 } 75 76 // Debug will call the Print method if level is less than or equal to the max 77 // debug level for the Logger. 78 func (l *Logger) Debug(level uint8, v ...interface{}) { 79 l.debug(int16(level), v...) 80 } 81 82 // Debugf will call the Printf method if level is less than or equal to the max 83 // debug level for the Logger. 84 func (l *Logger) Debugf(level uint8, format string, v ...interface{}) { 85 l.debugf(int16(level), format, v...) 86 } 87 88 // Debugln will call the Println method if level is less than or equal to the 89 // max debug level for the Logger. 90 func (l *Logger) Debugln(level uint8, v ...interface{}) { 91 l.debugln(int16(level), v...) 92 } 93 94 // GetLevel gets the current maximum debug level. 95 func (l *Logger) GetLevel() int16 { 96 return l.level 97 } 98 99 // Fatal is equivalent to Print() followed by a call to os.Exit(1). 100 func (l *Logger) Fatal(v ...interface{}) { 101 l.fatals(fmt.Sprint(v...)) 102 } 103 104 // Fatalf is equivalent to Printf() followed by a call to os.Exit(1). 105 func (l *Logger) Fatalf(format string, v ...interface{}) { 106 l.fatals(fmt.Sprintf(format, v...)) 107 } 108 109 // Fatalln is equivalent to Println() followed by a call to os.Exit(1). 110 func (l *Logger) Fatalln(v ...interface{}) { 111 l.fatals(fmt.Sprintln(v...)) 112 } 113 114 // Flush flushes the open log file (if one is open). This should only be called 115 // just prior to process termination. The log file is automatically flushed 116 // after short periods of inactivity. 117 func (l *Logger) Flush() error { 118 return l.circularBuffer.Flush() 119 } 120 121 // Panic is equivalent to Print() followed by a call to panic(). 122 func (l *Logger) Panic(v ...interface{}) { 123 l.panics(fmt.Sprint(v...)) 124 } 125 126 // Panicf is equivalent to Printf() followed by a call to panic(). 127 func (l *Logger) Panicf(format string, v ...interface{}) { 128 l.panics(fmt.Sprintf(format, v...)) 129 } 130 131 // Panicln is equivalent to Println() followed by a call to panic(). 132 func (l *Logger) Panicln(v ...interface{}) { 133 l.panics(fmt.Sprintln(v...)) 134 } 135 136 // Print prints to the logger. Arguments are handled in the manner of fmt.Print. 137 func (l *Logger) Print(v ...interface{}) { 138 l.prints(fmt.Sprint(v...)) 139 } 140 141 // Printf prints to the logger. Arguments are handled in the manner of 142 // fmt.Printf. 143 func (l *Logger) Printf(format string, v ...interface{}) { 144 l.prints(fmt.Sprintf(format, v...)) 145 } 146 147 // Println prints to the logger. Arguments are handled in the manner of 148 // fmt.Println. 149 func (l *Logger) Println(v ...interface{}) { 150 l.prints(fmt.Sprintln(v...)) 151 } 152 153 // SetAccessChecker sets the function that is called when SRPC methods are 154 // called for the Logger. This allows the application to control which users or 155 // groups are permitted to remotely control the Logger. 156 func (l *Logger) SetAccessChecker( 157 accessChecker func(method string, authInfo *srpc.AuthInformation) bool) { 158 l.accessChecker = accessChecker 159 } 160 161 // SetLevel sets the maximum debug level. A negative level will cause all debug 162 // messages to be dropped. 163 func (l *Logger) SetLevel(maxLevel int16) { 164 l.setLevel(maxLevel) 165 } 166 167 // WriteHtml will write the contents of the internal log buffer to writer, with 168 // appropriate HTML markups. 169 func (l *Logger) WriteHtml(writer io.Writer) { 170 l.circularBuffer.WriteHtml(writer) 171 }