code.dwrz.net

Go monorepo.
Log | Files | Refs

logger.go (2463B)


      1 package logging
      2 
      3 import (
      4 	"context"
      5 	"io"
      6 	"log"
      7 )
      8 
      9 // Classification is the type of the log entry's classification name.
     10 type Classification string
     11 
     12 // Set of standard classifications that can be used by clients and middleware
     13 const (
     14 	Warn  Classification = "WARN"
     15 	Debug Classification = "DEBUG"
     16 )
     17 
     18 // Logger is an interface for logging entries at certain classifications.
     19 type Logger interface {
     20 	// Logf is expected to support the standard fmt package "verbs".
     21 	Logf(classification Classification, format string, v ...interface{})
     22 }
     23 
     24 // LoggerFunc is a wrapper around a function to satisfy the Logger interface.
     25 type LoggerFunc func(classification Classification, format string, v ...interface{})
     26 
     27 // Logf delegates the logging request to the wrapped function.
     28 func (f LoggerFunc) Logf(classification Classification, format string, v ...interface{}) {
     29 	f(classification, format, v...)
     30 }
     31 
     32 // ContextLogger is an optional interface a Logger implementation may expose that provides
     33 // the ability to create context aware log entries.
     34 type ContextLogger interface {
     35 	WithContext(context.Context) Logger
     36 }
     37 
     38 // WithContext will pass the provided context to logger if it implements the ContextLogger interface and return the resulting
     39 // logger. Otherwise the logger will be returned as is. As a special case if a nil logger is provided, a Nop logger will
     40 // be returned to the caller.
     41 func WithContext(ctx context.Context, logger Logger) Logger {
     42 	if logger == nil {
     43 		return Nop{}
     44 	}
     45 
     46 	cl, ok := logger.(ContextLogger)
     47 	if !ok {
     48 		return logger
     49 	}
     50 
     51 	return cl.WithContext(ctx)
     52 }
     53 
     54 // Nop is a Logger implementation that simply does not perform any logging.
     55 type Nop struct{}
     56 
     57 // Logf simply returns without performing any action
     58 func (n Nop) Logf(Classification, string, ...interface{}) {
     59 	return
     60 }
     61 
     62 // StandardLogger is a Logger implementation that wraps the standard library logger, and delegates logging to it's
     63 // Printf method.
     64 type StandardLogger struct {
     65 	Logger *log.Logger
     66 }
     67 
     68 // Logf logs the given classification and message to the underlying logger.
     69 func (s StandardLogger) Logf(classification Classification, format string, v ...interface{}) {
     70 	if len(classification) != 0 {
     71 		format = string(classification) + " " + format
     72 	}
     73 
     74 	s.Logger.Printf(format, v...)
     75 }
     76 
     77 // NewStandardLogger returns a new StandardLogger
     78 func NewStandardLogger(writer io.Writer) *StandardLogger {
     79 	return &StandardLogger{
     80 		Logger: log.New(writer, "SDK ", log.LstdFlags),
     81 	}
     82 }