Skip to content

Commit 7ada0df

Browse files
committed
fix: uptime calc
1 parent 10f881f commit 7ada0df

File tree

7 files changed

+81
-14
lines changed

7 files changed

+81
-14
lines changed

apps/api/src/query/builders/uptime.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type { Filter, SimpleQueryConfig } from "../types";
88
* - site_id: Website identifier
99
* - url: Monitored URL
1010
* - timestamp: Check timestamp
11-
* - status: 1 = up, 0 = down
11+
* - status: 1 = up, 0 = down, 2 = pending
1212
* - http_code: HTTP response code
1313
* - ttfb_ms: Time to first byte (ms)
1414
* - total_ms: Total response time (ms)
@@ -25,9 +25,9 @@ export const UptimeBuilders: Record<string, SimpleQueryConfig> = {
2525
sql: `
2626
SELECT
2727
COUNT(*) as total_checks,
28-
sum(status) as successful_checks,
29-
COUNT(*) - sum(status) as failed_checks,
30-
round((sum(status) / COUNT(*)) * 100, 2) as uptime_percentage,
28+
countIf(status = 1) as successful_checks,
29+
countIf(status = 0) as failed_checks,
30+
if((countIf(status = 1) + countIf(status = 0)) = 0, 0, round((countIf(status = 1) / (countIf(status = 1) + countIf(status = 0))) * 100, 2)) as uptime_percentage,
3131
avg(total_ms) as avg_response_time,
3232
quantile(0.50)(total_ms) as p50_response_time,
3333
quantile(0.75)(total_ms) as p75_response_time,
@@ -73,9 +73,9 @@ export const UptimeBuilders: Record<string, SimpleQueryConfig> = {
7373
SELECT
7474
${timeGroup} as date,
7575
COUNT(*) as total_checks,
76-
sum(status) as successful_checks,
77-
COUNT(*) - sum(status) as failed_checks,
78-
round((sum(status) / COUNT(*)) * 100, 2) as uptime_percentage,
76+
countIf(status = 1) as successful_checks,
77+
countIf(status = 0) as failed_checks,
78+
if((countIf(status = 1) + countIf(status = 0)) = 0, 0, round((countIf(status = 1) / (countIf(status = 1) + countIf(status = 0))) * 100, 2)) as uptime_percentage,
7979
avg(total_ms) as avg_response_time,
8080
quantile(0.50)(total_ms) as p50_response_time,
8181
quantile(0.95)(total_ms) as p95_response_time,
@@ -230,9 +230,9 @@ export const UptimeBuilders: Record<string, SimpleQueryConfig> = {
230230
SELECT
231231
probe_region as region,
232232
COUNT(*) as total_checks,
233-
sum(status) as successful_checks,
234-
COUNT(*) - sum(status) as failed_checks,
235-
round((sum(status) / COUNT(*)) * 100, 2) as uptime_percentage,
233+
countIf(status = 1) as successful_checks,
234+
countIf(status = 0) as failed_checks,
235+
if((countIf(status = 1) + countIf(status = 0)) = 0, 0, round((countIf(status = 1) / (countIf(status = 1) + countIf(status = 0))) * 100, 2)) as uptime_percentage,
236236
avg(total_ms) as avg_response_time,
237237
quantile(0.95)(total_ms) as p95_response_time
238238
FROM ${UPTIME_TABLE}

apps/uptime/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
},
88
"dependencies": {
99
"@databuddy/db": "workspace:*",
10+
"@databuddy/services": "workspace:*",
1011
"elysia": "^1.4.18"
1112
}
1213
}

apps/uptime/src/actions.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createHash } from "node:crypto";
22
import { connect } from "node:tls";
3-
import { chQuery, db, eq, websites } from "@databuddy/db";
3+
import { chQuery } from "@databuddy/db";
4+
import { getWebsiteById } from "@databuddy/services/websites";
45
import type { ActionResult, UptimeData } from "./types";
56
import { MonitorStatus } from "./types";
67

@@ -41,9 +42,7 @@ export async function lookupWebsite(
4142
id: string
4243
): Promise<ActionResult<{ id: string; domain: string }>> {
4344
try {
44-
const site = await db.query.websites.findFirst({
45-
where: eq(websites.id, id),
46-
});
45+
const site = await getWebsiteById(id);
4746

4847
if (!site) {
4948
return { success: false, error: `Website ${id} not found` };

bun.lock

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@
381381
"version": "1.0.0",
382382
"dependencies": {
383383
"@databuddy/db": "workspace:*",
384+
"@databuddy/services": "workspace:*",
384385
"elysia": "^1.4.18",
385386
},
386387
},
@@ -541,6 +542,16 @@
541542
"vue",
542543
],
543544
},
545+
"packages/services": {
546+
"name": "@databuddy/services",
547+
"version": "1.0.0",
548+
"dependencies": {
549+
"@databuddy/db": "workspace:*",
550+
},
551+
"devDependencies": {
552+
"typescript": "^5.9.3",
553+
},
554+
},
544555
"packages/shared": {
545556
"name": "@databuddy/shared",
546557
"version": "0.0.1",
@@ -778,6 +789,8 @@
778789

779790
"@databuddy/sdk": ["@databuddy/sdk@workspace:packages/sdk"],
780791

792+
"@databuddy/services": ["@databuddy/services@workspace:packages/services"],
793+
781794
"@databuddy/shared": ["@databuddy/shared@workspace:packages/shared"],
782795

783796
"@databuddy/tracker": ["@databuddy/tracker@workspace:packages/tracker"],

packages/services/package.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "@databuddy/services",
3+
"version": "1.0.0",
4+
"exports": {
5+
"./websites": "./src/websites.ts"
6+
},
7+
"dependencies": {
8+
"@databuddy/db": "workspace:*"
9+
},
10+
"devDependencies": {
11+
"typescript": "^5.9.3"
12+
}
13+
}

packages/services/src/websites.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { db, eq, websites } from "@databuddy/db";
2+
import type { InferSelectModel } from "drizzle-orm";
3+
4+
export type Website = InferSelectModel<typeof websites>;
5+
6+
export async function getWebsiteById(id: string): Promise<Website | null> {
7+
try {
8+
const website = await db.query.websites.findFirst({
9+
where: eq(websites.id, id),
10+
});
11+
12+
return website || null;
13+
} catch (error) {
14+
console.error("Failed to get website by ID:", error);
15+
return null;
16+
}
17+
}

packages/services/tsconfig.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2022",
4+
"module": "ES2022",
5+
"lib": ["ES2022"],
6+
"moduleResolution": "bundler",
7+
"strict": true,
8+
"skipLibCheck": true,
9+
"forceConsistentCasingInFileNames": true,
10+
"resolveJsonModule": true,
11+
"isolatedModules": true,
12+
"baseUrl": ".",
13+
"paths": {
14+
"@/*": ["./src/*"]
15+
},
16+
"composite": true,
17+
"declaration": true,
18+
"declarationMap": true,
19+
"outDir": "./dist",
20+
"rootDir": "./src"
21+
},
22+
"include": ["src/**/*"],
23+
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
24+
}

0 commit comments

Comments
 (0)