forked from andygrunwald/go-jira
-
Notifications
You must be signed in to change notification settings - Fork 1
/
log.go
114 lines (102 loc) · 3.46 KB
/
log.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
package jira
import (
"context"
"io"
"log/slog"
"os"
)
const (
levelTrace = slog.Level(-8)
levelDebug = slog.LevelDebug
levelInfo = slog.LevelInfo
levelWarning = slog.LevelWarn
levelError = slog.LevelError
levelPanic = slog.Level(12)
levelFatal = slog.Level(16)
// logLevelEnvKey is the name of the environment variable whose value defines the logging level of
// the logger used by the default client.
logLevelEnvKey = "VERBOSITY"
)
// logger is the logger used by the default client. It writes log messages to stderr.
var logger = slog.New(newRetryablehttpHandler(os.Stderr))
// retryablehttpHandler handles log messages produced for LeveledLoggers by go-retryablehttp. It
// wraps another handler, mutating the log records it receives before forwarding them on to the
// wrapped handler.
type retryablehttpHandler struct {
// handler is the wrapped handler.
handler slog.Handler
// level is the minimum level for which messages should be logged.
level slog.Level
}
// newRetryablehttpHandler creates a retryablehttpHandler whose minimum logging level is the value
// of the VERBOSITY environment variable.
func newRetryablehttpHandler(output io.Writer) *retryablehttpHandler {
return &retryablehttpHandler{
handler: slog.NewTextHandler(output, nil),
level: defaultLogLevel(),
}
}
// Enabled reports whether the handler handles records at the given level. The handler ignores
// records whose level is lower.
//
// Enabled is called before Handle for performance reasons. Because retryablehttpHandler changes the
// level of some messages in Handle, records cannot be rejected at this point solely because of
// their level, so Enabled always returns true. However, Handle will only forward them on to the
// wrapped handler if their level is at least h.level.
func (h *retryablehttpHandler) Enabled(_ context.Context, _ slog.Level) bool {
return true
}
// WithAttrs returns a new retryablehttpHandler whose attributes consists of h's attributes followed
// by attrs.
func (h *retryablehttpHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
return &retryablehttpHandler{
handler: h.handler.WithAttrs(attrs),
level: h.level,
}
}
// WithGroup returns a new retryablehttpHandler with the given group appended to the receiver's
// existing groups.
func (h *retryablehttpHandler) WithGroup(name string) slog.Handler {
return &retryablehttpHandler{
handler: h.handler.WithGroup(name),
level: h.level,
}
}
// Handle processes a record created by a retryablehttp.Client and potentially forwards it on to the
// wrapped handler.
//
// Handle mutates records as follows:
// - records with a "retrying request" message (which are created by retryablehttp.Client when a
// request fails due to a server-side error or a retryable client-side error, e.g. when the Jira
// API's rate limits have been exceeded) are increased from debug level to warning level, to make
// them more visible.
func (h *retryablehttpHandler) Handle(ctx context.Context, r slog.Record) error {
if r.Message == "retrying request" {
r = r.Clone()
r.Level = levelWarning
}
if r.Level < h.level {
return nil
}
return h.handler.Handle(ctx, r)
}
func defaultLogLevel() slog.Level {
switch os.Getenv(logLevelEnvKey) {
case "TRACE":
return levelTrace
case "DEBUG":
return levelDebug
case "INFO":
return levelInfo
case "WARNING":
return levelWarning
case "ERROR":
return levelError
case "PANIC":
return levelPanic
case "FATAL":
return levelFatal
default:
return levelInfo
}
}