Skip to content

Commit 7cf1a5e

Browse files
authored
Merge pull request #27 from StephanHCB/issue-26-too-many-warns
feat(#26): allow squelching warn logs
2 parents 177d92f + affb835 commit 7cf1a5e

File tree

3 files changed

+111
-5
lines changed

3 files changed

+111
-5
lines changed

implementation/requestlogging/requestlogging.go

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,86 @@ package aurestlogging
33
import (
44
"context"
55
aulogging "github.com/StephanHCB/go-autumn-logging"
6+
auloggingapi "github.com/StephanHCB/go-autumn-logging/api"
67
aurestclientapi "github.com/StephanHCB/go-autumn-restclient/api"
78
aurestnontripping "github.com/StephanHCB/go-autumn-restclient/implementation/errors/nontrippingerror"
89
"time"
910
)
1011

12+
// RequestLoggingOptions allows overriding the log functions used.
13+
//
14+
// This allows easily changing the log level when setting up request logging.
15+
//
16+
// important: do not cache the LeveledLoggingImplementation, create one each time, or some loggers may use
17+
// cached values.
18+
type RequestLoggingOptions struct {
19+
BeforeRequest func(ctx context.Context) auloggingapi.LeveledLoggingImplementation
20+
Success func(ctx context.Context) auloggingapi.LeveledLoggingImplementation
21+
Failure func(ctx context.Context) auloggingapi.LeveledLoggingImplementation
22+
}
23+
24+
func Debug(ctx context.Context) auloggingapi.LeveledLoggingImplementation {
25+
return aulogging.Logger.Ctx(ctx).Debug()
26+
}
27+
28+
func Info(ctx context.Context) auloggingapi.LeveledLoggingImplementation {
29+
return aulogging.Logger.Ctx(ctx).Info()
30+
}
31+
32+
func Warn(ctx context.Context) auloggingapi.LeveledLoggingImplementation {
33+
return aulogging.Logger.Ctx(ctx).Warn()
34+
}
35+
1136
type RequestLoggingImpl struct {
1237
Wrapped aurestclientapi.Client
38+
Options RequestLoggingOptions
39+
}
40+
41+
func NewWithOptions(wrapped aurestclientapi.Client, opts RequestLoggingOptions) aurestclientapi.Client {
42+
instance := &RequestLoggingImpl{
43+
Wrapped: wrapped,
44+
Options: RequestLoggingOptions{
45+
BeforeRequest: Debug,
46+
Success: Info,
47+
Failure: Warn,
48+
},
49+
}
50+
if opts.BeforeRequest != nil {
51+
instance.Options.BeforeRequest = opts.BeforeRequest
52+
}
53+
if opts.Success != nil {
54+
instance.Options.Success = opts.Success
55+
}
56+
if opts.Failure != nil {
57+
instance.Options.Failure = opts.Failure
58+
}
59+
return instance
1360
}
1461

1562
func New(wrapped aurestclientapi.Client) aurestclientapi.Client {
1663
return &RequestLoggingImpl{
1764
Wrapped: wrapped,
65+
Options: RequestLoggingOptions{
66+
BeforeRequest: Debug,
67+
Success: Info,
68+
Failure: Warn,
69+
},
1870
}
1971
}
2072

2173
func (c *RequestLoggingImpl) Perform(ctx context.Context, method string, requestUrl string, requestBody interface{}, response *aurestclientapi.ParsedResponse) error {
22-
aulogging.Logger.Ctx(ctx).Debug().Printf("downstream %s %s...", method, requestUrl)
74+
c.Options.BeforeRequest(ctx).Printf("downstream %s %s...", method, requestUrl)
2375
before := time.Now()
2476
err := c.Wrapped.Perform(ctx, method, requestUrl, requestBody, response)
2577
millis := time.Now().Sub(before).Milliseconds()
2678
if err != nil {
2779
if aurestnontripping.Is(err) {
28-
aulogging.Logger.Ctx(ctx).Warn().WithErr(err).Printf("downstream %s %s -> %d FAILED (%d ms) (nontripping)", method, requestUrl, response.Status, millis)
80+
c.Options.Failure(ctx).WithErr(err).Printf("downstream %s %s -> %d FAILED (%d ms) (nontripping)", method, requestUrl, response.Status, millis)
2981
} else {
30-
aulogging.Logger.Ctx(ctx).Warn().WithErr(err).Printf("downstream %s %s -> %d FAILED (%d ms)", method, requestUrl, response.Status, millis)
82+
c.Options.Failure(ctx).WithErr(err).Printf("downstream %s %s -> %d FAILED (%d ms)", method, requestUrl, response.Status, millis)
3183
}
3284
} else {
33-
aulogging.Logger.Ctx(ctx).Info().Printf("downstream %s %s -> %d OK (%d ms)", method, requestUrl, response.Status, millis)
85+
c.Options.Success(ctx).Printf("downstream %s %s -> %d OK (%d ms)", method, requestUrl, response.Status, millis)
3486
}
3587
return err
3688
}

implementation/retry/retry.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ import (
77
"time"
88
)
99

10+
type RetryOptions struct {
11+
RepeatCount uint8
12+
13+
BeforeRetryOrNil aurestclientapi.BeforeRetryCallback
14+
15+
SilenceGivingUp bool
16+
}
17+
1018
type RetryImpl struct {
1119
Wrapped aurestclientapi.Client
1220
RepeatCount uint8
@@ -16,6 +24,28 @@ type RetryImpl struct {
1624

1725
RetryingMetricsCallback aurestclientapi.MetricsCallbackFunction
1826
GivingUpMetricsCallback aurestclientapi.MetricsCallbackFunction
27+
28+
SilenceGivingUp bool
29+
}
30+
31+
func NewWithOptions(
32+
wrapped aurestclientapi.Client,
33+
condition aurestclientapi.RetryConditionCallback,
34+
opts RetryOptions,
35+
) aurestclientapi.Client {
36+
repeatCount := uint8(2)
37+
if opts.RepeatCount > 0 {
38+
repeatCount = opts.RepeatCount
39+
}
40+
return &RetryImpl{
41+
Wrapped: wrapped,
42+
RepeatCount: repeatCount,
43+
RetryCondition: condition,
44+
BeforeRetry: opts.BeforeRetryOrNil,
45+
RetryingMetricsCallback: doNothingMetricsCallback,
46+
GivingUpMetricsCallback: doNothingMetricsCallback,
47+
SilenceGivingUp: opts.SilenceGivingUp,
48+
}
1949
}
2050

2151
func New(
@@ -69,7 +99,9 @@ func (c *RetryImpl) Perform(ctx context.Context, method string, requestUrl strin
6999
// (*)
70100
if attempt == c.RepeatCount+1 {
71101
c.GivingUpMetricsCallback(ctx, method, requestUrl, response.Status, err, 0, 0)
72-
aulogging.Logger.Ctx(ctx).Warn().WithErr(err).Printf("giving up on %s %s after attempt %d", method, requestUrl, attempt)
102+
if !c.SilenceGivingUp {
103+
aulogging.Logger.Ctx(ctx).Warn().WithErr(err).Printf("giving up on %s %s after attempt %d", method, requestUrl, attempt)
104+
}
73105
return err
74106
}
75107
} else {

implementation/retry/retry_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,28 @@ func TestFailWithRetry(t *testing.T) {
127127
require.Equal(t, []string{r, r, r, r}, aurestcapture.GetRecording(mock))
128128
}
129129

130+
func TestFailWithRetryWithOpts(t *testing.T) {
131+
aulogging.SetupNoLoggerForTesting()
132+
133+
mock := tstMock()
134+
cut := NewWithOptions(mock,
135+
func(ctx context.Context, response *aurestclientapi.ParsedResponse, err error) bool {
136+
return true
137+
},
138+
RetryOptions{
139+
BeforeRetryOrNil: nil,
140+
SilenceGivingUp: true,
141+
},
142+
)
143+
144+
response := &aurestclientapi.ParsedResponse{}
145+
err := cut.Perform(context.Background(), "GET", "http://err", nil, response)
146+
require.NotNil(t, err)
147+
require.Equal(t, "some transport error", err.Error())
148+
r := "GET http://err <nil>"
149+
require.Equal(t, []string{r, r, r}, aurestcapture.GetRecording(mock))
150+
}
151+
130152
func TestAbortRetry(t *testing.T) {
131153
aulogging.SetupNoLoggerForTesting()
132154

0 commit comments

Comments
 (0)