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  }