feat: integrate Datadog APM + Sentry error tracking with CloudWatch metrics FRE-4806

- Add CloudWatch metrics emitter (api_latency, api_requests, api_errors)
- Add request monitoring middleware for API (latency, error rate, throughput)
- Register error-handling, logging, and monitoring middleware in server.ts
- Add Datadog log forwarding via HTTP intake API
- Add application-level CloudWatch alarms for P99 latency, error rate, throughput
- Inject Datadog/Sentry env vars and secrets into ECS task definitions
- Add DD_API_KEY and SENTRY_DSN to ECS secrets
- Create CloudWatch log groups for datadog and sentry services
- Update .env.example with AWS_REGION and monitoring variables
- Add @aws-sdk/client-cloudwatch dependency to monitoring package

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-05-10 02:15:11 -04:00
parent 57a206d7b3
commit c7df40ac26
18 changed files with 5260 additions and 76 deletions

View File

@@ -0,0 +1,49 @@
import { getMonitoringConfig } from './config';
let logForwarder: { send: (log: string, service: string) => Promise<void> } | null = null;
export function initDatadogLogs() {
const config = getMonitoringConfig();
if (!process.env.DD_API_KEY) {
console.log('[Datadog Logs] API key not configured, log forwarding disabled');
return;
}
const site = process.env.DD_SITE || 'datadoghq.com';
const logIntakeUrl = `https://http-intake.logs.${site}`;
logForwarder = {
async send(log: string, service: string) {
try {
const payload = JSON.stringify({
ddsource: 'nodejs',
ddtags: `env:${config.DD_ENV},service:${service}`,
hostname: config.DD_SERVICE,
message: log,
service,
});
await fetch(`${logIntakeUrl}/api/v2/logs`, {
method: 'POST',
headers: {
'DD-API-KEY': process.env.DD_API_KEY!,
'Content-Type': 'application/json',
},
body: payload,
});
} catch (err) {
console.warn('[Datadog Logs] Forward failed:', (err as Error).message);
}
},
};
}
export async function forwardLog(log: string, service: string = 'shieldai-api') {
if (!logForwarder) return;
await logForwarder.send(log, service);
}
export function getLogForwarder() {
return logForwarder;
}