fix: make log alert delivery durable

This commit is contained in:
zxr
2026-07-21 02:32:18 +08:00
parent ce559d5218
commit 6e66bad884
8 changed files with 709 additions and 305 deletions

View File

@@ -23,6 +23,9 @@ func InitData(db *gorm.DB) error {
if db == nil {
return nil
}
if err := backfillDispatchOutboxIDs(db); err != nil {
return err
}
if err := seedDefaultSyslogRules(db); err != nil {
return err
}
@@ -35,6 +38,52 @@ func InitData(db *gorm.DB) error {
return nil
}
func backfillDispatchOutboxIDs(db *gorm.DB) error {
const postgresUpdate = `
WITH latest AS (
SELECT target_event.id AS log_event_id, current_outbox.id, current_outbox.status
FROM logs_events AS target_event
JOIN LATERAL (
SELECT id, status
FROM logs_alert_outbox
WHERE log_event_id = target_event.id
ORDER BY id DESC
LIMIT 1
) AS current_outbox ON TRUE
WHERE target_event.dispatch_outbox_id = 0
)
UPDATE logs_events AS target_event
SET dispatch_outbox_id = latest.id,
dispatch_status = CASE latest.status WHEN 'processing' THEN 'retrying' ELSE latest.status END,
alert_sent = CASE WHEN latest.status = 'sent' THEN TRUE ELSE FALSE END
FROM latest
WHERE target_event.id = latest.log_event_id
AND target_event.dispatch_outbox_id = 0`
const mysqlUpdate = `
UPDATE logs_events AS target_event
JOIN (
SELECT candidate.id AS log_event_id, MAX(outbox.id) AS id
FROM logs_events AS candidate
JOIN logs_alert_outbox AS outbox ON outbox.log_event_id = candidate.id
WHERE candidate.dispatch_outbox_id = 0
GROUP BY candidate.id
) AS latest_id ON latest_id.log_event_id = target_event.id
JOIN logs_alert_outbox AS latest ON latest.id = latest_id.id
SET dispatch_outbox_id = latest.id,
dispatch_status = CASE latest.status WHEN 'processing' THEN 'retrying' ELSE latest.status END,
alert_sent = CASE WHEN latest.status = 'sent' THEN TRUE ELSE FALSE END
WHERE target_event.dispatch_outbox_id = 0`
switch db.Dialector.Name() {
case "postgres":
return db.Exec(postgresUpdate).Error
case "mysql":
return db.Exec(mysqlUpdate).Error
default:
return gorm.ErrUnsupportedDriver
}
}
func seedDefaultSyslogRules(db *gorm.DB) error {
var cnt int64
if err := db.Model(&SyslogRule{}).Count(&cnt).Error; err != nil {