-
Notifications
You must be signed in to change notification settings - Fork 22
/
logger.go
122 lines (103 loc) · 3.04 KB
/
logger.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package ksql
import (
"context"
"encoding/json"
"fmt"
)
// This variable is only used during tests:
var logPrinter = fmt.Println
var _ LoggerFn = ErrorLogger
// ErrorLogger is a builtin logger that can be passed to
// ksql.InjectLogger() to only log when an error occurs.
//
// Note that only errors that happen after KSQL sends the
// query to the backend adapter will be logged.
// Any errors that happen before that will not be logged.
func ErrorLogger(ctx context.Context, values LogValues) {
if values.Err == nil {
return
}
Logger(ctx, values)
}
var _ LoggerFn = Logger
// Logger is a builtin logger that can be passed to
// ksql.InjectLogger() to log every query and query errors.
//
// Note that only errors that happen after KSQL sends the
// query to the backend adapter will be logged.
// Any errors that happen before that will not be logged.
func Logger(ctx context.Context, values LogValues) {
b, _ := json.Marshal(values)
logPrinter(string(b))
}
type loggerKey struct{}
// LogValues is the argument type of ksql.LoggerFn which contains
// the data available for logging whenever a query is executed.
type LogValues struct {
Query string
Params []interface{}
Err error
}
func (l LogValues) MarshalJSON() ([]byte, error) {
var out struct {
Query string `json:"query"`
Params []interface{} `json:"params"`
Err string `json:"error,omitempty"`
}
out.Query = l.Query
out.Params = l.Params
// Force it to print Params: [], instead of Params: null
if out.Params == nil {
out.Params = []interface{}{}
}
if l.Err != nil {
out.Err = l.Err.Error()
}
return json.Marshal(out)
}
// LoggerFn is a the type of function received as
// argument of the ksql.InjectLogger function.
type LoggerFn func(ctx context.Context, values LogValues)
type loggerFn func(ctx context.Context, query string, params []interface{}, err error)
// InjectLogger is a debugging tool that allows the user to force
// KSQL to log the query, query params and error response whenever
// a query is executed.
//
// Example Usage:
//
// // After injecting a logger into `ctx` all subsequent queries
// // that use this context will be logged.
// ctx = ksql.InjectLogger(ctx, ksql.Logger)
//
// // All the calls below will cause KSQL to log the queries:
// var user User
// db.Insert(ctx, usersTable, &user)
//
// user.Name = "NewName"
// db.Patch(ctx, usersTable, &user)
//
// var users []User
// db.Query(ctx, &users, someQuery, someParams...)
// db.QueryOne(ctx, &user, someQuery, someParams...)
//
// db.Delete(ctx, usersTable, user.ID)
//
func InjectLogger(
ctx context.Context,
logFn LoggerFn,
) context.Context {
return context.WithValue(ctx, loggerKey{}, loggerFn(func(ctx context.Context, query string, params []interface{}, err error) {
logFn(ctx, LogValues{
Query: query,
Params: params,
Err: err,
})
}))
}
func ctxLog(ctx context.Context, query string, params []interface{}, err *error) {
l := ctx.Value(loggerKey{})
if l == nil {
return
}
l.(loggerFn)(ctx, query, params, *err)
}