fix: use singleton pattern and force nodejs runtime for metrics route
- Add runtime = 'nodejs' to ensure Node.js environment - Add dynamic = 'force-dynamic' to prevent static optimization - Use singleton pattern to avoid duplicate metric registration - Add error logging for debugging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
5f2f71e539
commit
d636578761
|
|
@ -1,30 +1,55 @@
|
||||||
import { NextResponse } from 'next/server';
|
import { NextResponse } from 'next/server';
|
||||||
import client from 'prom-client';
|
import client from 'prom-client';
|
||||||
|
|
||||||
// Create a Registry to register the metrics
|
// Force Node.js runtime for this route
|
||||||
const register = new client.Registry();
|
export const runtime = 'nodejs';
|
||||||
|
export const dynamic = 'force-dynamic';
|
||||||
|
|
||||||
// Add default metrics (CPU, memory, etc.)
|
// Singleton pattern to avoid duplicate metric registration
|
||||||
client.collectDefaultMetrics({ register });
|
const globalForProm = globalThis as unknown as {
|
||||||
|
promRegistry: client.Registry | undefined;
|
||||||
|
metricsInitialized: boolean | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
// Custom metrics
|
function getRegistry(): client.Registry {
|
||||||
const httpRequestsTotal = new client.Counter({
|
if (!globalForProm.promRegistry) {
|
||||||
name: 'http_requests_total',
|
globalForProm.promRegistry = new client.Registry();
|
||||||
help: 'Total number of HTTP requests',
|
}
|
||||||
labelNames: ['method', 'path', 'status'],
|
return globalForProm.promRegistry;
|
||||||
registers: [register],
|
}
|
||||||
});
|
|
||||||
|
|
||||||
const httpRequestDuration = new client.Histogram({
|
function initializeMetrics(register: client.Registry) {
|
||||||
name: 'http_request_duration_seconds',
|
if (globalForProm.metricsInitialized) {
|
||||||
help: 'Duration of HTTP requests in seconds',
|
return;
|
||||||
labelNames: ['method', 'path'],
|
}
|
||||||
buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10],
|
|
||||||
registers: [register],
|
// Add default metrics (CPU, memory, etc.)
|
||||||
});
|
client.collectDefaultMetrics({ register });
|
||||||
|
|
||||||
|
// Custom metrics
|
||||||
|
new client.Counter({
|
||||||
|
name: 'http_requests_total',
|
||||||
|
help: 'Total number of HTTP requests',
|
||||||
|
labelNames: ['method', 'path', 'status'],
|
||||||
|
registers: [register],
|
||||||
|
});
|
||||||
|
|
||||||
|
new client.Histogram({
|
||||||
|
name: 'http_request_duration_seconds',
|
||||||
|
help: 'Duration of HTTP requests in seconds',
|
||||||
|
labelNames: ['method', 'path'],
|
||||||
|
buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10],
|
||||||
|
registers: [register],
|
||||||
|
});
|
||||||
|
|
||||||
|
globalForProm.metricsInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
try {
|
try {
|
||||||
|
const register = getRegistry();
|
||||||
|
initializeMetrics(register);
|
||||||
|
|
||||||
const metrics = await register.metrics();
|
const metrics = await register.metrics();
|
||||||
return new NextResponse(metrics, {
|
return new NextResponse(metrics, {
|
||||||
status: 200,
|
status: 200,
|
||||||
|
|
@ -33,6 +58,7 @@ export async function GET() {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error('Metrics error:', error);
|
||||||
return NextResponse.json({ error: 'Failed to get metrics' }, { status: 500 });
|
return NextResponse.json({ error: 'Failed to get metrics' }, { status: 500 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user