feat(phase-2): workstream 7 — Prometheus + Grafana Monitoring

- Add prom-client 15; shared registry in src/metrics/registry.ts (7 metrics)
- HTTP request counter + duration histogram via metricsMiddleware
- DB query duration histogram wrapping pg Pool.query
- Redis command duration histogram via typed instrumentRedisMethod wrapper
- agentidp_tokens_issued_total in OAuth2Service
- agentidp_agents_registered_total in AgentService
- GET /metrics unauthenticated endpoint (Prometheus text format)
- docker-compose.monitoring.yml overlay (Prometheus + Grafana)
- Grafana auto-provisioned datasource + pre-built AgentIdP dashboard
- docs/devops/operations.md monitoring section added
- 36/36 unit tests passing, 100% coverage on new metrics code
- Fix pre-existing unused import in tests/integration/agents.test.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
SentryAgent.ai Developer
2026-03-29 06:13:41 +00:00
parent 7d6e248a14
commit a504964e5f
21 changed files with 1053 additions and 15 deletions

View File

@@ -19,6 +19,7 @@ import {
AgentAlreadyDecommissionedError,
FreeTierLimitError,
} from '../utils/errors.js';
import { agentsRegisteredTotal } from '../metrics/registry.js';
const FREE_TIER_MAX_AGENTS = 100;
@@ -81,6 +82,9 @@ export class AgentService {
{ agentType: agent.agentType, owner: agent.owner },
);
// Instrument: count successful agent registrations
agentsRegisteredTotal.inc({ deployment_env: data.deploymentEnv });
return agent;
}

View File

@@ -22,6 +22,7 @@ import {
import { signToken, verifyToken, decodeToken, getTokenExpiresIn } from '../utils/jwt.js';
import { verifySecret } from '../utils/crypto.js';
import { v4 as uuidv4 } from 'uuid';
import { tokensIssuedTotal } from '../metrics/registry.js';
const FREE_TIER_MAX_MONTHLY_TOKENS = 10000;
@@ -202,6 +203,9 @@ export class OAuth2Service {
{ scope, expiresAt: expiresAtDate.toISOString() },
);
// Instrument: count successful token issuances
tokensIssuedTotal.inc({ scope });
return {
access_token: accessToken,
token_type: 'Bearer',