| 105 | } |
| 106 | |
| 107 | func NewStatsCollector(opts StatsCollectorOptions) *StatsCollector { |
| 108 | if opts.Logger == nil { |
| 109 | opts.Logger = &slog.Logger{} |
| 110 | } |
| 111 | if opts.ReportInterval == 0 { |
| 112 | opts.ReportInterval = DefaultStatsCollectorReportInterval |
| 113 | } |
| 114 | if opts.RollupWindow == 0 { |
| 115 | opts.RollupWindow = DefaultStatsCollectorRollupWindow |
| 116 | } |
| 117 | if opts.Now == nil { |
| 118 | opts.Now = time.Now |
| 119 | } |
| 120 | |
| 121 | ctx, cancel := context.WithCancel(context.Background()) |
| 122 | sc := &StatsCollector{ |
| 123 | ctx: ctx, |
| 124 | cancel: cancel, |
| 125 | done: make(chan struct{}), |
| 126 | opts: opts, |
| 127 | |
| 128 | statsBySessionID: make(map[uuid.UUID]*StatsReport), |
| 129 | groupedStats: make(map[statsGroupKey][]*StatsReport), |
| 130 | } |
| 131 | |
| 132 | go sc.start() |
| 133 | return sc |
| 134 | } |
| 135 | |
| 136 | // Collect the given StatsReport for later reporting (non-blocking). |
| 137 | func (sc *StatsCollector) Collect(report StatsReport) { |