|
- package recorder
-
- import (
- "bufio"
- "encoding/json"
- "os"
- "path/filepath"
- "sync"
- "time"
- )
-
- const (
- audioStutterDebugDir = "debug/audio-stutter"
- serverStreamSummaryFile = "server_stream_summary.jsonl"
- browserAudioSummaryFile = "browser_audio_summary.jsonl"
- )
-
- type audioStutterDebugLogger struct {
- mu sync.Mutex
- serverFile *os.File
- serverWriter *bufio.Writer
- browserFile *os.File
- browserWriter *bufio.Writer
- }
-
- func newAudioStutterDebugLogger() *audioStutterDebugLogger {
- return &audioStutterDebugLogger{}
- }
-
- func (l *audioStutterDebugLogger) WriteServerSummary(v any) error {
- l.mu.Lock()
- defer l.mu.Unlock()
- if err := l.ensureServerWriterLocked(); err != nil {
- return err
- }
- return writeJSONLLineLocked(l.serverWriter, v)
- }
-
- func (l *audioStutterDebugLogger) WriteBrowserSummary(v any) error {
- l.mu.Lock()
- defer l.mu.Unlock()
- if err := l.ensureBrowserWriterLocked(); err != nil {
- return err
- }
- envelope := map[string]any{
- "ts_server": time.Now().UTC().Format(time.RFC3339Nano),
- "payload": v,
- }
- return writeJSONLLineLocked(l.browserWriter, envelope)
- }
-
- func (l *audioStutterDebugLogger) Close() {
- l.mu.Lock()
- defer l.mu.Unlock()
- if l.serverWriter != nil {
- _ = l.serverWriter.Flush()
- }
- if l.serverFile != nil {
- _ = l.serverFile.Close()
- }
- if l.browserWriter != nil {
- _ = l.browserWriter.Flush()
- }
- if l.browserFile != nil {
- _ = l.browserFile.Close()
- }
- l.serverWriter = nil
- l.serverFile = nil
- l.browserWriter = nil
- l.browserFile = nil
- }
-
- func (l *audioStutterDebugLogger) ensureServerWriterLocked() error {
- if l.serverWriter != nil {
- return nil
- }
- if err := os.MkdirAll(audioStutterDebugDir, 0o755); err != nil {
- return err
- }
- path := filepath.Join(audioStutterDebugDir, serverStreamSummaryFile)
- f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644)
- if err != nil {
- return err
- }
- l.serverFile = f
- l.serverWriter = bufio.NewWriterSize(f, 16*1024)
- return nil
- }
-
- func (l *audioStutterDebugLogger) ensureBrowserWriterLocked() error {
- if l.browserWriter != nil {
- return nil
- }
- if err := os.MkdirAll(audioStutterDebugDir, 0o755); err != nil {
- return err
- }
- path := filepath.Join(audioStutterDebugDir, browserAudioSummaryFile)
- f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644)
- if err != nil {
- return err
- }
- l.browserFile = f
- l.browserWriter = bufio.NewWriterSize(f, 16*1024)
- return nil
- }
-
- func writeJSONLLineLocked(w *bufio.Writer, v any) error {
- b, err := json.Marshal(v)
- if err != nil {
- return err
- }
- if _, err := w.Write(b); err != nil {
- return err
- }
- if err := w.WriteByte('\n'); err != nil {
- return err
- }
- return w.Flush()
- }
|