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}