diff --git a/.changeset/olive-peaches-marry.md b/.changeset/olive-peaches-marry.md new file mode 100644 index 00000000..4181f8a2 --- /dev/null +++ b/.changeset/olive-peaches-marry.md @@ -0,0 +1,5 @@ +--- +"@hyperdx/common-utils": patch +--- + +fix: aggCondition issue in sum/gauge/histogram metrics diff --git a/packages/common-utils/src/__tests__/__snapshots__/renderChartConfig.test.ts.snap b/packages/common-utils/src/__tests__/__snapshots__/renderChartConfig.test.ts.snap index 6b346045..59617538 100644 --- a/packages/common-utils/src/__tests__/__snapshots__/renderChartConfig.test.ts.snap +++ b/packages/common-utils/src/__tests__/__snapshots__/renderChartConfig.test.ts.snap @@ -41,7 +41,7 @@ exports[`renderChartConfig should generate sql for a single histogram metric 1`] SELECT *, cityHash64(mapConcat(ScopeAttributes, ResourceAttributes, Attributes)) AS AttributesHash, length(BucketCounts) as CountLength FROM default.otel_metrics_histogram) - WHERE MetricName = 'http.server.duration' + WHERE (TimeUnix >= fromUnixTimestamp64Milli(1739318400000) AND TimeUnix <= fromUnixTimestamp64Milli(1765670400000)) AND ((MetricName = 'http.server.duration')) ORDER BY Attributes, TimeUnix ASC ),RawHist AS ( SELECT *, toUInt64( 0.5 * arraySum(BucketRates)) AS Rank, diff --git a/packages/common-utils/src/renderChartConfig.ts b/packages/common-utils/src/renderChartConfig.ts index c4beef4c..9199329a 100644 --- a/packages/common-utils/src/renderChartConfig.ts +++ b/packages/common-utils/src/renderChartConfig.ts @@ -867,6 +867,7 @@ async function translateMetricChartConfig( { ..._select, valueExpression: 'LastValue', + aggCondition: '', // clear up the condition since the where clause is already applied at the upstream CTE }, ], from: { @@ -959,7 +960,13 @@ async function translateMetricChartConfig( `, }, ], - select, + select: [ + { + ..._select, + valueExpression: 'Value', + aggCondition: '', // clear up the condition since the where clause is already applied at the upstream CTE + }, + ], from: { databaseName: '', tableName: 'Bucketed', @@ -977,6 +984,31 @@ async function translateMetricChartConfig( throw new Error('quantile must be specified for histogram metrics'); } + // Render the where clause to limit data selection on the source CTE but also search forward/back one + // bucket window to ensure that there is enough data to compute a reasonable value on the ends of the + // series. + const where = await renderWhere( + { + ...chartConfig, + from: { + ...from, + tableName: metricTables[MetricsDataType.Histogram], + }, + filters: [ + { + type: 'sql', + condition: `MetricName = '${metricName}'`, + }, + ], + includedDataInterval: + chartConfig.granularity === 'auto' && + Array.isArray(chartConfig.dateRange) + ? convertDateRangeToGranularityString(chartConfig.dateRange, 60) + : chartConfig.granularity, + }, + metadata, + ); + return { ...restChartConfig, with: [ @@ -994,7 +1026,7 @@ async function translateMetricChartConfig( SELECT *, cityHash64(mapConcat(ScopeAttributes, ResourceAttributes, Attributes)) AS AttributesHash, length(BucketCounts) as CountLength FROM ${renderFrom({ from: { ...from, tableName: metricTables[MetricsDataType.Histogram] } })}) - WHERE MetricName = '${metricName}' + WHERE ${where} ORDER BY Attributes, TimeUnix ASC `, }, @@ -1019,6 +1051,7 @@ async function translateMetricChartConfig( { ..._selectRest, aggFn: 'sum', + aggCondition: '', // clear up the condition since the where clause is already applied at the upstream CTE valueExpression: 'Rate', }, ],