mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
fix: Fix queries/minute calculation in Services Dashboard (#1457)
Closes HDX-2973 # Summary This PR updates the queries on the services dashboard to 1. Fix the queries/min calculation, which was previously just the total number of queries 2. Support materialized views in the enterprise edition by separating aggregations from conversions to rates and millisecond values. ## Queries/Min Before: <img width="779" height="100" alt="Screenshot 2025-12-09 at 11 28 00 AM" src="https://github.com/user-attachments/assets/52f2581f-5af4-4528-bdb6-5505e5ed7709" /> <img width="1511" height="842" alt="Screenshot 2025-12-09 at 11 27 17 AM" src="https://github.com/user-attachments/assets/94ea121d-02ce-4460-a1c9-cc6f9e9cd8d3" /> After: <img width="776" height="129" alt="Screenshot 2025-12-09 at 11 28 27 AM" src="https://github.com/user-attachments/assets/5c23bd73-23ea-4d44-a2e9-e4f01b93dc3c" /> <img width="1511" height="787" alt="Screenshot 2025-12-09 at 11 28 33 AM" src="https://github.com/user-attachments/assets/9c8d1932-f1ac-49bc-b122-7229cd8ad360" />
This commit is contained in:
parent
b564a369be
commit
776e392777
3 changed files with 88 additions and 27 deletions
5
.changeset/ten-cups-jam.md
Normal file
5
.changeset/ten-cups-jam.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@hyperdx/app": patch
|
||||
---
|
||||
|
||||
fix: Fix queries/minute calculation in Services Dashboard
|
||||
|
|
@ -631,7 +631,9 @@ function HttpTab({
|
|||
selectGroupBy: false,
|
||||
groupBy: expressions.endpoint,
|
||||
orderBy: '"Total (ms)" DESC',
|
||||
filters: getScopedFilters({ appliedConfig, expressions }),
|
||||
filters: [
|
||||
...getScopedFilters({ appliedConfig, expressions }),
|
||||
],
|
||||
dateRange: searchedTimeRange,
|
||||
numberFormat: MS_NUMBER_FORMAT,
|
||||
limit: { limit: 20 },
|
||||
|
|
@ -803,11 +805,16 @@ function DatabaseTab({
|
|||
where: appliedConfig.where || '',
|
||||
whereLanguage: appliedConfig.whereLanguage || 'sql',
|
||||
select: [
|
||||
// Separate the aggregations from the conversion to ms so that AggregatingMergeTree MVs can be used
|
||||
{
|
||||
alias: 'total_query_time_ns',
|
||||
aggFn: 'sum',
|
||||
valueExpression: expressions.duration,
|
||||
aggCondition: '',
|
||||
},
|
||||
{
|
||||
alias: 'total_query_time_ms',
|
||||
aggFn: 'sum',
|
||||
valueExpression: expressions.durationInMillis,
|
||||
aggCondition: '',
|
||||
valueExpression: `total_query_time_ns / ${expressions.durationDivisorForMillis}`,
|
||||
},
|
||||
{
|
||||
alias: 'Statement',
|
||||
|
|
@ -1090,6 +1097,12 @@ function DatabaseTab({
|
|||
valueColumn="Total"
|
||||
hoverCardPosition="top-start"
|
||||
getRowSearchLink={getRowSearchLink}
|
||||
hiddenSeries={[
|
||||
'total_duration_ns',
|
||||
'total_queries',
|
||||
'p95_duration_ns',
|
||||
'p50_duration_ns',
|
||||
]}
|
||||
config={{
|
||||
...source,
|
||||
where: appliedConfig.where || '',
|
||||
|
|
@ -1099,35 +1112,51 @@ function DatabaseTab({
|
|||
selectGroupBy: false,
|
||||
orderBy: '"Total" DESC',
|
||||
select: [
|
||||
// Separate the aggregations from the conversion to ms and rate so that AggregatingMergeTree MVs can be used
|
||||
{
|
||||
alias: 'Statement',
|
||||
valueExpression: expressions.dbStatement,
|
||||
},
|
||||
{
|
||||
alias: 'Total',
|
||||
alias: 'total_duration_ns',
|
||||
aggFn: 'sum',
|
||||
valueExpression: expressions.duration,
|
||||
aggCondition: '',
|
||||
valueExpression: expressions.durationInMillis,
|
||||
},
|
||||
{
|
||||
alias: 'Total',
|
||||
valueExpression: `total_duration_ns / ${expressions.durationDivisorForMillis}`,
|
||||
},
|
||||
{
|
||||
alias: 'total_queries',
|
||||
aggFn: 'count',
|
||||
valueExpression: '',
|
||||
},
|
||||
{
|
||||
alias: 'Queries/Min',
|
||||
aggFn: 'count',
|
||||
valueExpression: `value / age('mi', toDateTime(${searchedTimeRange[0].getTime() / 1000}), toDateTime(${searchedTimeRange[1].getTime() / 1000}))`,
|
||||
valueExpression: `total_queries / age('mi', toDateTime(${searchedTimeRange[0].getTime() / 1000}), toDateTime(${searchedTimeRange[1].getTime() / 1000}))`,
|
||||
},
|
||||
{
|
||||
alias: 'p95_duration_ns',
|
||||
aggFn: 'quantile',
|
||||
level: 0.95,
|
||||
valueExpression: expressions.duration,
|
||||
aggCondition: '',
|
||||
},
|
||||
{
|
||||
alias: 'P95 (ms)',
|
||||
valueExpression: `p95_duration_ns / ${expressions.durationDivisorForMillis}`,
|
||||
},
|
||||
{
|
||||
alias: 'p50_duration_ns',
|
||||
aggFn: 'quantile',
|
||||
valueExpression: expressions.durationInMillis,
|
||||
level: 0.5,
|
||||
valueExpression: expressions.duration,
|
||||
aggCondition: '',
|
||||
level: 0.95,
|
||||
},
|
||||
{
|
||||
alias: 'Median (ms)',
|
||||
aggFn: 'quantile',
|
||||
valueExpression: expressions.durationInMillis,
|
||||
aggCondition: '',
|
||||
level: 0.5,
|
||||
valueExpression: `p50_duration_ns / ${expressions.durationDivisorForMillis}`,
|
||||
},
|
||||
],
|
||||
filters: [
|
||||
|
|
@ -1144,6 +1173,12 @@ function DatabaseTab({
|
|||
) : (
|
||||
<DBTableChart
|
||||
getRowSearchLink={getRowSearchLink}
|
||||
hiddenColumns={[
|
||||
'duration_ns',
|
||||
'total_count',
|
||||
'p95_duration_ns',
|
||||
'p50_duration_ns',
|
||||
]}
|
||||
config={{
|
||||
...source,
|
||||
where: appliedConfig.where || '',
|
||||
|
|
@ -1158,31 +1193,46 @@ function DatabaseTab({
|
|||
valueExpression: expressions.dbStatement,
|
||||
},
|
||||
{
|
||||
alias: 'Total',
|
||||
alias: 'duration_ns',
|
||||
aggFn: 'sum',
|
||||
valueExpression: expressions.duration,
|
||||
aggCondition: '',
|
||||
valueExpression: expressions.durationInMillis,
|
||||
},
|
||||
{
|
||||
alias: 'Total',
|
||||
valueExpression: `duration_ns / ${expressions.durationDivisorForMillis}`,
|
||||
},
|
||||
{
|
||||
alias: 'total_count',
|
||||
aggFn: 'count',
|
||||
valueExpression: '',
|
||||
},
|
||||
{
|
||||
alias: 'Queries/Min',
|
||||
aggFn: 'count',
|
||||
valueExpression: `value / age('mi', toDateTime(${searchedTimeRange[0].getTime() / 1000}), toDateTime(${searchedTimeRange[1].getTime() / 1000}))`,
|
||||
aggCondition: '',
|
||||
valueExpression: `total_count / age('mi', toDateTime(${searchedTimeRange[0].getTime() / 1000}), toDateTime(${searchedTimeRange[1].getTime() / 1000}))`,
|
||||
},
|
||||
{
|
||||
alias: 'P95 (ms)',
|
||||
alias: 'p95_duration_ns',
|
||||
aggFn: 'quantile',
|
||||
valueExpression: expressions.durationInMillis,
|
||||
valueExpression: expressions.duration,
|
||||
aggCondition: '',
|
||||
level: 0.95,
|
||||
},
|
||||
{
|
||||
alias: 'Median (ms)',
|
||||
alias: 'P95 (ms)',
|
||||
valueExpression: `p95_duration_ns / ${expressions.durationDivisorForMillis}`,
|
||||
},
|
||||
{
|
||||
alias: 'p50_duration_ns',
|
||||
aggFn: 'quantile',
|
||||
valueExpression: expressions.durationInMillis,
|
||||
valueExpression: expressions.duration,
|
||||
aggCondition: '',
|
||||
level: 0.5,
|
||||
},
|
||||
{
|
||||
alias: 'Median (ms)',
|
||||
valueExpression: `p50_duration_ns / ${expressions.durationDivisorForMillis}`,
|
||||
},
|
||||
],
|
||||
filters: [
|
||||
...getScopedFilters({
|
||||
|
|
|
|||
|
|
@ -94,17 +94,23 @@ export default function ServiceDashboardDbQuerySidePanel({
|
|||
{source && expressions && (
|
||||
<DBTimeChart
|
||||
sourceId={sourceId}
|
||||
hiddenSeries={['total_duration_ns']}
|
||||
config={{
|
||||
...source,
|
||||
where: '',
|
||||
whereLanguage: 'sql',
|
||||
select: [
|
||||
// Separate the aggregations from the conversion to ms so that AggregatingMergeTree MVs can be used
|
||||
{
|
||||
aggFn: 'sum' as const,
|
||||
valueExpression: expressions.durationInMillis,
|
||||
alias: 'Total Query Time',
|
||||
aggFn: 'sum',
|
||||
valueExpression: expressions.duration,
|
||||
alias: 'total_duration_ns',
|
||||
aggCondition: '',
|
||||
},
|
||||
{
|
||||
valueExpression: `total_duration_ns / ${expressions.durationDivisorForMillis}`,
|
||||
alias: 'Total Query Time',
|
||||
},
|
||||
],
|
||||
numberFormat: MS_NUMBER_FORMAT,
|
||||
filters: dbQueryFilters,
|
||||
|
|
@ -119,7 +125,7 @@ export default function ServiceDashboardDbQuerySidePanel({
|
|||
<Group justify="space-between" align="center" mb="sm">
|
||||
<Text size="sm">Query Throughput</Text>
|
||||
</Group>
|
||||
{source && (
|
||||
{source && expressions && (
|
||||
<DBTimeChart
|
||||
sourceId={sourceId}
|
||||
config={{
|
||||
|
|
|
|||
Loading…
Reference in a new issue