logger.go

 1package logging
 2
 3import (
 4	"context"
 5	"io"
 6	"log"
 7)
 8
 9// Classification is the type of the log entry's classification name.
10type Classification string
11
12// Set of standard classifications that can be used by clients and middleware
13const (
14	Warn  Classification = "WARN"
15	Debug Classification = "DEBUG"
16)
17
18// Logger is an interface for logging entries at certain classifications.
19type 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.
25type LoggerFunc func(classification Classification, format string, v ...interface{})
26
27// Logf delegates the logging request to the wrapped function.
28func (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.
34type 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.
41func 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.
55type Nop struct{}
56
57// Logf simply returns without performing any action
58func (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.
64type StandardLogger struct {
65	Logger *log.Logger
66}
67
68// Logf logs the given classification and message to the underlying logger.
69func (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
78func NewStandardLogger(writer io.Writer) *StandardLogger {
79	return &StandardLogger{
80		Logger: log.New(writer, "SDK ", log.LstdFlags),
81	}
82}