单二进制三角色 + Dock 适配器 + Swarm stack 达到可部署态;mgr1 实测订阅经 central-proxy bootstrap,探活 alive=41/52。 Co-authored-by: Cursor <cursoragent@cursor.com>
67 lines
1.9 KiB
Go
67 lines
1.9 KiB
Go
// audit.go:合规审计表(denied/redact 记录,design-arch §5.4 / §7.2)。
|
||
package store
|
||
|
||
import (
|
||
"fmt"
|
||
"time"
|
||
|
||
"onesvm.com/onesvm/browser-server/internal/config"
|
||
)
|
||
|
||
// AuditRow 审计记录。
|
||
type AuditRow struct {
|
||
ID int64
|
||
ConsumerID int64 // 0 = 匿名/未认证
|
||
URL string
|
||
RuleID string
|
||
TS time.Time
|
||
}
|
||
|
||
// AuditAppend 写一条审计(能停能报最低限度)。
|
||
func (d *DB) AuditAppend(consumerID int64, url, ruleID string) error {
|
||
_, err := d.raw.Exec(
|
||
`INSERT INTO audit(consumer_id, url, rule_id, ts) VALUES(?, ?, ?, ?)`,
|
||
consumerID, url, ruleID, config.Now().Format(time.RFC3339))
|
||
if err != nil {
|
||
return fmt.Errorf("store: AuditAppend: %w", err)
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// AuditRecent 按时间倒序取最近 n 条(运维排查用,禁 SELECT *)。
|
||
func (d *DB) AuditRecent(n int) ([]AuditRow, error) {
|
||
rows, err := d.raw.Query(
|
||
`SELECT id, consumer_id, url, rule_id, ts FROM audit ORDER BY ts DESC, id DESC LIMIT ?`, n)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("store: AuditRecent: %w", err)
|
||
}
|
||
defer rows.Close()
|
||
var out []AuditRow
|
||
for rows.Next() {
|
||
var r AuditRow
|
||
var ts string
|
||
if err := rows.Scan(&r.ID, &r.ConsumerID, &r.URL, &r.RuleID, &ts); err != nil {
|
||
return nil, fmt.Errorf("store: AuditRecent scan: %w", err)
|
||
}
|
||
t, err := time.Parse(time.RFC3339, ts)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("store: AuditRecent ts 解析: %w", err)
|
||
}
|
||
r.TS = t
|
||
out = append(out, r)
|
||
}
|
||
if err := rows.Err(); err != nil {
|
||
return nil, fmt.Errorf("store: AuditRecent rows: %w", err)
|
||
}
|
||
return out, nil
|
||
}
|
||
|
||
// AuditCountByRule 统计某规则命中次数(/metrics denied_total{rule_id})。
|
||
func (d *DB) AuditCountByRule(ruleID string) (int, error) {
|
||
var n int
|
||
if err := d.raw.QueryRow(
|
||
`SELECT COUNT(id) FROM audit WHERE rule_id = ?`, ruleID).Scan(&n); err != nil {
|
||
return 0, fmt.Errorf("store: AuditCountByRule: %w", err)
|
||
}
|
||
return n, nil
|
||
}
|