mirror of
https://github.com/EZ-Api/ez-api.git
synced 2026-01-13 17:47:51 +00:00
Implement webhook notifications for log error threshold alerts with configurable thresholds, time windows, and cooldown periods. - Add LogWebhookService with Redis-backed configuration storage - Add admin endpoints for webhook config management (GET/PUT) - Trigger webhook notifications when error count exceeds threshold - Support status code threshold and error message detection - Include sample log record data in webhook payload
61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"sync/atomic"
|
|
"testing"
|
|
|
|
"github.com/alicebob/miniredis/v2"
|
|
"github.com/ez-api/ez-api/internal/model"
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
func TestLogWebhookServiceNotifyThreshold(t *testing.T) {
|
|
mr := miniredis.RunT(t)
|
|
rdb := redis.NewClient(&redis.Options{Addr: mr.Addr()})
|
|
svc := NewLogWebhookService(rdb)
|
|
|
|
var hits int64
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
atomic.AddInt64(&hits, 1)
|
|
w.WriteHeader(http.StatusOK)
|
|
}))
|
|
defer srv.Close()
|
|
|
|
cfg := LogWebhookConfig{
|
|
Enabled: true,
|
|
URL: srv.URL,
|
|
Threshold: 2,
|
|
WindowSeconds: 60,
|
|
CooldownSeconds: 300,
|
|
StatusCodeThreshold: 500,
|
|
}
|
|
if _, err := svc.SetConfig(context.Background(), cfg); err != nil {
|
|
t.Fatalf("set config: %v", err)
|
|
}
|
|
|
|
rec := model.LogRecord{StatusCode: 500, ErrorMessage: "upstream error"}
|
|
svc.NotifyIfNeeded(context.Background(), rec)
|
|
svc.NotifyIfNeeded(context.Background(), rec)
|
|
|
|
if atomic.LoadInt64(&hits) != 1 {
|
|
t.Fatalf("expected 1 webhook hit, got %d", hits)
|
|
}
|
|
}
|
|
|
|
func TestLogWebhookServiceDefaults(t *testing.T) {
|
|
mr := miniredis.RunT(t)
|
|
rdb := redis.NewClient(&redis.Options{Addr: mr.Addr()})
|
|
svc := NewLogWebhookService(rdb)
|
|
|
|
cfg, err := svc.GetConfig(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("get config: %v", err)
|
|
}
|
|
if cfg.Threshold != defaultWebhookThreshold || cfg.WindowSeconds != defaultWebhookWindow {
|
|
t.Fatalf("unexpected defaults: %+v", cfg)
|
|
}
|
|
}
|