feat: propagate alert forwarding trace ids

This commit is contained in:
zxr
2026-07-21 17:19:39 +08:00
parent c263825cbc
commit 567dda70c0
3 changed files with 26 additions and 5 deletions

View File

@@ -2,6 +2,7 @@ package ingest
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
@@ -14,7 +15,10 @@ import (
"git.apinb.com/ops/logs/internal/config"
)
const alertResponseBodyLimit = 1 << 20
const (
alertResponseBodyLimit = 1 << 20
maxAlertTraceIDLength = 96
)
var errAlertForwardDisabled = errors.New("Alert 转发未启用或 base_url 为空")
@@ -36,6 +40,7 @@ type AlertReceiveBody struct {
PolicyID uint `json:"policy_id"`
State string `json:"state,omitempty"`
SourceEventKey string `json:"source_event_key"`
TraceID string `json:"trace_id"`
OccurredAt time.Time `json:"occurred_at"`
RawData json.RawMessage `json:"raw_data"`
}
@@ -70,11 +75,12 @@ func forwardAlert(body AlertReceiveBody) error {
if body.PolicyID == 0 && cfg.DefaultPolicyID > 0 {
body.PolicyID = cfg.DefaultPolicyID
}
body.TraceID = ensureAlertTraceID(body.TraceID, body.SourceEventKey)
raw, err := json.Marshal(body)
if err != nil {
return err
}
result, err := postAlertPayload(cfg, "/Alert/v1/alerts/receive", raw)
result, err := postAlertPayload(cfg, "/Alert/v1/alerts/receive", raw, body.TraceID)
if err != nil {
return err
}
@@ -101,12 +107,13 @@ func forwardAlert(body AlertReceiveBody) error {
return nil
}
func postAlertPayload(cfg *config.AlertForwardConf, path string, payload []byte) (*alertForwardResponse, error) {
func postAlertPayload(cfg *config.AlertForwardConf, path string, payload []byte, traceID string) (*alertForwardResponse, error) {
req, err := http.NewRequest(http.MethodPost, cfg.BaseURL+path, bytes.NewReader(payload))
if err != nil {
return nil, fmt.Errorf("创建 Alert 转发请求失败:%w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Trace-Id", traceID)
if cfg.InternalKey != "" {
req.Header.Set("X-Internal-Key", cfg.InternalKey)
}
@@ -173,9 +180,19 @@ func buildRawEventIngestBody(body AlertReceiveBody, parseStatus string) RawEvent
Annotations: annotations,
ParseStatus: parseStatus,
RawPayload: body.RawData,
TraceID: ensureAlertTraceID(body.TraceID, body.SourceEventKey),
}
}
func ensureAlertTraceID(traceID, sourceEventKey string) string {
traceID = strings.TrimSpace(traceID)
if traceID != "" && len(traceID) <= maxAlertTraceIDLength {
return traceID
}
sum := sha256.Sum256([]byte(strings.TrimSpace(sourceEventKey)))
return hex.EncodeToString(sum[:16])
}
func validFingerprint(value string) bool {
if len(value) != 64 {
return false

View File

@@ -25,6 +25,7 @@ const (
)
func enqueueAlertWithDB(db *gorm.DB, logEventID uint, body AlertReceiveBody) (uint, error) {
body.TraceID = ensureAlertTraceID(body.TraceID, body.SourceEventKey)
payload, err := json.Marshal(body)
if err != nil {
return 0, err
@@ -193,11 +194,12 @@ func forwardRawEvent(body RawEventIngestBody) error {
if len(body.RawPayload) == 0 {
return fmt.Errorf("raw_payload 不能为空")
}
body.TraceID = ensureAlertTraceID(body.TraceID, body.SourceEventKey)
raw, err := json.Marshal(body)
if err != nil {
return err
}
result, err := postAlertPayload(cfg, "/Alert/v1/raw-events/ingest", raw)
result, err := postAlertPayload(cfg, "/Alert/v1/raw-events/ingest", raw, body.TraceID)
if err != nil {
return err
}

View File

@@ -53,9 +53,10 @@ func BuildReplayRawEventPayload(ev models.LogEvent) (RawEventIngestBody, error)
labels["resource_uid"] = resourceUID
labels["resource_category"] = category
labels["service_identity"] = identity
sourceEventKey := fmt.Sprintf("logs:replay:%d:%d", ev.ID, now.UnixNano())
return RawEventIngestBody{
SourceType: sourceType,
SourceEventKey: fmt.Sprintf("logs:replay:%d:%d", ev.ID, now.UnixNano()),
SourceEventKey: sourceEventKey,
State: "firing",
ResourceUID: resourceUID,
EventTime: now,
@@ -69,6 +70,7 @@ func BuildReplayRawEventPayload(ev models.LogEvent) (RawEventIngestBody, error)
},
ParseStatus: "parsed",
RawPayload: rawBytes,
TraceID: ensureAlertTraceID("", sourceEventKey),
}, nil
}