Files
SamWaf/wafqueue/log_split.go
T
samwafgo 64aaab16fa Feat log shared (#1007)
* fix: make archived log shard connections concurrency-safe and recoverable

* fix: build the WebSocket online table before its consumers start

* perf: cap stored payloads, index log lookups by IP and rule, batch IP tag writes

* fix: keep archived log shards readable when the live table gains a column

* feat: merge IP tag history when their database location changes

* refactor: move request payloads out of the access log into their own table

* feat: scope log database export to a time range and selected tiers

* feat: add an IP watchlist that full-captures watched IPs

* feat: split log storage into security events, access rows, and payload tiers

* feat: roll up requests per actor and path into daily analysis tables

* fix:actor key by ip

* feat: add a source and path analysis page over the daily rollups

* feat: exclude chosen source IPs from web log recording

* docs: add upgrade notes for the analysis page and log IP exclusion

* feat: derive the log partition from the time range and look up identifiers across all of them

* feat: add time partition verbs and the period naming they share

* feat: cut log archives per month and expire them by dropping partitions

* feat: manage log partitions, and answer why an IP has no logs

* fix: read archived SQLite log shards read-only and choose tiers by data

* fix: count the live log shard from access_log instead of a stale snapshot

* fix:export db bug

* fix: default backend keep-alive pool (512/128/90s) to stop connect-close churn under load

* chore: gen_swagger.bat outputs json only, syncs doc site, runs route test

* feat: pin web frontend version and embed it into the binary
2026-10-10 14:39:06 +08:00

31 lines
1.1 KiB
Go

package wafqueue
import (
"SamWaf/common/zlog"
"SamWaf/global"
"SamWaf/model"
"gorm.io/gorm/clause"
)
// PayloadKindEvent 安全事件的报文归属(事件全量留报文)。
// 另外两种 sample(采样负样本)/ watch(观察名单)在 log_tier.go。
const PayloadKindEvent = "event"
// storePayloads 写报文表。单独一条语句,且失败只告警:
// 日志行已经落库,报文丢了详情页显示「未留存报文」,比整批日志一起回滚强。
// 跨批次可能撞上同一个 req_uuid(同一请求分两批入队),主键冲突按「保留先到的」跳过。
func storePayloads(payloads []*model.EventPayload) {
if len(payloads) == 0 {
return
}
// 不指定冲突列:三个引擎对"无目标的 DO NOTHING"都认(MySQL 走 INSERT IGNORE),
// 指定了反而要各写各的。这里只有主键一种冲突,无目标正合适。
err := global.GWAF_LOCAL_LOG_DB.
Clauses(clause.OnConflict{DoNothing: true}).
CreateInBatches(payloads, len(payloads)).Error
if err != nil {
zlog.Warn("报文落库失败", "条数", len(payloads), "error", err.Error())
}
}