Skip to content

Commit a35f6d6

Browse files
authored
Improve splunk output errors (#608)
1 parent 6de60c8 commit a35f6d6

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

plugin/output/splunk/splunk.go

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"io"
1010
"net/http"
11+
"strconv"
1112
"time"
1213

1314
"github.com/ozontech/file.d/cfg"
@@ -37,7 +38,7 @@ type Plugin struct {
3738
controller pipeline.OutputPluginController
3839

3940
// plugin metrics
40-
sendErrorMetric prometheus.Counter
41+
sendErrorMetric *prometheus.CounterVec
4142
}
4243

4344
// ! config-params
@@ -172,7 +173,11 @@ func (p *Plugin) Start(config pipeline.AnyConfig, params *pipeline.OutputPluginP
172173
}
173174

174175
func (p *Plugin) registerMetrics(ctl *metric.Ctl) {
175-
p.sendErrorMetric = ctl.RegisterCounter("output_splunk_send_error", "Total splunk send errors")
176+
p.sendErrorMetric = ctl.RegisterCounterVec(
177+
"output_splunk_send_error",
178+
"Total splunk send errors",
179+
"status_code",
180+
)
176181
}
177182

178183
func (p *Plugin) Stop() {
@@ -209,10 +214,15 @@ func (p *Plugin) out(workerData *pipeline.WorkerData, batch *pipeline.Batch) err
209214

210215
p.logger.Debugf("trying to send: %s", outBuf)
211216

212-
err := p.send(outBuf)
217+
code, err := p.send(outBuf)
213218
if err != nil {
214-
p.sendErrorMetric.Inc()
219+
p.sendErrorMetric.WithLabelValues(strconv.Itoa(code)).Inc()
215220
p.logger.Errorf("can't send data to splunk address=%s: %s", p.config.Endpoint, err.Error())
221+
222+
// skip retries for bad request
223+
if code == http.StatusBadRequest {
224+
return nil
225+
}
216226
} else {
217227
p.logger.Debugf("successfully sent: %s", outBuf)
218228
}
@@ -234,46 +244,46 @@ func (p *Plugin) newClient(timeout time.Duration) http.Client {
234244
}
235245
}
236246

237-
func (p *Plugin) send(data []byte) error {
247+
func (p *Plugin) send(data []byte) (int, error) {
238248
r := bytes.NewReader(data)
239249
// todo pass context from parent.
240250
req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, p.config.Endpoint, r)
241251
if err != nil {
242-
return fmt.Errorf("can't create request: %w", err)
252+
return 0, fmt.Errorf("can't create request: %w", err)
243253
}
244254

245255
req.Header.Set("Authorization", "Splunk "+p.config.Token)
246256
resp, err := p.client.Do(req)
247257
if err != nil {
248-
return fmt.Errorf("can't send request: %w", err)
258+
return 0, fmt.Errorf("can't send request: %w", err)
249259
}
250260
defer func(Body io.ReadCloser) {
251261
_ = Body.Close()
252262
}(resp.Body)
253263

254-
if resp.StatusCode != http.StatusOK {
255-
return fmt.Errorf("can't send request: %s", resp.Status)
256-
}
257-
258264
b, err := io.ReadAll(resp.Body)
259265
if err != nil {
260-
return fmt.Errorf("can't read response: %w", err)
266+
return resp.StatusCode, fmt.Errorf("can't read response: %w", err)
267+
}
268+
269+
if resp.StatusCode != http.StatusOK {
270+
return resp.StatusCode, fmt.Errorf("bad response: code=%s, body=%s", resp.Status, b)
261271
}
262272

263273
root, err := insaneJSON.DecodeBytes(b)
264274
defer insaneJSON.Release(root)
265275
if err != nil {
266-
return fmt.Errorf("can't decode response: %w", err)
276+
return resp.StatusCode, fmt.Errorf("can't decode response: %w", err)
267277
}
268278

269279
code := root.Dig("code")
270280
if code == nil {
271-
return fmt.Errorf("invalid response format, expecting json with 'code' field, got: %s", string(b))
281+
return resp.StatusCode, fmt.Errorf("invalid response format, expecting json with 'code' field, got: %s", string(b))
272282
}
273283

274284
if code.AsInt() > 0 {
275-
return fmt.Errorf("error while sending to splunk: %s", string(b))
285+
return resp.StatusCode, fmt.Errorf("error while sending to splunk: %s", string(b))
276286
}
277287

278-
return nil
288+
return resp.StatusCode, nil
279289
}

0 commit comments

Comments
 (0)