fix(agent): 审计写入失败不再静默
审计日志是证据而不是控制手段:写失败不能让请求失败,否则磁盘写满会变成一次远程 拒绝服务——已经执行成功的指令会因为日志追加不上而开始报错,那是坏错了地方。 但它也不能消失。静默丢审计条目是那种"运维以为自己有记录、其实没有"的失败,而这份 日志的全部意义就是事后能回答"谁在什么时候要求了什么"。现在写失败会进 agent 自己的 日志,磁盘写满表现为一行反复出现,而不是一片空白。 顺带把 Close 之后的语义写清楚:Close 会丢掉 sink,此后的写入返回 nil——这是刻意的, 因为一个正在关闭的进程与在途请求赛跑时,为每一个恰好到达的请求报一次失败是噪声 而不是信息。这条差别在 agent 日志里看得见。 测试用真实失败路径(写一个已关闭的文件)而不是填满文件系统,并断言 exec.record 把 它报了出来。 Go 全包、Node 112 项、Swift 101 项通过。
This commit is contained in:
@@ -59,6 +59,11 @@ func NullAudit() *Audit { return &Audit{} }
|
||||
|
||||
// Write appends one entry. A write failure is returned to the caller rather than panicking: the
|
||||
// audit log is evidence, not a control, and a full disk must not become a remote denial of service.
|
||||
//
|
||||
// Returning nil after Close is deliberate and is the one case where a dropped entry is not an error:
|
||||
// a shutdown path racing an in-flight request would otherwise log a failure for every request that
|
||||
// happened to arrive at that moment, which is noise rather than information. The executor logs what it
|
||||
// sees either way, so the difference is visible in the agent's log.
|
||||
func (a *Audit) Write(entry Entry) error {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
@@ -75,8 +80,12 @@ func (a *Audit) Write(entry Entry) error {
|
||||
return a.sink.Sync()
|
||||
}
|
||||
|
||||
// Close releases the file. Subsequent writes are silently dropped, which is the right behaviour for
|
||||
// a shutdown path: failing the request that happens to race with a clean exit buys nothing.
|
||||
// Close releases the file.
|
||||
//
|
||||
// A write after Close is dropped, and dropped silently is the wrong word for it: the executor reports
|
||||
// every write error it sees, and this returns one, so a request racing a clean shutdown shows up as a
|
||||
// warning rather than as a missing line nobody notices. The alternative — failing the request — buys
|
||||
// nothing, because the command it describes has already run or been refused.
|
||||
func (a *Audit) Close() error {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
|
||||
Reference in New Issue
Block a user