From fa4c7d63b65850b1fcfb9fd23ab15086e55b3084 Mon Sep 17 00:00:00 2001 From: Maximilian Kaske <56969857+mxkaske@users.noreply.github.com> Date: Mon, 13 Nov 2023 17:48:47 +0100 Subject: [PATCH] fix: timezones (#469) * chore: timezone playground * fix: truncate * fix: missing timezone props * wip: small adjustements * fix: og image monitor id * chore: activate cache * chore: update tinybird schema and docs --- apps/docs/developer-guide/setup-env.mdx | 66 ++++++++---- apps/web/src/app/api/og/route.tsx | 8 +- .../play/_components/timezone-combobox.tsx | 101 ++++++++++++++++++ apps/web/src/app/play/layout.tsx | 4 +- apps/web/src/app/play/page.tsx | 62 +++++++++-- apps/web/src/components/marketing/example.tsx | 8 +- .../src/components/status-page/monitor.tsx | 12 ++- apps/web/src/components/tracker.tsx | 14 ++- apps/web/src/lib/tb.ts | 6 +- apps/web/src/lib/tracker.ts | 72 ++++++++----- .../aggregated_monitor_day_mv.pipe | 4 +- .../aggregated_monitor_per_day_mv.datasource | 2 + packages/tinybird/pipes/home_stats.pipe | 2 +- packages/tinybird/pipes/monitor_list.pipe | 14 --- packages/tinybird/pipes/status_timezone.pipe | 47 ++++++++ packages/tinybird/src/client.ts | 12 ++- packages/tinybird/src/validation.ts | 11 +- 17 files changed, 356 insertions(+), 89 deletions(-) create mode 100644 apps/web/src/app/play/_components/timezone-combobox.tsx rename packages/tinybird/{pipes => _legacy}/aggregated_monitor_day_mv.pipe (92%) rename packages/tinybird/{datasources => _legacy}/aggregated_monitor_per_day_mv.datasource (94%) delete mode 100644 packages/tinybird/pipes/monitor_list.pipe create mode 100644 packages/tinybird/pipes/status_timezone.pipe diff --git a/apps/docs/developer-guide/setup-env.mdx b/apps/docs/developer-guide/setup-env.mdx index 1c8551ffd..ada77c158 100644 --- a/apps/docs/developer-guide/setup-env.mdx +++ b/apps/docs/developer-guide/setup-env.mdx @@ -164,7 +164,7 @@ the pipes to the Tinybird server. ### Datasource -We ingest the monitor response into the `ping_response__v3` table. If you want +We ingest the monitor response into the `ping_response__v4` table. If you want to have some dummy data to start with, check out the [csv](/dummy/ping_response__v3.csv) file. @@ -181,7 +181,8 @@ data. We currently have three pipes: -1. `monitor_list__v0`: returns aggregated data from the `ping_response` table. +1. `status_timezone__v0`: returns aggregated data from the `ping_response` + table. 2. `response_list__v0`: returns the list of responses from the `ping_response` table. 3. `home_stats__v0`: returns the total amount of pings during a timeframe from @@ -293,8 +294,8 @@ pip install tinybird-cli > Please make sure while importing you edit the table header fields in > camelcase . -6. Create pipe from the datasource name as a `response_list__v0` and - `monitor_list__v0` +6. Create pipe from the datasource name as a `response_list__v1` and + `status_timezone__v0` 7. Inside `response_list__v0` pipe, create a endpoint by running a following query : @@ -302,7 +303,7 @@ pip install tinybird-cli ``` % SELECT id, latency, monitorId, pageId, region, statusCode, timestamp, url, workspaceId, cronTimestamp - FROM ping_response__v3 + FROM ping_response__v4 WHERE monitorId = {{ String(monitorId, 'openstatusPing') }} {% if defined(region) %} AND region = {{ String(region) }} @@ -320,23 +321,52 @@ pip install tinybird-cli LIMIT {{Int32(limit, 1000)}} ``` -8. Inside `monitor_list__v0` pipe , create a endpoint by running a following +8. Inside `status_timezone__v0` pipe , create a endpoint by running a following query : ``` -% +VERSION 0 + +NODE group_by_cronTimestamp +SQL > + + % SELECT - {% if defined(groupBy) and groupBy == "day" %} - toUnixTimestamp64Milli(toDateTime64(DATE(cronTimestamp / 1000), 3)) - {% else %} - cronTimestamp - {% end %} - AS cronTimestamp, ROUND(AVG(latency)) as avgLatency, COUNT(*) as count, COUNT(CASE WHEN statusCode BETWEEN 200 AND 299 THEN 1 ELSE NULL END) as ok - FROM ping_response__v3 - WHERE monitorId = {{ String(monitorId, 'openstatusPing') }} AND cronTimestamp IS NOT NULL AND cronTimestamp != 0 - GROUP BY cronTimestamp - ORDER BY cronTimestamp DESC - LIMIT {{Int32(limit, 1000)}} + toDateTime(cronTimestamp / 1000, 'UTC') AS day, + -- only for debugging purposes + toTimezone(day, {{ String(timezone, 'Europe/Berlin') }}) as with_timezone, + toStartOfDay(with_timezone) as start_of_day, + avg(latency) AS avgLatency, + count() AS count, + count(multiIf((statusCode >= 200) AND (statusCode <= 299), 1, NULL)) AS ok + FROM ping_response__v4 + WHERE + (day IS NOT NULL) + AND (day != 0) + AND monitorId = {{ String(monitorId, '1') }} + -- By default, we only only query the last 45 days + AND cronTimestamp >= toUnixTimestamp64Milli( + toDateTime64(toStartOfDay(date_sub(DAY, 45, now())), 3) + ) + GROUP BY cronTimestamp, monitorId + ORDER BY day DESC + + + +NODE group_by_day +SQL > + + % + SELECT + start_of_day as day, + sum(count) as count, + sum(ok) as ok, + round(avg(avgLatency)) as avgLatency + FROM group_by_cronTimestamp + GROUP BY start_of_day + ORDER BY start_of_day DESC + LIMIT {{ Int32(limit, 100) }} + ``` diff --git a/apps/web/src/app/api/og/route.tsx b/apps/web/src/app/api/og/route.tsx index afe014a0a..9aa2790ee 100644 --- a/apps/web/src/app/api/og/route.tsx +++ b/apps/web/src/app/api/og/route.tsx @@ -1,3 +1,4 @@ +import { headers } from "next/headers"; import { ImageResponse } from "next/server"; import { DESCRIPTION, TITLE } from "@/app/shared-metadata"; @@ -13,6 +14,7 @@ const size = { }; const LIMIT = 40; +const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; const interRegular = fetch( new URL("../../../public/fonts/Inter-Regular.ttf", import.meta.url), @@ -41,16 +43,20 @@ export async function GET(req: Request) { ? searchParams.get("monitorId") : undefined; + const headersList = headers(); + const timezone = headersList.get("x-vercel-ip-timezone") || currentTimezone; + // currently, we only show the tracker for a single(!) monitor const data = (monitorId && (await getMonitorListData({ monitorId, limit: LIMIT, + timezone, }))) || []; - const { bars, uptime } = cleanData({ data, last: LIMIT }); + const { bars, uptime } = cleanData(data, LIMIT); return new ImageResponse( ( diff --git a/apps/web/src/app/play/_components/timezone-combobox.tsx b/apps/web/src/app/play/_components/timezone-combobox.tsx new file mode 100644 index 000000000..834f0b87a --- /dev/null +++ b/apps/web/src/app/play/_components/timezone-combobox.tsx @@ -0,0 +1,101 @@ +"use client"; + +import * as React from "react"; +import { usePathname, useRouter } from "next/navigation"; +import { Check, ChevronsUpDown } from "lucide-react"; + +import { + Button, + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + Popover, + PopoverContent, + PopoverTrigger, +} from "@openstatus/ui"; + +import useUpdateSearchParams from "@/hooks/use-update-search-params"; +import { cn } from "@/lib/utils"; + +const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; +const supportedTimezones = Intl.supportedValuesOf("timeZone"); + +export function TimezoneCombobox({ defaultValue }: { defaultValue?: string }) { + const [open, setOpen] = React.useState(false); + const pathname = usePathname(); + const router = useRouter(); + const updateSearchParams = useUpdateSearchParams(); + + const value = defaultValue?.toLowerCase(); + + const timezones = supportedTimezones.map((timezone) => ({ + value: timezone.toLowerCase(), + label: timezone, + })); + + return ( + + + + + + + + No timezone found. + + {timezones.map((timezone) => ( + { + setOpen(false); + + // update search params + const searchParams = updateSearchParams({ + timezone: + currentValue === value + ? null // remove search param and use default timezone + : timezones.find( + (timezone) => timezone.value === currentValue, + )?.label || null, + }); + + // refresh page with new search params + router.replace(`${pathname}?${searchParams}`); + router.refresh(); + }} + > + + {timezone.label} + + ))} + + + + + ); +} diff --git a/apps/web/src/app/play/layout.tsx b/apps/web/src/app/play/layout.tsx index 40370b430..40ba3a6f4 100644 --- a/apps/web/src/app/play/layout.tsx +++ b/apps/web/src/app/play/layout.tsx @@ -14,11 +14,11 @@ export const metadata: Metadata = { ...defaultMetadata, twitter: { ...twitterMetadata, - images: [`/api/og?monitorId=openstatus`], + images: [`/api/og?monitorId=1`], }, openGraph: { ...ogMetadata, - images: [`/api/og?monitorId=openstatus`], + images: [`/api/og?monitorId=1`], }, }; diff --git a/apps/web/src/app/play/page.tsx b/apps/web/src/app/play/page.tsx index fa8717331..9bc407e26 100644 --- a/apps/web/src/app/play/page.tsx +++ b/apps/web/src/app/play/page.tsx @@ -1,14 +1,55 @@ +import { headers } from "next/headers"; +import * as z from "zod"; + +import { Label } from "@openstatus/ui"; + import { Tracker } from "@/components/tracker"; import { getHomeMonitorListData } from "@/lib/tb"; +import { TimezoneCombobox } from "./_components/timezone-combobox"; + +const supportedTimezones = Intl.supportedValuesOf("timeZone"); +const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; + +/** + * allowed URL search params + */ +const searchParamsSchema = z.object({ + timezone: z.string().optional(), +}); + +export default async function PlayPage({ + searchParams, +}: { + searchParams: { [key: string]: string | string[] | undefined }; +}) { + const headersList = headers(); + const timezone = headersList.get("x-vercel-ip-timezone") || currentTimezone; + + const search = searchParamsSchema.safeParse(searchParams); + + function getDefaultValue() { + if ( + search.success && + search.data.timezone && + supportedTimezones.includes(search.data.timezone) + ) { + return search.data.timezone; + } + return timezone; + } + + const defaultValue = getDefaultValue(); + + const data = await getHomeMonitorListData({ timezone: defaultValue }); -export default async function PlayPage() { - const data = await getHomeMonitorListData(); return ( -
-

Status

-

- Build your own within seconds. -

+
+
+

Status

+

+ Build your own within seconds. +

+
{data && ( )}
+
+
+ + +
+
); } diff --git a/apps/web/src/components/marketing/example.tsx b/apps/web/src/components/marketing/example.tsx index 5b0efe861..d1e2ef728 100644 --- a/apps/web/src/components/marketing/example.tsx +++ b/apps/web/src/components/marketing/example.tsx @@ -1,4 +1,5 @@ import { Suspense } from "react"; +import { headers } from "next/headers"; import Link from "next/link"; import { Button } from "@openstatus/ui"; @@ -7,6 +8,8 @@ import { Shell } from "@/components/dashboard/shell"; import { Tracker } from "@/components/tracker"; import { getHomeMonitorListData } from "@/lib/tb"; +const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; + export async function Example() { return ( @@ -35,7 +38,9 @@ function ExampleTrackerFallback() { } async function ExampleTracker() { - const data = await getHomeMonitorListData(); + const headersList = headers(); + const timezone = headersList.get("x-vercel-ip-timezone") || currentTimezone; + const data = await getHomeMonitorListData({ timezone }); if (!data) return null; return ( ); } diff --git a/apps/web/src/components/status-page/monitor.tsx b/apps/web/src/components/status-page/monitor.tsx index 21676e7b2..423e80382 100644 --- a/apps/web/src/components/status-page/monitor.tsx +++ b/apps/web/src/components/status-page/monitor.tsx @@ -1,3 +1,4 @@ +import { headers } from "next/headers"; import type { z } from "zod"; import type { selectPublicMonitorSchema } from "@openstatus/db/src/schema"; @@ -5,13 +6,22 @@ import type { selectPublicMonitorSchema } from "@openstatus/db/src/schema"; import { getMonitorListData } from "@/lib/tb"; import { Tracker } from "../tracker"; +const currentTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone; + export const Monitor = async ({ monitor, }: { monitor: z.infer; }) => { - const data = await getMonitorListData({ monitorId: String(monitor.id) }); + const headersList = headers(); + const timezone = headersList.get("x-vercel-ip-timezone") || currentTimezone; + + const data = await getMonitorListData({ + monitorId: String(monitor.id), + timezone, + }); if (!data) return
Something went wrong
; + return ( (isMobile ? 35 : 45), [isMobile]); - const { bars, uptime } = cleanData({ data, last: maxSize }); + const { bars, uptime } = cleanData(data, maxSize, timezone); return (
@@ -134,6 +136,11 @@ const Bar = ({ const toDate = date.setDate(date.getDate() + 1); const dateFormat = "dd/MM/yy"; + const className = tracker({ + variant: blacklist ? "blacklist" : getStatus(ratio).variant, + }); + // console.log({ className, blacklist }); + return ( setOpen(true)} asChild>
diff --git a/apps/web/src/lib/tb.ts b/apps/web/src/lib/tb.ts index ca886a9b1..011abd641 100644 --- a/apps/web/src/lib/tb.ts +++ b/apps/web/src/lib/tb.ts @@ -37,9 +37,11 @@ export async function getMonitorListData(props: MonitorListParams) { } // Includes caching of data for 10 minutes -export async function getHomeMonitorListData() { +export async function getHomeMonitorListData( + props: Pick, +) { try { - const res = await getHomeMonitorList(tb)({ monitorId: "1" }); + const res = await getHomeMonitorList(tb)({ monitorId: "1", ...props }); return res.data; } catch (e) { console.error(e); diff --git a/apps/web/src/lib/tracker.ts b/apps/web/src/lib/tracker.ts index 859d67ee1..868fae9c6 100644 --- a/apps/web/src/lib/tracker.ts +++ b/apps/web/src/lib/tracker.ts @@ -36,20 +36,33 @@ export const getStatus = (ratio: number): GetStatusReturnType => { // TODO: move into Class component sharing the same `data` -export type CleanMonitor = Monitor & { +// FIXME: name TrackerMonitor + +export type CleanMonitor = { + count: number; + ok: number; + avgLatency: number; + cronTimestamp: number; blacklist?: string; }; -export function cleanData({ data, last }: { data: Monitor[]; last: number }) { - const today = new Date(); +/** + * Clean the data to show only the last X days + * @param data array of monitors + * @param last number of days to show + * @param timeZone timezone of the monitor + * @returns + */ +export function cleanData(data: Monitor[], last: number, timeZone?: string) { + const today = new Date(new Date().toLocaleString("en-US", { timeZone })); const currentDay = new Date(today); - currentDay.setUTCDate(today.getDate()); - currentDay.setUTCHours(0, 0, 0, 0); + currentDay.setDate(today.getDate()); + currentDay.setHours(0, 0, 0, 0); const lastDay = new Date(today); - lastDay.setUTCDate(today.getDate() - last); - lastDay.setUTCHours(0, 0, 0, 0); + lastDay.setDate(today.getDate() - last); + lastDay.setHours(0, 0, 0, 0); const dateSequence = generateDateSequence(lastDay, currentDay); @@ -67,24 +80,26 @@ function fillEmptyData(data: Monitor[], dateSequence: Date[]) { for (const date of dateSequence) { const timestamp = date.getTime(); const cronTimestamp = - dataIndex < data.length ? data[dataIndex].cronTimestamp : undefined; + dataIndex < data.length ? data[dataIndex].day.getTime() : undefined; + if ( cronTimestamp && - areDatesEqualByDayMonthYear(new Date(cronTimestamp), date) + areDatesEqualByDayMonthYear(date, new Date(cronTimestamp)) ) { - const isBlacklisted = isInBlacklist(cronTimestamp); + const blacklist = isInBlacklist(cronTimestamp); /** * automatically remove the data from the array to avoid wrong uptime * that provides time to remove cursed logs from tinybird via mv migration */ - if (isBlacklisted) { + if (blacklist) { filledData.push({ - ...emptyData(timestamp), - blacklist: blacklistDates[cronTimestamp], + ...emptyData(cronTimestamp), + blacklist, }); } else { - filledData.push(data[dataIndex]); + const { day, ...props } = data[dataIndex]; + filledData.push({ ...props, cronTimestamp }); } dataIndex++; } else { @@ -105,17 +120,17 @@ function emptyData(cronTimestamp: number) { } /** - * equal UTC days - fixes issue with daylight saving + * equal days - fixes issue with daylight saving * @param date1 * @param date2 * @returns */ function areDatesEqualByDayMonthYear(date1: Date, date2: Date) { - date1.setUTCDate(date1.getDate()); - date1.setUTCHours(0, 0, 0, 0); + date1.setDate(date1.getDate()); + date1.setHours(0, 0, 0, 0); - date2.setUTCDate(date2.getDate()); - date2.setUTCHours(0, 0, 0, 0); + date2.setDate(date2.getDate()); + date2.setHours(0, 0, 0, 0); return date1.toUTCString() === date2.toUTCString(); } @@ -132,13 +147,13 @@ export function generateDateSequence(startDate: Date, endDate: Date): Date[] { while (currentDate <= endDate) { dateSequence.push(new Date(currentDate)); - currentDate.setUTCDate(currentDate.getDate() + 1); + currentDate.setDate(currentDate.getDate() + 1); } return dateSequence.reverse(); } -export function getTotalUptime(data: Monitor[]) { +export function getTotalUptime(data: { ok: number; count: number }[]) { const reducedData = data.reduce( (prev, curr) => { prev.ok += curr.ok; @@ -153,7 +168,7 @@ export function getTotalUptime(data: Monitor[]) { return reducedData; } -export function getTotalUptimeString(data: Monitor[]) { +export function getTotalUptimeString(data: { ok: number; count: number }[]) { const reducedData = getTotalUptime(data); const uptime = (reducedData.ok / reducedData.count) * 100; @@ -163,17 +178,20 @@ export function getTotalUptimeString(data: Monitor[]) { } export function isInBlacklist(timestamp: number) { - return Object.keys(blacklistDates).includes(timestamp.toString()); + const el = Object.keys(blacklistDates).find((date) => + areDatesEqualByDayMonthYear(new Date(date), new Date(timestamp)), + ); + return el ? blacklistDates[el] : undefined; } /** * Blacklist dates where we had issues with data collection */ -export const blacklistDates: Record = { - 1692921600000: +export const blacklistDates: Record = { + "Fri Aug 25 2023": "OpenStatus faced issues between 24.08. and 27.08., preventing data collection.", - 1693008000000: + "Sat Aug 26 2023": "OpenStatus faced issues between 24.08. and 27.08., preventing data collection.", - 1697587200000: + "Wed Oct 18 2023": "OpenStatus migrated from Vercel to Fly to improve the performance of the checker.", }; diff --git a/packages/tinybird/pipes/aggregated_monitor_day_mv.pipe b/packages/tinybird/_legacy/aggregated_monitor_day_mv.pipe similarity index 92% rename from packages/tinybird/pipes/aggregated_monitor_day_mv.pipe rename to packages/tinybird/_legacy/aggregated_monitor_day_mv.pipe index 21c0ad324..da595cbff 100644 --- a/packages/tinybird/pipes/aggregated_monitor_day_mv.pipe +++ b/packages/tinybird/_legacy/aggregated_monitor_day_mv.pipe @@ -1,3 +1,5 @@ +# REMINDER: legacy + VERSION 0 NODE aggregated_monitor_day_0 @@ -9,7 +11,7 @@ SQL > avgState(latency) AS avgLatency, countState() AS count, countState(multiIf((statusCode >= 200) AND (statusCode <= 299), 1, NULL)) AS ok - FROM ping_response__v3 + FROM ping_response__v4 WHERE (day IS NOT NULL) AND (day != 0) GROUP BY day, diff --git a/packages/tinybird/datasources/aggregated_monitor_per_day_mv.datasource b/packages/tinybird/_legacy/aggregated_monitor_per_day_mv.datasource similarity index 94% rename from packages/tinybird/datasources/aggregated_monitor_per_day_mv.datasource rename to packages/tinybird/_legacy/aggregated_monitor_per_day_mv.datasource index 5f018bc5a..f3a05b093 100644 --- a/packages/tinybird/datasources/aggregated_monitor_per_day_mv.datasource +++ b/packages/tinybird/_legacy/aggregated_monitor_per_day_mv.datasource @@ -1,3 +1,5 @@ +# REMINDER: legacy + # Data Source created from Pipe 'aggregated_monitor_day_mv' VERSION 0 diff --git a/packages/tinybird/pipes/home_stats.pipe b/packages/tinybird/pipes/home_stats.pipe index 85c2c0fcc..5955f688a 100644 --- a/packages/tinybird/pipes/home_stats.pipe +++ b/packages/tinybird/pipes/home_stats.pipe @@ -5,7 +5,7 @@ SQL > % SELECT COUNT(*) as count - FROM ping_response__v3 + FROM ping_response__v4 {% if defined(period) %} {% if String(period) == "1h" %} WHERE cronTimestamp > toUnixTimestamp(now() - INTERVAL 1 HOUR) * 1000 diff --git a/packages/tinybird/pipes/monitor_list.pipe b/packages/tinybird/pipes/monitor_list.pipe deleted file mode 100644 index 5cd36e7de..000000000 --- a/packages/tinybird/pipes/monitor_list.pipe +++ /dev/null @@ -1,14 +0,0 @@ -VERSION 1 - -NODE monitor_list_0 -SQL > - - % - SELECT day as cronTimestamp, round(avgMerge(avgLatency)) avgLatency, countMerge(ok) ok, countMerge(count) count - FROM aggregated_monitor_per_day_mv - WHERE monitorId = {{ String(monitorId, 'openstatusPing') }} - GROUP BY day, monitorId - ORDER BY cronTimestamp DESC - LIMIT {{Int32(limit, 100)}} - - diff --git a/packages/tinybird/pipes/status_timezone.pipe b/packages/tinybird/pipes/status_timezone.pipe new file mode 100644 index 000000000..820f06b85 --- /dev/null +++ b/packages/tinybird/pipes/status_timezone.pipe @@ -0,0 +1,47 @@ +VERSION 0 + +DESCRIPTION > + TODO: descripe what it is for! + + +NODE group_by_cronTimestamp +SQL > + + % + SELECT + toDateTime(cronTimestamp / 1000, 'UTC') AS day, + -- only for debugging purposes + toTimezone(day, {{ String(timezone, 'Europe/Berlin') }}) as with_timezone, + toStartOfDay(with_timezone) as start_of_day, + avg(latency) AS avgLatency, + count() AS count, + count(multiIf((statusCode >= 200) AND (statusCode <= 299), 1, NULL)) AS ok + FROM ping_response__v4 + WHERE + (day IS NOT NULL) + AND (day != 0) + AND monitorId = {{ String(monitorId, '1') }} + -- By default, we only only query the last 45 days + AND cronTimestamp >= toUnixTimestamp64Milli( + toDateTime64(toStartOfDay(date_sub(DAY, 45, now())), 3) + ) + GROUP BY cronTimestamp, monitorId + ORDER BY day DESC + + + +NODE group_by_day +SQL > + + % + SELECT + start_of_day as day, + sum(count) as count, + sum(ok) as ok, + round(avg(avgLatency)) as avgLatency + FROM group_by_cronTimestamp + GROUP BY start_of_day + ORDER BY start_of_day DESC + LIMIT {{ Int32(limit, 100) }} + + diff --git a/packages/tinybird/src/client.ts b/packages/tinybird/src/client.ts index b9d3d8aad..2b5109f51 100644 --- a/packages/tinybird/src/client.ts +++ b/packages/tinybird/src/client.ts @@ -24,18 +24,20 @@ export function getResponseList(tb: Tinybird) { parameters: tbParameterResponseList, data: tbBuildResponseList, opts: { - cache: "no-store", + // cache: "no-store", + revalidate: 30, // 30 seconds cache }, }); } export function getMonitorList(tb: Tinybird) { return tb.buildPipe({ - pipe: "monitor_list__v1", + pipe: "status_timezone__v0", parameters: tbParameterMonitorList, data: tbBuildMonitorList, opts: { - cache: "no-store", + // cache: "no-store", + revalidate: 30, // 30 seconds cache }, }); } @@ -47,7 +49,7 @@ export function getMonitorList(tb: Tinybird) { */ export function getHomeMonitorList(tb: Tinybird) { return tb.buildPipe({ - pipe: "monitor_list__v1", + pipe: "status_timezone__v0", parameters: tbParameterMonitorList, data: tbBuildMonitorList, opts: { @@ -65,7 +67,7 @@ export function getHomeStats(tb: Tinybird) { parameters: tbParameterHomeStats, data: tbBuildHomeStats, opts: { - revalidate: 86400, // 60 * 60 * 24 = 86400s - 1d + revalidate: 86400, // 60 * 60 * 24 = 86400s = 1d }, }); } diff --git a/packages/tinybird/src/validation.ts b/packages/tinybird/src/validation.ts index c59f4eed9..e7d1766ee 100644 --- a/packages/tinybird/src/validation.ts +++ b/packages/tinybird/src/validation.ts @@ -68,21 +68,22 @@ export const tbParameterResponseList = z.object({ }); /** - * Params for pipe monitor_list__v1 + * Params for pipe status_timezone__v0 */ export const tbParameterMonitorList = z.object({ monitorId: z.string(), - limit: z.number().int().default(60).optional(), // 40 days + timezone: z.string().optional(), + limit: z.number().int().default(46).optional(), // 46 days }); /** - * Values from the pipe monitor_list__v1 + * Values from the pipe status_timezone__v0 */ export const tbBuildMonitorList = z.object({ count: z.number().int(), ok: z.number().int(), - avgLatency: z.number().int(), // in ms - cronTimestamp: z.number().int(), + avgLatency: z.number().int(), + day: z.coerce.date(), }); /** -- 2.54.0