MCPcopy Create free account
hub / github.com/github/gh-aw / parseEventsJSONLMetrics

Function parseEventsJSONLMetrics

pkg/cli/copilot_events_jsonl.go:173–322  ·  view source on GitHub ↗

parseEventsJSONLMetrics parses a Copilot events.jsonl file and extracts log metrics. events.jsonl provides precise, structured data about a Copilot CLI session: - "session.start": session metadata (sessionId, copilotVersion) - "user.message": one per conversation turn (used to co

(path string, verbose bool)

Source from the content-addressed store, hash-verified

171// Returns the extracted metrics and nil on success, or empty metrics and an
172// error if the file cannot be read or contains no recognizable events.
173func parseEventsJSONLMetrics(path string, verbose bool) (workflow.LogMetrics, error) {
174 copilotEventsJSONLLog.Printf("Parsing events.jsonl from: %s", path)
175
176 var metrics workflow.LogMetrics
177
178 // Sanitize path to prevent traversal
179 cleanPath := filepath.Clean(path)
180
181 file, err := os.Open(cleanPath)
182 if err != nil {
183 return metrics, fmt.Errorf("failed to open events.jsonl: %w", err)
184 }
185 defer file.Close()
186
187 toolCallMap := make(map[string]*workflow.ToolCallInfo)
188 var currentSequence []string
189 turns := 0
190 totalTokens := 0
191 foundAnyEvent := false
192
193 // Per-turn timestamps used to compute Time Between Turns (TBT)
194 var turnTimestamps []time.Time
195
196 scanner := bufio.NewScanner(file)
197 buf := make([]byte, maxScannerBufferSize)
198 scanner.Buffer(buf, maxScannerBufferSize)
199
200 for scanner.Scan() {
201 line := strings.TrimSpace(scanner.Text())
202 if line == "" || !strings.HasPrefix(line, "{") {
203 continue
204 }
205
206 var entry copilotEventsJSONLEntry
207 if err := json.Unmarshal([]byte(line), &entry); err != nil {
208 copilotEventsJSONLLog.Printf("Skipping malformed events.jsonl line: %v", err)
209 continue
210 }
211
212 foundAnyEvent = true
213
214 switch entry.Type {
215 case "session.start":
216 copilotEventsJSONLLog.Printf("session.start: sessionId=%s copilotVersion=%s",
217 entry.Data.SessionID, entry.Data.CopilotVersion)
218
219 case "user.message":
220 // Each user message represents one conversation turn.
221 // Save the current tool sequence before starting a new turn.
222 turns++
223 if len(currentSequence) > 0 {
224 metrics.ToolSequences = append(metrics.ToolSequences, currentSequence)
225 currentSequence = []string{}
226 }
227 // Record the timestamp for TBT computation.
228 if entry.Timestamp != "" {
229 if ts, parseErr := time.Parse(time.RFC3339Nano, entry.Timestamp); parseErr == nil {
230 turnTimestamps = append(turnTimestamps, ts)

Callers 5

TestParseEventsJSONLFileFunction · 0.85
extractLogMetricsFunction · 0.85
inferFallbackLogMetricsFunction · 0.85

Calls 10

AddMethod · 0.95
CountMethod · 0.95
MeanMethod · 0.95
MaxMethod · 0.95
MedianMethod · 0.95
SampleStdDevMethod · 0.95
FormatSuccessMessageFunction · 0.92
CloseMethod · 0.65
PrintfMethod · 0.45
ErrorfMethod · 0.45