Conversation
Add MetricsCollector class that tracks: - Webhook event counts and processing duration - Error counts by type - AI call metrics (total, failures, avg duration) - Server uptime Exposes data via GET /metrics endpoint for monitoring. Includes 6 unit tests for the collector.
PR SummarySummaryThis PR adds observability to the RepoKeeper application by introducing a Files Changed
Flags
Files Changed (3)
Size: medium (167 lines changed) |
PR SummarySummaryThis PR adds a new observability feature by introducing a Files Changed
Flags
Files Changed (3)
Size: medium (167 lines changed) |
GodsBoy
left a comment
There was a problem hiding this comment.
RepoKeeper Code Review
The pull request adds a metrics collection system with a new /metrics endpoint. The implementation is generally solid with good test coverage, but there are security and integration concerns that need addressing before merge.
Found 6 issue(s): 0 blocking, 2 warning(s), 4 suggestion(s)
Review by RepoKeeper
| res.json({ status: 'ok', version: '0.1.0' }); | ||
| }); | ||
|
|
||
| app.get('/metrics', (_req, res) => { |
There was a problem hiding this comment.
The /metrics endpoint exposes internal application metrics without any authentication or authorization checks. This could leak sensitive operational information to unauthorized users. Consider adding authentication middleware or restricting this endpoint to localhost only.
| recordEvent(eventType: string, durationMs: number): void { | ||
| const existing = this.events.get(eventType); | ||
| if (existing) { | ||
| existing.count++; |
There was a problem hiding this comment.
Calling new Date().toISOString() on every event recording (lines 38, 44) creates unnecessary object allocations. Consider using a single timestamp per batch or caching the current time to improve performance in high-throughput scenarios.
| @@ -0,0 +1,102 @@ | |||
| import { log } from './logger.js'; | |||
There was a problem hiding this comment.
💡 SUGGESTION
The MetricsCollector class is exported as a singleton instance but is never actually integrated with the rest of the application. The webhook handler, AI providers, and GitHub client don't call recordEvent(), recordError(), or recordAICall(). Add instrumentation throughout the codebase to make this metrics collection functional.
| private startedAt: string; | ||
| private events: Map<string, MetricEntry> = new Map(); | ||
| private errors: Map<string, number> = new Map(); | ||
| private aiCallCount = 0; |
There was a problem hiding this comment.
💡 SUGGESTION
Memory leak potential: The events and errors Maps grow unbounded over the application's lifetime. For long-running applications, consider implementing a sliding window or TTL-based eviction strategy to prevent excessive memory consumption.
| @@ -0,0 +1,60 @@ | |||
| import { describe, it, expect, beforeEach } from 'vitest'; | |||
There was a problem hiding this comment.
💡 SUGGESTION
The test file only tests the MetricsCollector class in isolation. Add integration tests in src/index.ts to verify that the /metrics endpoint is properly secured, returns valid JSON, and integrates correctly with the Express app.
| res.json({ status: 'ok', version: '0.1.0' }); | ||
| }); | ||
|
|
||
| app.get('/metrics', (_req, res) => { |
There was a problem hiding this comment.
💡 SUGGESTION
The /metrics endpoint doesn't set appropriate HTTP headers (e.g., Content-Type is not explicitly set, no Cache-Control headers). Add explicit response headers for clarity and to prevent caching of dynamic metrics data.
Summary
MetricsCollectorclass (src/metrics.ts) that tracks webhook event counts, processing duration, error counts, and AI call metricsGET /metricsendpoint on the Express server for monitoringChanges
MetricsCollectorclass withrecordEvent(),recordError(),recordAICall(),getSnapshot(), andreset()methods/metricsrouteTest plan
pnpm buildpassespnpm testpasses (91 tests)/metricsreturns JSON with expected shape