|
4 | 4 | "bufio" |
5 | 5 | "context" |
6 | 6 | "encoding/json" |
| 7 | + "errors" |
7 | 8 | "fmt" |
8 | 9 | "io" |
9 | 10 | "net/http" |
|
37 | 38 | activityLimit int |
38 | 39 | activityOffset int |
39 | 40 | activityIntentType string // Spec 018: Filter by operation type (read, write, destructive) |
| 41 | + activityRequestID string // Spec 021: Filter by HTTP request ID for correlation |
40 | 42 | activityNoIcons bool // Disable emoji icons in output |
41 | 43 |
|
42 | 44 | // Show command flags |
@@ -64,6 +66,7 @@ type ActivityFilter struct { |
64 | 66 | Limit int |
65 | 67 | Offset int |
66 | 68 | IntentType string // Spec 018: Filter by operation type (read, write, destructive) |
| 69 | + RequestID string // Spec 021: Filter by HTTP request ID for correlation |
67 | 70 | } |
68 | 71 |
|
69 | 72 | // Validate validates the filter options |
@@ -168,6 +171,10 @@ func (f *ActivityFilter) ToQueryParams() url.Values { |
168 | 171 | if f.IntentType != "" { |
169 | 172 | q.Set("intent_type", f.IntentType) |
170 | 173 | } |
| 174 | + // Spec 021: Add request_id filter for log correlation |
| 175 | + if f.RequestID != "" { |
| 176 | + q.Set("request_id", f.RequestID) |
| 177 | + } |
171 | 178 | return q |
172 | 179 | } |
173 | 180 |
|
@@ -369,14 +376,30 @@ func outputActivityError(err error, code string) error { |
369 | 376 | return err |
370 | 377 | } |
371 | 378 |
|
| 379 | + // T026: Extract request_id from APIError if available |
| 380 | + var requestID string |
| 381 | + var apiErr *cliclient.APIError |
| 382 | + if errors.As(err, &apiErr) && apiErr.HasRequestID() { |
| 383 | + requestID = apiErr.RequestID |
| 384 | + } |
| 385 | + |
372 | 386 | if outputFormat == "json" || outputFormat == "yaml" { |
373 | 387 | structErr := output.NewStructuredError(code, err.Error()). |
374 | 388 | WithGuidance("Use 'mcpproxy activity list' to view recent activities"). |
375 | 389 | WithRecoveryCommand("mcpproxy activity list --limit 10") |
| 390 | + // T026: Add request_id to StructuredError if available |
| 391 | + if requestID != "" { |
| 392 | + structErr = structErr.WithRequestID(requestID) |
| 393 | + } |
376 | 394 | result, _ := formatter.FormatError(structErr) |
377 | 395 | fmt.Println(result) |
378 | 396 | } else { |
379 | 397 | fmt.Fprintf(os.Stderr, "Error: %v\n", err) |
| 398 | + // T026: Include request ID with log retrieval suggestion if available |
| 399 | + if requestID != "" { |
| 400 | + fmt.Fprintf(os.Stderr, "\nRequest ID: %s\n", requestID) |
| 401 | + fmt.Fprintf(os.Stderr, "Use 'mcpproxy activity list --request-id %s' to find related logs.\n", requestID) |
| 402 | + } |
380 | 403 | fmt.Fprintf(os.Stderr, "Hint: Use 'mcpproxy activity list' to view recent activities\n") |
381 | 404 | } |
382 | 405 | return err |
@@ -405,6 +428,9 @@ Examples: |
405 | 428 | # List errors from github server |
406 | 429 | mcpproxy activity list --server github --status error |
407 | 430 |
|
| 431 | + # List activity by request ID (for error correlation) |
| 432 | + mcpproxy activity list --request-id abc123-def456 |
| 433 | +
|
408 | 434 | # List activity as JSON |
409 | 435 | mcpproxy activity list -o json`, |
410 | 436 | RunE: runActivityList, |
@@ -501,6 +527,7 @@ func init() { |
501 | 527 | activityListCmd.Flags().IntVarP(&activityLimit, "limit", "n", 50, "Max records to return (1-100)") |
502 | 528 | activityListCmd.Flags().IntVar(&activityOffset, "offset", 0, "Pagination offset") |
503 | 529 | activityListCmd.Flags().StringVar(&activityIntentType, "intent-type", "", "Filter by intent operation type: read, write, destructive") |
| 530 | + activityListCmd.Flags().StringVar(&activityRequestID, "request-id", "", "Filter by HTTP request ID for log correlation") |
504 | 531 | activityListCmd.Flags().BoolVar(&activityNoIcons, "no-icons", false, "Disable emoji icons in output (use text instead)") |
505 | 532 |
|
506 | 533 | // Watch command flags |
@@ -585,6 +612,7 @@ func runActivityList(cmd *cobra.Command, _ []string) error { |
585 | 612 | Limit: activityLimit, |
586 | 613 | Offset: activityOffset, |
587 | 614 | IntentType: activityIntentType, |
| 615 | + RequestID: activityRequestID, |
588 | 616 | } |
589 | 617 |
|
590 | 618 | if err := filter.Validate(); err != nil { |
|
0 commit comments