From e275be70e2dc707ec53e20383c16397eb6495b40 Mon Sep 17 00:00:00 2001 From: Alvar Penning Date: Fri, 2 Aug 2024 16:08:24 +0200 Subject: [PATCH] webhook: Log HTTP response in case of an error It might be useful to have additional debug logging of the HTTP response if the status code is outside the expected range. With this change, a truncated output will now be logged. --- cmd/channels/webhook/main.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/cmd/channels/webhook/main.go b/cmd/channels/webhook/main.go index 90a72701..e1d82e2b 100644 --- a/cmd/channels/webhook/main.go +++ b/cmd/channels/webhook/main.go @@ -8,6 +8,7 @@ import ( "github.com/icinga/icinga-notifications/pkg/plugin" "io" "net/http" + "os" "slices" "strconv" "strings" @@ -142,7 +143,7 @@ func (ch *Webhook) SetConfig(jsonStr json.RawMessage) error { } func (ch *Webhook) SendNotification(req *plugin.NotificationRequest) error { - var urlBuff, reqBodyBuff bytes.Buffer + var urlBuff, reqBodyBuff, respBuffer bytes.Buffer if err := ch.tmplUrl.Execute(&urlBuff, req); err != nil { return fmt.Errorf("cannot execute URL template: %w", err) } @@ -158,10 +159,22 @@ func (ch *Webhook) SendNotification(req *plugin.NotificationRequest) error { if err != nil { return err } - _, _ = io.Copy(io.Discard, httpResp.Body) - _ = httpResp.Body.Close() + + defer func() { + _, _ = io.Copy(io.Discard, httpResp.Body) + _ = httpResp.Body.Close() + }() + + // Limit response to 1 MiB as it will be logged in case of an unexpected status code. + limitedRespReader := io.LimitReader(httpResp.Body, 1024*1024) + if _, err := io.Copy(&respBuffer, limitedRespReader); err != nil { + return fmt.Errorf("cannot read response: %w", err) + } if !slices.Contains(ch.respStatusCodes, httpResp.StatusCode) { + _, _ = fmt.Fprintf(os.Stderr, "received unexpected HTTP response code %d with body %q\n", + httpResp.StatusCode, respBuffer.String()) + return fmt.Errorf("unaccepted HTTP response status code %d not in %v", httpResp.StatusCode, ch.respStatusCodes) }