refactor(trace): decouple recorder from file persistence

Turn TraceRecorder into a lightweight trace event entry point and move
file persistence responsibilities into the default FileTraceSink. Trace
events are now published through TraceSinkRegistry, allowing additional
runtime observers to subscribe without parsing trace files.

Add TraceSink and TraceSinkRegistry, keep FileTraceSink registered as the
default sink, and preserve the existing active/historical/archived trace
file rotation behavior inside the file sink.

Also change TraceEvent to carry a logical key instead of a caller-provided
path, so trace storage locations are resolved internally under the traceroot. Update existing trace producers to emit logical keys such ascontext-workspace, exception, and advice targets.
This commit is contained in:
2026-04-27 23:53:20 +08:00
parent 3eac52f4e2
commit 73f6ff2745
5 changed files with 98 additions and 35 deletions

View File

@@ -4,10 +4,8 @@ import com.alibaba.fastjson2.JSONObject
import org.w3c.dom.Document
import org.w3c.dom.Element
import work.slhaf.partner.common.base.Block
import work.slhaf.partner.framework.agent.config.ConfigCenter
import work.slhaf.partner.framework.agent.log.TraceEvent
import work.slhaf.partner.framework.agent.log.TraceRecorder
import java.nio.file.Path
import java.time.Duration
import java.time.Instant
import java.util.*
@@ -18,11 +16,6 @@ import kotlin.math.min
class ContextWorkspace {
private val tracePath: Path = ConfigCenter.paths.stateDir
.resolve("trace")
.resolve("context-workspace")
.normalize()
.toAbsolutePath()
private val stateSet = mutableSetOf<ContextBlock>()
private val lock = ReentrantReadWriteLock()
@@ -157,7 +150,7 @@ class ContextWorkspace {
.thenBy { it.sourceKey.source }
)
.map(::blockSnapshot)
TraceRecorder.record(TraceEvent(tracePath, payload))
TraceRecorder.record(TraceEvent("context-workspace", payload))
}
private fun blockSnapshot(block: ContextBlock): JSONObject {