(maxItems, maxBodyBytes int)
| 80 | var backendMaxBodyBytes int |
| 81 | |
| 82 | func InitBackendTracingIfEnabled(maxItems, maxBodyBytes int) { |
| 83 | backendInitOnce.Do(func() { |
| 84 | if maxItems <= 0 { |
| 85 | maxItems = 100 |
| 86 | } |
| 87 | backendMu.Lock() |
| 88 | backendTraceBuffer = circularbuffer.New[*BackendTrace](maxItems) |
| 89 | backendMu.Unlock() |
| 90 | |
| 91 | go func() { |
| 92 | for t := range backendLogChan { |
| 93 | backendMu.Lock() |
| 94 | if backendTraceBuffer != nil { |
| 95 | backendTraceBuffer.Enqueue(t) |
| 96 | } |
| 97 | backendMu.Unlock() |
| 98 | } |
| 99 | }() |
| 100 | }) |
| 101 | |
| 102 | // The body cap tracks the LATEST call, not the first: tracing_max_body_bytes |
| 103 | // is runtime-mutable via the settings API (ApplyRuntimeSettings), and every |
| 104 | // recording path calls this right before RecordBackendTrace with the current |
| 105 | // appConfig value. Freezing the cap on first init meant a raised setting let |
| 106 | // producers (e.g. trace.AudioSnippet, which reads the live value) embed |
| 107 | // payloads that this recorder then stomped with the "<truncated: N bytes>" |
| 108 | // marker — corrupting audio_wav_base64 into an unplayable string. maxItems |
| 109 | // keeps first-call semantics: resizing the ring buffer would drop entries. |
| 110 | backendMu.Lock() |
| 111 | backendMaxBodyBytes = maxBodyBytes |
| 112 | backendMu.Unlock() |
| 113 | } |
| 114 | |
| 115 | func RecordBackendTrace(t BackendTrace) { |
| 116 | backendMu.Lock() |
no test coverage detected