- 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>
72 lines
2.6 KiB
TypeScript
72 lines
2.6 KiB
TypeScript
import Fastify from "fastify";
|
|
import cors from "@fastify/cors";
|
|
import helmet from "@fastify/helmet";
|
|
import sensible from "@fastify/sensible";
|
|
import { extractOrGenerateRequestId } from "@shieldai/types";
|
|
import { authMiddleware } from "./middleware/auth.middleware";
|
|
import { errorHandlingMiddleware } from "./middleware/error-handling.middleware";
|
|
import { loggingMiddleware } from "./middleware/logging.middleware";
|
|
import { monitoringMiddleware } from "./middleware/monitoring.middleware";
|
|
import { darkwatchRoutes } from "./routes/darkwatch.routes";
|
|
import { voiceprintRoutes } from "./routes/voiceprint.routes";
|
|
import { correlationRoutes } from "./routes/correlation.routes";
|
|
import { extensionRoutes } from "./routes/extension.routes";
|
|
import { initDatadog, initSentry, initDatadogLogs, captureSentryError } from "@shieldai/monitoring";
|
|
import { getCorsOrigins } from "./config/api.config";
|
|
|
|
initDatadog();
|
|
initSentry();
|
|
initDatadogLogs();
|
|
|
|
const app = Fastify({
|
|
logger: {
|
|
level: process.env.LOG_LEVEL || "info",
|
|
},
|
|
});
|
|
|
|
async function bootstrap() {
|
|
const corsOrigins = getCorsOrigins();
|
|
await app.register(cors, { origin: corsOrigins });
|
|
await app.register(helmet);
|
|
await app.register(sensible);
|
|
|
|
// Register auth middleware to populate request.user
|
|
await app.register(authMiddleware);
|
|
|
|
// Register logging middleware (request/response logging)
|
|
await app.register(loggingMiddleware);
|
|
|
|
// Register monitoring middleware (CloudWatch metrics)
|
|
await app.register(monitoringMiddleware);
|
|
|
|
// Register error handling middleware (Sentry integration)
|
|
await app.register(errorHandlingMiddleware);
|
|
|
|
app.addHook("onRequest", async (request, _reply) => {
|
|
const requestId = extractOrGenerateRequestId(request.headers);
|
|
request.id = requestId;
|
|
const pinoLog = request.log as typeof request.log & { bindings?: Record<string, string>; bindActive?: () => void };
|
|
pinoLog.bindings = { requestId };
|
|
pinoLog.bindActive?.();
|
|
request.headers["x-request-id"] = requestId;
|
|
});
|
|
|
|
await app.register(darkwatchRoutes);
|
|
await app.register(voiceprintRoutes);
|
|
await app.register(correlationRoutes);
|
|
await app.register(extensionRoutes, { prefix: '/extension' });
|
|
|
|
app.get("/health", async () => ({ status: "ok", timestamp: new Date().toISOString() }));
|
|
|
|
try {
|
|
await app.listen({ port: parseInt(process.env.PORT || "3000", 10), host: "0.0.0.0" });
|
|
app.log.info(`Server listening on port ${process.env.PORT || 3000}`);
|
|
} catch (err) {
|
|
app.log.error(err);
|
|
captureSentryError(err as Error, { context: "server_startup" });
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
bootstrap();
|