diff --git a/apps/studio/components/interfaces/Settings/Logs/Logs.types.ts b/apps/studio/components/interfaces/Settings/Logs/Logs.types.ts index f9c055618af..ff6bfac43a5 100644 --- a/apps/studio/components/interfaces/Settings/Logs/Logs.types.ts +++ b/apps/studio/components/interfaces/Settings/Logs/Logs.types.ts @@ -53,6 +53,7 @@ export interface CountData { export interface EventChartData extends Datum { count: number timestamp: string + has_error: boolean } type LFResponse = { diff --git a/apps/studio/components/interfaces/Settings/Logs/Logs.utils.ts b/apps/studio/components/interfaces/Settings/Logs/Logs.utils.ts index 3410dc3da7b..e336e62dba2 100644 --- a/apps/studio/components/interfaces/Settings/Logs/Logs.utils.ts +++ b/apps/studio/components/interfaces/Settings/Logs/Logs.utils.ts @@ -296,6 +296,24 @@ const calcChartStart = (params: Partial): [Dayjs, string] => return [its.add(-extendValue, trunc), trunc] } +function getErrorCondition(table: LogsTableName): string { + switch (table) { + case 'edge_logs': + return 'response.status_code >= 400' + case 'postgres_logs': + return "parsed.error_severity IN ('ERROR', 'FATAL', 'PANIC')" + case 'function_logs': + return "metadata.level IN ('error', 'fatal')" + case 'auth_logs': + return "metadata.level = 'error' OR metadata.status >= 400" + case 'function_edge_logs': + return 'response.status_code >= 400' + // Add conditions for other log types as needed + default: + return 'false' // Default to no errors if table type is unknown + } +} + /** * * generates log event chart query @@ -308,13 +326,16 @@ export const genChartQuery = ( const [startOffset, trunc] = calcChartStart(params) const where = genWhereStatement(table, filters) + const errorCondition = getErrorCondition(table) + let joins = genCrossJoinUnnests(table) return ` SELECT -- log-event-chart timestamp_trunc(t.timestamp, ${trunc}) as timestamp, - count(t.timestamp) as count + count(t.timestamp) as count, + LOGICAL_OR(${errorCondition}) as has_error FROM ${table} t ${joins} diff --git a/apps/studio/components/interfaces/Settings/Logs/LogsPreviewer.tsx b/apps/studio/components/interfaces/Settings/Logs/LogsPreviewer.tsx index 22d16b44199..f928f01c282 100644 --- a/apps/studio/components/interfaces/Settings/Logs/LogsPreviewer.tsx +++ b/apps/studio/components/interfaces/Settings/Logs/LogsPreviewer.tsx @@ -19,6 +19,7 @@ import { LOGS_TABLES, LOG_ROUTES_WITH_REPLICA_SUPPORT, LogsTableName } from './L import type { Filters, LogSearchCallback, LogTemplate, QueryType } from './Logs.types' import { ensureNoTimestampConflict, maybeShowUpgradePrompt } from './Logs.utils' import UpgradePrompt from './UpgradePrompt' +import dayjs from 'dayjs' /** * Acts as a container component for the entire log display @@ -229,10 +230,18 @@ export const LogsPreviewer = ({ { + // from should be 1 hour before the bar + // to should be 1 hour after the bar + const from = dayjs(isoTimestamp as string) + .subtract(1, 'hour') + .toISOString() + const to = dayjs(isoTimestamp as string) + .add(1, 'hour') + .toISOString() handleSearch('event-chart-bar-click', { query: filters.search_query as string, - to: isoTimestamp as string, - from: null, + to: to, + from: from, }) }} /> diff --git a/apps/studio/components/ui/Charts/BarChart.tsx b/apps/studio/components/ui/Charts/BarChart.tsx index ea05d94ae0e..4417bd50643 100644 --- a/apps/studio/components/ui/Charts/BarChart.tsx +++ b/apps/studio/components/ui/Charts/BarChart.tsx @@ -82,7 +82,7 @@ const BarChart = ({ (focusDataIndex !== null && data && data[focusDataIndex] !== undefined && - day(data[focusDataIndex][xAxisKey]).format(customDateFormat)) || + day(String(data[focusDataIndex][xAxisKey])).format(customDateFormat)) || highlightedLabel ) } @@ -114,9 +114,11 @@ const BarChart = ({ highlightedValue={ typeof resolvedHighlightedValue === 'number' ? numberFormatter(resolvedHighlightedValue, valuePrecision) - : resolvedHighlightedValue + : typeof resolvedHighlightedValue === 'string' + ? resolvedHighlightedValue + : undefined } - highlightedLabel={resolvedHighlightedLabel} + highlightedLabel={String(resolvedHighlightedLabel)} minimalHeader={minimalHeader} /> @@ -163,9 +165,11 @@ const BarChart = ({ key={`cell-${index}`} className={`transition-all duration-300 ${onBarClick ? 'cursor-pointer' : ''}`} fill={ - focusDataIndex === index || focusDataIndex === null - ? CHART_COLORS.GREEN_1 - : CHART_COLORS.GREEN_2 + _entry.has_error + ? CHART_COLORS.YELLOW_1 + : focusDataIndex === index || focusDataIndex === null + ? CHART_COLORS.GREEN_1 + : CHART_COLORS.GREEN_2 } enableBackground={12} /> @@ -176,11 +180,13 @@ const BarChart = ({ {data && (
- {xAxisIsDate ? day(data[0][xAxisKey]).format(customDateFormat) : data[0][xAxisKey]} + {xAxisIsDate + ? day(String(data[0][xAxisKey])).format(customDateFormat) + : data[0][xAxisKey]} {xAxisIsDate - ? day(data[data?.length - 1]?.[xAxisKey]).format(customDateFormat) + ? day(String(data[data?.length - 1]?.[xAxisKey])).format(customDateFormat) : data[data?.length - 1]?.[xAxisKey]}
diff --git a/apps/studio/components/ui/Charts/Charts.constants.ts b/apps/studio/components/ui/Charts/Charts.constants.ts index a8bb2e8aca5..671c5e2d70f 100644 --- a/apps/studio/components/ui/Charts/Charts.constants.ts +++ b/apps/studio/components/ui/Charts/Charts.constants.ts @@ -7,6 +7,7 @@ export const CHART_COLORS = { AXIS: 'hsl(var(--background-overlay-hover))', GREEN_1: 'hsl(var(--brand-default))', // #3ECF8E GREEN_2: 'hsl(var(--brand-500))', + YELLOW_1: 'hsl(var(--warning-600))', } // refer to packages/ui/radix-colors.js for full list of colors diff --git a/apps/studio/components/ui/Charts/Charts.types.tsx b/apps/studio/components/ui/Charts/Charts.types.tsx index 2890e58f444..b836c0973ca 100644 --- a/apps/studio/components/ui/Charts/Charts.types.tsx +++ b/apps/studio/components/ui/Charts/Charts.types.tsx @@ -38,7 +38,7 @@ export type HeaderType = { displayDateInUtc?: boolean } -export type Datum = Record +export type Datum = Record export interface TimeseriesDatum extends Datum { timestamp: string diff --git a/apps/studio/pages/project/[ref]/logs/edge-logs.tsx b/apps/studio/pages/project/[ref]/logs/edge-logs.tsx index 923dca7a204..dcef42de7c7 100644 --- a/apps/studio/pages/project/[ref]/logs/edge-logs.tsx +++ b/apps/studio/pages/project/[ref]/logs/edge-logs.tsx @@ -19,6 +19,6 @@ export const LogPage: NextPageWithLayout = () => { ) } -LogPage.getLayout = (page) => {page} +LogPage.getLayout = (page) => {page} export default LogPage