fix: metrics > logs correlation flow (#711)

Ref: HDX-1537

<img width="907" alt="Screenshot 2025-03-25 at 1 52 45 PM" src="https://github.com/user-attachments/assets/f2cc7f1c-0516-4c04-a339-ec80e4cc188d" />

If no log source is associated with metric source, the app notifies users

<img width="753" alt="image" src="https://github.com/user-attachments/assets/453ea3f7-f721-4189-b035-623602483c6a" />
This commit is contained in:
Warren 2025-03-25 14:28:43 -07:00 committed by GitHub
parent 50ce38f1a9
commit e884d85354
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 7 deletions

View file

@ -0,0 +1,6 @@
---
"@hyperdx/common-utils": patch
"@hyperdx/app": patch
---
fix: metrics > logs correlation flow

View file

@ -3,12 +3,14 @@ import Link from 'next/link';
import cx from 'classnames';
import { add } from 'date-fns';
import { ClickHouseQueryError } from '@hyperdx/common-utils/dist/clickhouse';
import { isMetricChartConfig } from '@hyperdx/common-utils/dist/renderChartConfig';
import {
ChartConfigWithDateRange,
DisplayType,
} from '@hyperdx/common-utils/dist/types';
import { Box, Button, Code, Collapse, Text } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { notifications } from '@mantine/notifications';
import {
convertDateRangeToGranularityString,
@ -132,7 +134,15 @@ export function DBTimeChart({
}, [activeClickPayload]);
const qparams = useMemo(() => {
if (!clickedActiveLabelDate || !sourceId) {
if (clickedActiveLabelDate == null || !source?.id == null) {
return null;
}
const isMetricChart = isMetricChartConfig(config);
if (isMetricChart && source?.logSourceId == null) {
notifications.show({
color: 'yellow',
message: 'No log source is associated with the selected metric source.',
});
return null;
}
const from = clickedActiveLabelDate.getTime();
@ -140,14 +150,14 @@ export function DBTimeChart({
seconds: convertGranularityToSeconds(granularity),
}).getTime();
return new URLSearchParams({
source: sourceId,
source: (isMetricChart ? source?.logSourceId : source?.id) ?? '',
where: config.where,
whereLanguage: config.whereLanguage || 'lucene',
filters: JSON.stringify(config.filters),
from: from.toString(),
to: to.toString(),
});
}, [clickedActiveLabelDate, config, granularity, sourceId]);
}, [clickedActiveLabelDate, config, granularity, source]);
return isLoading && !data ? (
<div className="d-flex h-100 w-100 align-items-center justify-content-center text-muted">

View file

@ -1135,16 +1135,21 @@ async function translateMetricChartConfig(
throw new Error(`no query support for metric type=${metricType}`);
}
export const isMetricChartConfig = (
chartConfig: ChartConfigWithOptDateRange,
) => {
return chartConfig.metricTables != null;
};
export async function renderChartConfig(
rawChartConfig: ChartConfigWithOptDateRange,
metadata: Metadata,
): Promise<ChSql> {
// metric types require more rewriting since we know more about the schema
// but goes through the same generation process
const chartConfig =
rawChartConfig.metricTables != null
? await translateMetricChartConfig(rawChartConfig, metadata)
: rawChartConfig;
const chartConfig = isMetricChartConfig(rawChartConfig)
? await translateMetricChartConfig(rawChartConfig, metadata)
: rawChartConfig;
const withClauses = await renderWith(chartConfig, metadata);
const select = await renderSelect(chartConfig, metadata);