fix(dashboard): real error rate from llm_api_errors_total

- errors now = rate(llm_api_errors_total) instead of network TX bytes
- rps = rate(llm_api_requests_total) + rate(http_server_request_count_total)
- Latency card → Load Average (was misleading: showed node load as 'ms')
- Overview 'Errors' StatBox was hardcoded 0 → real llm err/s
- rename hasTraffik → hasTraffic (Traefik removed 2026-08-02)
This commit is contained in:
asepharyana
2026-08-03 13:06:27 +07:00
parent 62966fd7cf
commit a90d0c4333
2 changed files with 37 additions and 17 deletions
+20 -8
View File
@@ -159,10 +159,10 @@ export async function GET() {
load15,
netIn,
netOut,
rps,
latency,
errors,
traceVolume,
netInSpark,
loadSpark,
netOutSpark,
upstreamCount,
] = await Promise.all([
promQuery(
`100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[1m])) * 100)`,
@@ -184,6 +184,18 @@ export async function GET() {
promQuery("count(up)"),
]);
// ── Error rate (llm-api) & request rate (any /metrics service) ──
const [errRate, errSpark] = await Promise.all([
promQuery(`sum(rate(llm_api_errors_total[5m]))`),
promRange(`sum(rate(llm_api_errors_total[1m]))`),
]);
const reqRate = await promQuery(
`sum(rate(llm_api_requests_total[5m])) + sum(rate(http_server_request_count_total[5m]))`,
);
const reqSpark = await promRange(
`sum(rate(llm_api_requests_total[1m])) + sum(rate(http_server_request_count_total[1m]))`,
);
// ── LLM inference metrics (llm-api /metrics) ──
const [
llmReqRate,
@@ -225,10 +237,10 @@ export async function GET() {
services,
traces: [],
node: { cpu, ram, disk, load1, load5, load15, netIn, netOut },
rps,
latency,
errors,
traceVolume: traceVolume ? [traceVolume] : [],
rps: reqSpark,
latency: loadSpark,
errors: errSpark,
traceVolume: netInSpark,
links,
llm: {
reqRate: llmReqRate,
+17 -9
View File
@@ -60,8 +60,8 @@ export default function Dashboard() {
data?.services.filter((s) => s.state === "running").length ?? 0;
const degraded = (data?.services.length ?? 0) - running;
const hasNode = data?.node.cpu !== null || data?.node.ram !== null;
const hasTraffik =
(data?.rps?.length ?? 0) > 0 || (data?.latency?.length ?? 0) > 0;
const hasTraffic =
(data?.rps?.length ?? 0) > 0 || (data?.errors?.length ?? 0) > 0;
const node = data?.node;
return (
@@ -147,7 +147,15 @@ export default function Dashboard() {
label="Traces"
color="text-blue-400"
/>
<StatBox value={0} label="Errors" color="text-red-400" />
<StatBox
value={
data?.errors?.length
? data.errors[data.errors.length - 1].toFixed(2)
: undefined
}
label="LLM err/s"
color="text-red-400"
/>
</div>
</CardContent>
</Card>
@@ -299,7 +307,7 @@ export default function Dashboard() {
</motion.div>
{/* Request Rate */}
{hasTraffik && (
{hasTraffic && (
<motion.div variants={cardVariants}>
<Card className="transition-shadow duration-300 hover:shadow-md hover:shadow-border/20">
<CardHeader className="flex flex-row items-center justify-between">
@@ -317,15 +325,15 @@ export default function Dashboard() {
</motion.div>
)}
{/* Latency */}
{hasTraffik && (
{/* Load Average */}
{hasNode && (
<motion.div variants={cardVariants}>
<Card className="transition-shadow duration-300 hover:shadow-md hover:shadow-border/20">
<CardHeader className="flex flex-row items-center justify-between">
<CardTitle>Latency</CardTitle>
<CardTitle>Load Average</CardTitle>
<Badge variant="secondary" className="text-[10px] font-normal">
{data?.latency?.length
? `${data.latency[data.latency.length - 1].toFixed(0)}ms`
? data.latency[data.latency.length - 1].toFixed(2)
: "-"}
</Badge>
</CardHeader>
@@ -337,7 +345,7 @@ export default function Dashboard() {
)}
{/* Error Rate */}
{hasTraffik && (
{hasTraffic && (
<motion.div variants={cardVariants}>
<Card className="transition-shadow duration-300 hover:shadow-md hover:shadow-border/20">
<CardHeader className="flex flex-row items-center justify-between">