Skip to content

Commit 4914df2

Browse files
committed
fix(dashboard): use AE-compatible observability buckets
1 parent b8a6cee commit 4914df2

2 files changed

Lines changed: 18 additions & 11 deletions

File tree

src/lib/edge/__tests__/admin-bot-analytics.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,8 +552,9 @@ describe("admin bot analytics handlers", () => {
552552
`timestamp >= toDateTime(${Math.floor(expectedFrom / 1000)})`,
553553
);
554554
expect(allSql.join("\n")).toContain(
555-
"toStartOfInterval(timestamp, INTERVAL 1 DAY, 'Asia/Shanghai')",
555+
"intDiv(toUnixTimestamp(timestamp) + 28800, 86400)",
556556
);
557+
expect(allSql.join("\n")).not.toContain("toStartOfInterval");
557558
expect(body.trend[0]?.timestampMs).toBe(expectedFrom);
558559
});
559560

src/lib/edge/admin-bot-analytics.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
resolveReportingTimeZone,
1414
startOfZonedDay,
1515
startOfZonedInterval,
16+
timeZoneOffsetMinutes,
1617
} from "@/lib/dashboard/time-zone";
1718

1819
import { requireActor } from "./admin-auth";
@@ -288,7 +289,11 @@ function buildCountByBucketSql(input: {
288289
const dataset = analyticsDatasetIdentifier(input.dataset);
289290
const fromSeconds = Math.floor(input.from / 1000);
290291
const toSeconds = Math.ceil(input.to / 1000);
291-
const bucketExpression = `toUnixTimestamp(toStartOfInterval(timestamp, INTERVAL 1 ${analyticsBucketUnit(input.interval)}, ${analyticsSqlString(input.timeZone)})) * 1000`;
292+
const bucketSeconds = Math.max(60, Math.floor(input.bucketMs / 1000));
293+
const bucketOffsetSeconds =
294+
timeZoneOffsetMinutes(input.timeZone, input.from) * 60 +
295+
(input.interval === "week" ? 3 * 24 * 60 * 60 : 0);
296+
const bucketExpression = `(intDiv(toUnixTimestamp(timestamp) + ${bucketOffsetSeconds}, ${bucketSeconds}) * ${bucketSeconds} - ${bucketOffsetSeconds}) * 1000`;
292297
const latencySelect =
293298
input.includeLatency && input.source === "normal"
294299
? `,
@@ -309,13 +314,6 @@ function buildCountByBucketSql(input: {
309314
`;
310315
}
311316

312-
function analyticsBucketUnit(interval: BotAnalyticsInterval): string {
313-
if (interval === "minute") return "MINUTE";
314-
if (interval === "hour") return "HOUR";
315-
if (interval === "week") return "WEEK";
316-
return "DAY";
317-
}
318-
319317
function buildMapPointsSql(input: {
320318
dataset: string;
321319
from: number;
@@ -949,7 +947,11 @@ function mergeTrendRows(input: {
949947
});
950948
}
951949
for (const row of input.abnormalRows) {
952-
const timestampMs = Math.floor(toFiniteNumber(row.timestampMs));
950+
const timestampMs = bucketTimestamp(
951+
Math.floor(toFiniteNumber(row.timestampMs)),
952+
input.interval,
953+
input.timeZone,
954+
);
953955
const current = trend.get(timestampMs);
954956
if (!current) continue;
955957
current.abnormalCount = Math.max(0, Math.trunc(toFiniteNumber(row.count)));
@@ -961,7 +963,11 @@ function mergeTrendRows(input: {
961963
);
962964
}
963965
for (const row of input.normalRows) {
964-
const timestampMs = Math.floor(toFiniteNumber(row.timestampMs));
966+
const timestampMs = bucketTimestamp(
967+
Math.floor(toFiniteNumber(row.timestampMs)),
968+
input.interval,
969+
input.timeZone,
970+
);
965971
const current = trend.get(timestampMs);
966972
if (!current) continue;
967973
current.normalCount = Math.max(0, Math.trunc(toFiniteNumber(row.count)));

0 commit comments

Comments
 (0)