build: update golangci-lint to v2.12.2 with canonical config
Add the canonical .golangci.yml (v2 schema, all linters enabled with a
small documented disable list) and pin the Dockerfile lint stage to
golangci/golangci-lint:v2.12.2 by tag and digest, replacing the old
v1.64.8 digest-only pin.
Fix all findings surfaced by the v1 to v2 jump without changing any
exported signatures or behavior:
- add package and exported-symbol doc comments (revive)
- rename unused handler parameters to underscore (revive)
- check or explicitly discard error returns (errcheck, errchkjson)
- wrap errors with %w instead of %v (err113)
- use http.NewRequestWithContext instead of http.Post (noctx)
- replace fmt.Println with fmt.Fprintln(os.Stdout, ...) (forbidigo)
- name magic numbers as constants (mnd)
- add explicit slog.LevelDebug case (exhaustive)
- interface{} to any (modernize)
- move tests to the simplelog_test package (testpackage) and add
t.Parallel() (paralleltest)
- move NewWebhookHandler above its methods (funcorder)
- whitespace, line-length, and blank-line fixes (wsl_v5, whitespace,
nlreturn, lll, embeddedstructfieldcheck)
- nolint with justification for the intentional init/global design
(gochecknoinits, gochecknoglobals) and interface-returning
constructor (ireturn)
This commit is contained in:
@@ -10,38 +10,64 @@ import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// WebhookHandler POSTs each log record as JSON to a configured webhook
|
||||
// URL.
|
||||
type WebhookHandler struct {
|
||||
webhookURL string
|
||||
}
|
||||
|
||||
func (w *WebhookHandler) Enabled(ctx context.Context, level slog.Level) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *WebhookHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *WebhookHandler) WithGroup(name string) slog.Handler {
|
||||
return w
|
||||
}
|
||||
|
||||
// NewWebhookHandler returns a WebhookHandler that delivers records to
|
||||
// the given URL, validating the URL first.
|
||||
func NewWebhookHandler(webhookURL string) (*WebhookHandler, error) {
|
||||
if _, err := url.ParseRequestURI(webhookURL); err != nil {
|
||||
return nil, fmt.Errorf("invalid webhook URL: %v", err)
|
||||
_, err := url.ParseRequestURI(webhookURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid webhook URL: %w", err)
|
||||
}
|
||||
|
||||
return &WebhookHandler{webhookURL: webhookURL}, nil
|
||||
}
|
||||
|
||||
// Enabled reports whether the handler processes records at the given
|
||||
// level; it always returns true.
|
||||
func (w *WebhookHandler) Enabled(_ context.Context, _ slog.Level) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// WithAttrs returns the handler unchanged; attributes are not rendered.
|
||||
func (w *WebhookHandler) WithAttrs(_ []slog.Attr) slog.Handler {
|
||||
return w
|
||||
}
|
||||
|
||||
// WithGroup returns the handler unchanged; groups are not rendered.
|
||||
func (w *WebhookHandler) WithGroup(_ string) slog.Handler {
|
||||
return w
|
||||
}
|
||||
|
||||
// Handle marshals the record to JSON and POSTs it to the webhook URL.
|
||||
func (w *WebhookHandler) Handle(ctx context.Context, record slog.Record) error {
|
||||
jsonData, err := json.Marshal(record)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error marshaling event: %v", err)
|
||||
return fmt.Errorf("error marshaling event: %w", err)
|
||||
}
|
||||
response, err := http.Post(w.webhookURL, "application/json", bytes.NewBuffer(jsonData))
|
||||
|
||||
request, err := http.NewRequestWithContext(
|
||||
ctx,
|
||||
http.MethodPost,
|
||||
w.webhookURL,
|
||||
bytes.NewReader(jsonData),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating webhook request: %w", err)
|
||||
}
|
||||
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
response, err := http.DefaultClient.Do(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
defer func() { _ = response.Body.Close() }()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user