-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathlogging.go
72 lines (63 loc) · 2.15 KB
/
logging.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package pgmigrate
import (
"context"
"fmt"
"testing"
)
// LogLevel represents the severity of the log message, and is one of
// - [LogLevelDebug]
// - [LogLevelInfo]
// - [LogLevelError]
type LogLevel string
const (
LogLevelDebug LogLevel = "debug"
LogLevelInfo LogLevel = "info"
LogLevelError LogLevel = "error"
LogLevelWarning LogLevel = "warning"
)
// LogField holds a key/value pair for structured logging.
type LogField struct {
Key string
Value any
}
// Logger is a generic logging interface so that you can easily use pgmigrate
// with your existing structured ogging solution -- hopefully it is not
// difficult for you to write an adapter.
type Logger interface {
Log(context.Context, LogLevel, string, ...LogField)
}
// Helper is an optional interface that your logger can implement to help
// make debugging and stacktraces easier to understand, primarily in tests.
// If a [Logger] implements this interface, pgmigrate will call Helper()
// in its own helper methods for writing to your logger, with the goal of
// omitting pgmigrate's helper methods from your stacktraces.
//
// For instance, the [TestLogger] we provide embeds a [testing.T], which
// implements Helper().
//
// You do *not* need to implement this interface in order for pgmigrate
// to successfully use your logger.
type Helper interface {
Helper()
}
// NewTestLogger returns a [TestLogger], which is a [Logger] and [Helper] (due
// to the embedded [testing.T]) that writes all logs to a given test's output in
// such a way that stack traces are correctly preserved.
func NewTestLogger(t *testing.T) TestLogger {
return TestLogger{t}
}
// TestLogger implements the [Logger] and [Helper] interface and writes all logs
// to a given test's output in such a way that stack traces are correctly
// preserved.
type TestLogger struct {
*testing.T
}
// Log writes a message to a given test's output in pseudo key=value form.
func (t TestLogger) Log(_ context.Context, level LogLevel, msg string, fields ...LogField) {
t.Helper()
line := fmt.Sprintf("%s: %s", level, msg)
for _, field := range fields {
line = fmt.Sprintf("%s %s=%v", line, field.Key, field.Value)
}
t.T.Log(line)
}