Skip to content

Commit 1c45c15

Browse files
fix(outputs/plugins/datadog): prevent retry on authentication error
Signed-off-by: Florentin Dubois <florentin.dubois@clever.cloud>
1 parent 1980bf8 commit 1c45c15

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

internal/errors.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package internal
22

3-
import "errors"
3+
import (
4+
"errors"
5+
"fmt"
6+
)
47

58
var (
69
ErrNotConnected = errors.New("not connected")
@@ -61,3 +64,23 @@ func (e *PartialWriteError) Error() string {
6164
func (e *PartialWriteError) Unwrap() error {
6265
return e.Err
6366
}
67+
68+
// HTTPError represents an error from an HTTP API with retry information.
69+
// Use this for HTTP-based output plugins to indicate whether an error
70+
// is retryable (e.g., 5xx server errors) or not (e.g., 4xx client errors).
71+
type HTTPError struct {
72+
Err error
73+
StatusCode int
74+
Retryable bool
75+
}
76+
77+
func (e *HTTPError) Error() string {
78+
if e.Err == nil {
79+
return fmt.Sprintf("HTTP error: status %d", e.StatusCode)
80+
}
81+
return e.Err.Error()
82+
}
83+
84+
func (e *HTTPError) Unwrap() error {
85+
return e.Err
86+
}

plugins/outputs/datadog/datadog.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,20 @@ func (d *Datadog) Write(metrics []telegraf.Metric) error {
189189
if resp.StatusCode < 200 || resp.StatusCode > 209 {
190190
//nolint:errcheck // err can be ignored since it is just for logging
191191
body, _ := io.ReadAll(resp.Body)
192-
return fmt.Errorf("received bad status code, %d: %s", resp.StatusCode, string(body))
192+
// 4xx client errors are not retryable - the request itself is invalid
193+
if resp.StatusCode >= 400 && resp.StatusCode < 500 {
194+
d.Log.Errorf("Client error %d, metrics will be dropped: %s", resp.StatusCode, string(body))
195+
return &internal.HTTPError{
196+
Err: fmt.Errorf("client error %d: metrics dropped", resp.StatusCode),
197+
StatusCode: resp.StatusCode,
198+
Retryable: false,
199+
}
200+
}
201+
return &internal.HTTPError{
202+
Err: fmt.Errorf("received bad status code, %d: %s", resp.StatusCode, string(body)),
203+
StatusCode: resp.StatusCode,
204+
Retryable: true,
205+
}
193206
}
194207

195208
return nil

0 commit comments

Comments
 (0)