Skip to content

Commit ca693c0

Browse files
authored
feat: add support for visualizing histogram counts (#1477)
Adds support for histogram `count` aggregations. This partially resolves #1441, which should probably be split into a new ticket to only address `sum`. As part of this, I also moved the translation functionality for histograms to a new file `histogram.ts` to avoid contributing even more bloat to `renderChartConfig`. Happy to revert this and move that stuff back into the file if that's preferred. I also noticed by doing this that there was actually a SQL error in the snapshots for the tests--the existing quantile test was missing a trailing `,` after the time bucket if no group was provided https://github.com/hyperdxio/hyperdx/blob/main/packages/common-utils/src/__tests__/__snapshots__/renderChartConfig.test.ts.snap#L194 so centralizing like this is probably desirable to keep things consistent. I also personally use webstorm so I added that stuff to the gitignore.
1 parent 12cd643 commit ca693c0

File tree

6 files changed

+544
-230
lines changed

6 files changed

+544
-230
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@hyperdx/common-utils": minor
3+
---
4+
5+
Add support for visualizing histogram counts

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,7 @@ docker-compose.prod.yml
7373
.volumes
7474

7575
# NX
76-
.nx/
76+
.nx/
77+
78+
# webstorm
79+
.idea

packages/common-utils/src/__tests__/__snapshots__/renderChartConfig.test.ts.snap

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,100 @@ exports[`renderChartConfig containing CTE clauses should render a ChSql CTE conf
2626

2727
exports[`renderChartConfig containing CTE clauses should render a chart config CTE configuration correctly 1`] = `"WITH Parts AS (SELECT _part, _part_offset FROM default.some_table WHERE ((FieldA = 'test')) ORDER BY rand() DESC LIMIT 1000) SELECT * FROM Parts WHERE ((FieldA = 'test') AND (indexHint((_part, _part_offset) IN (SELECT tuple(_part, _part_offset) FROM Parts)))) ORDER BY rand() DESC LIMIT 1000"`;
2828

29-
exports[`renderChartConfig histogram metric queries should generate a query with grouping and time bucketing 1`] = `
29+
exports[`renderChartConfig histogram metric queries count should generate a count query with grouping and time bucketing 1`] = `
30+
"WITH source AS (
31+
SELECT
32+
TimeUnix,
33+
AggregationTemporality,
34+
toStartOfInterval(toDateTime(TimeUnix), INTERVAL 2 minute) AS \`__hdx_time_bucket\`,
35+
[ResourceAttributes['host']] AS group,
36+
cityHash64(mapConcat(ScopeAttributes, ResourceAttributes, Attributes)) AS attr_hash,
37+
cityHash64(ExplicitBounds) AS bounds_hash,
38+
toInt64(Count) AS current_count,
39+
lagInFrame(toNullable(current_count), 1, NULL) OVER (
40+
PARTITION BY group, attr_hash, bounds_hash, AggregationTemporality
41+
ORDER BY TimeUnix
42+
) AS prev_count,
43+
CASE
44+
WHEN AggregationTemporality = 1 THEN current_count
45+
WHEN AggregationTemporality = 2 THEN greatest(0, current_count - coalesce(prev_count, 0))
46+
ELSE 0
47+
END AS delta
48+
FROM default.otel_metrics_histogram
49+
WHERE (TimeUnix >= toStartOfInterval(fromUnixTimestamp64Milli(1739318400000), INTERVAL 2 minute) - INTERVAL 2 minute AND TimeUnix <= toStartOfInterval(fromUnixTimestamp64Milli(1765670400000), INTERVAL 2 minute) + INTERVAL 2 minute) AND ((MetricName = 'http.server.duration'))
50+
),metrics AS (
51+
SELECT
52+
\`__hdx_time_bucket\`,
53+
group,
54+
sum(delta) AS \\"Value\\"
55+
FROM source
56+
GROUP BY group, \`__hdx_time_bucket\`
57+
) SELECT \`__hdx_time_bucket\`, group, \\"Value\\" FROM metrics WHERE (\`__hdx_time_bucket\` >= fromUnixTimestamp64Milli(1739318400000) AND \`__hdx_time_bucket\` <= fromUnixTimestamp64Milli(1765670400000)) LIMIT 10 SETTINGS short_circuit_function_evaluation = 'force_enable'"
58+
`;
59+
60+
exports[`renderChartConfig histogram metric queries count should generate a count query without grouping but time bucketing 1`] = `
61+
"WITH source AS (
62+
SELECT
63+
TimeUnix,
64+
AggregationTemporality,
65+
toStartOfInterval(toDateTime(TimeUnix), INTERVAL 2 minute) AS \`__hdx_time_bucket\`,
66+
67+
cityHash64(mapConcat(ScopeAttributes, ResourceAttributes, Attributes)) AS attr_hash,
68+
cityHash64(ExplicitBounds) AS bounds_hash,
69+
toInt64(Count) AS current_count,
70+
lagInFrame(toNullable(current_count), 1, NULL) OVER (
71+
PARTITION BY attr_hash, bounds_hash, AggregationTemporality
72+
ORDER BY TimeUnix
73+
) AS prev_count,
74+
CASE
75+
WHEN AggregationTemporality = 1 THEN current_count
76+
WHEN AggregationTemporality = 2 THEN greatest(0, current_count - coalesce(prev_count, 0))
77+
ELSE 0
78+
END AS delta
79+
FROM default.otel_metrics_histogram
80+
WHERE (TimeUnix >= toStartOfInterval(fromUnixTimestamp64Milli(1739318400000), INTERVAL 2 minute) - INTERVAL 2 minute AND TimeUnix <= toStartOfInterval(fromUnixTimestamp64Milli(1765670400000), INTERVAL 2 minute) + INTERVAL 2 minute) AND ((MetricName = 'http.server.duration'))
81+
),metrics AS (
82+
SELECT
83+
\`__hdx_time_bucket\`,
84+
85+
sum(delta) AS \\"Value\\"
86+
FROM source
87+
GROUP BY \`__hdx_time_bucket\`
88+
) SELECT \`__hdx_time_bucket\`, \\"Value\\" FROM metrics WHERE (\`__hdx_time_bucket\` >= fromUnixTimestamp64Milli(1739318400000) AND \`__hdx_time_bucket\` <= fromUnixTimestamp64Milli(1765670400000)) LIMIT 10 SETTINGS short_circuit_function_evaluation = 'force_enable'"
89+
`;
90+
91+
exports[`renderChartConfig histogram metric queries count should generate a count query without grouping or time bucketing 1`] = `
92+
"WITH source AS (
93+
SELECT
94+
TimeUnix,
95+
AggregationTemporality,
96+
TimeUnix AS \`__hdx_time_bucket\`,
97+
98+
cityHash64(mapConcat(ScopeAttributes, ResourceAttributes, Attributes)) AS attr_hash,
99+
cityHash64(ExplicitBounds) AS bounds_hash,
100+
toInt64(Count) AS current_count,
101+
lagInFrame(toNullable(current_count), 1, NULL) OVER (
102+
PARTITION BY attr_hash, bounds_hash, AggregationTemporality
103+
ORDER BY TimeUnix
104+
) AS prev_count,
105+
CASE
106+
WHEN AggregationTemporality = 1 THEN current_count
107+
WHEN AggregationTemporality = 2 THEN greatest(0, current_count - coalesce(prev_count, 0))
108+
ELSE 0
109+
END AS delta
110+
FROM default.otel_metrics_histogram
111+
WHERE (TimeUnix >= fromUnixTimestamp64Milli(1739318400000) AND TimeUnix <= fromUnixTimestamp64Milli(1765670400000)) AND ((MetricName = 'http.server.duration'))
112+
),metrics AS (
113+
SELECT
114+
\`__hdx_time_bucket\`,
115+
116+
sum(delta) AS \\"Value\\"
117+
FROM source
118+
GROUP BY \`__hdx_time_bucket\`
119+
) SELECT \`__hdx_time_bucket\`, \\"Value\\" FROM metrics WHERE (\`__hdx_time_bucket\` >= fromUnixTimestamp64Milli(1739318400000) AND \`__hdx_time_bucket\` <= fromUnixTimestamp64Milli(1765670400000)) LIMIT 10 SETTINGS short_circuit_function_evaluation = 'force_enable'"
120+
`;
121+
122+
exports[`renderChartConfig histogram metric queries quantile should generate a query with grouping and time bucketing 1`] = `
30123
"WITH source AS (
31124
SELECT
32125
MetricName,
@@ -110,7 +203,7 @@ exports[`renderChartConfig histogram metric queries should generate a query with
110203
) SELECT \`__hdx_time_bucket\`, group, \\"Value\\" FROM metrics WHERE (\`__hdx_time_bucket\` >= fromUnixTimestamp64Milli(1739318400000) AND \`__hdx_time_bucket\` <= fromUnixTimestamp64Milli(1765670400000)) LIMIT 10 SETTINGS short_circuit_function_evaluation = 'force_enable'"
111204
`;
112205

113-
exports[`renderChartConfig histogram metric queries should generate a query without grouping but time bucketing 1`] = `
206+
exports[`renderChartConfig histogram metric queries quantile should generate a query without grouping but time bucketing 1`] = `
114207
"WITH source AS (
115208
SELECT
116209
MetricName,
@@ -194,12 +287,12 @@ exports[`renderChartConfig histogram metric queries should generate a query with
194287
) SELECT \`__hdx_time_bucket\`, \\"Value\\" FROM metrics WHERE (\`__hdx_time_bucket\` >= fromUnixTimestamp64Milli(1739318400000) AND \`__hdx_time_bucket\` <= fromUnixTimestamp64Milli(1765670400000)) LIMIT 10 SETTINGS short_circuit_function_evaluation = 'force_enable'"
195288
`;
196289

197-
exports[`renderChartConfig histogram metric queries should generate a query without grouping or time bucketing 1`] = `
290+
exports[`renderChartConfig histogram metric queries quantile should generate a query without grouping or time bucketing 1`] = `
198291
"WITH source AS (
199292
SELECT
200293
MetricName,
201294
ExplicitBounds,
202-
TimeUnix AS \`__hdx_time_bucket\`
295+
TimeUnix AS \`__hdx_time_bucket\`,
203296
204297
sumForEach(deltas) as rates
205298
FROM (

0 commit comments

Comments
 (0)