From 0c53c940f812a6a63a2ef2bbc74c2bf7896c43f1 Mon Sep 17 00:00:00 2001 From: Dominik Buszowiecki Date: Thu, 20 Nov 2025 14:25:00 -0500 Subject: [PATCH 1/2] add legend to queries module dashboard --- .../dashboards/utils/prebuiltConfigs.tsx | 4 +- .../utils/prebuiltConfigs/queries.ts | 150 ----------- .../utils/prebuiltConfigs/querySummary.ts | 236 ------------------ 3 files changed, 2 insertions(+), 388 deletions(-) delete mode 100644 static/app/views/dashboards/utils/prebuiltConfigs/queries.ts delete mode 100644 static/app/views/dashboards/utils/prebuiltConfigs/querySummary.ts diff --git a/static/app/views/dashboards/utils/prebuiltConfigs.tsx b/static/app/views/dashboards/utils/prebuiltConfigs.tsx index 50bc05a881f8a3..35deeaa745d7e2 100644 --- a/static/app/views/dashboards/utils/prebuiltConfigs.tsx +++ b/static/app/views/dashboards/utils/prebuiltConfigs.tsx @@ -1,6 +1,6 @@ import {type DashboardDetails} from 'sentry/views/dashboards/types'; -import {QUERIES_PREBUILT_CONFIG} from 'sentry/views/dashboards/utils/prebuiltConfigs/queries'; -import {QUERIES_SUMMARY_PREBUILT_CONFIG} from 'sentry/views/dashboards/utils/prebuiltConfigs/querySummary'; +import {QUERIES_PREBUILT_CONFIG} from 'sentry/views/dashboards/utils/prebuiltConfigs/queries/queries'; +import {QUERIES_SUMMARY_PREBUILT_CONFIG} from 'sentry/views/dashboards/utils/prebuiltConfigs/queries/querySummary'; import {SESSION_HEALTH_PREBUILT_CONFIG} from 'sentry/views/dashboards/utils/prebuiltConfigs/sessionHealth'; export enum PrebuiltDashboardId { diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/queries.ts b/static/app/views/dashboards/utils/prebuiltConfigs/queries.ts deleted file mode 100644 index 4ae5c7bde1f613..00000000000000 --- a/static/app/views/dashboards/utils/prebuiltConfigs/queries.ts +++ /dev/null @@ -1,150 +0,0 @@ -import {t} from 'sentry/locale'; -import {RATE_UNIT_TITLE, RateUnit} from 'sentry/utils/discover/fields'; -import {FieldKind} from 'sentry/utils/fields'; -import {MutableSearch} from 'sentry/utils/tokenizeSearch'; -import {DisplayType, WidgetType} from 'sentry/views/dashboards/types'; -import type {PrebuiltDashboard} from 'sentry/views/dashboards/utils/prebuiltConfigs'; -import {DataTitles} from 'sentry/views/insights/common/views/spans/types'; -import {EXCLUDED_DB_OPS} from 'sentry/views/insights/database/settings'; -import {ModuleName, SpanFields} from 'sentry/views/insights/types'; - -const BASE_FILTERS = { - [SpanFields.SPAN_CATEGORY]: ModuleName.DB, - [`!${SpanFields.SPAN_OP}`]: `[${EXCLUDED_DB_OPS.join(',')}]`, - has: SpanFields.NORMALIZED_DESCRIPTION, -}; - -const FILTER_STRING = MutableSearch.fromQueryObject(BASE_FILTERS).formatString(); - -export const QUERIES_PREBUILT_CONFIG: PrebuiltDashboard = { - dateCreated: '', - projects: [], - title: 'Backend Queries', - filters: { - globalFilter: [ - { - dataset: WidgetType.SPANS, - tag: { - key: 'span.system', - name: 'span.system', - kind: FieldKind.TAG, - }, - value: 'span.system:postgresql', - }, - { - dataset: WidgetType.SPANS, - tag: { - key: 'span.action', - name: 'span.action', - kind: FieldKind.TAG, - }, - value: '', - }, - { - dataset: WidgetType.SPANS, - tag: { - key: 'span.domain', - name: 'span.domain', - kind: FieldKind.TAG, - }, - value: '', - }, - ], - }, - widgets: [ - { - id: 'throughput', - title: t('Queries Per Minute'), - displayType: DisplayType.LINE, - widgetType: WidgetType.SPANS, - interval: '', - queries: [ - { - name: '', - conditions: FILTER_STRING, - fields: ['epm()'], - aggregates: ['epm()'], - columns: [], - orderby: 'epm()', - }, - ], - layout: { - y: 0, - w: 3, - h: 2, - x: 0, - minH: 2, - }, - }, - { - id: 'duration', - title: t('Average Duration'), - displayType: DisplayType.LINE, - widgetType: WidgetType.SPANS, - interval: '', - queries: [ - { - name: '', - conditions: FILTER_STRING, - fields: [`avg(${SpanFields.SPAN_SELF_TIME})`], - aggregates: [`avg(${SpanFields.SPAN_SELF_TIME})`], - columns: [], - orderby: `avg(${SpanFields.SPAN_SELF_TIME})`, - }, - ], - layout: { - y: 0, - w: 3, - h: 2, - x: 3, - minH: 2, - }, - }, - { - id: 'queries-table', - title: t('Queries List'), - displayType: DisplayType.TABLE, - widgetType: WidgetType.SPANS, - interval: '', - queries: [ - { - name: '', - conditions: FILTER_STRING, - fields: [ - SpanFields.NORMALIZED_DESCRIPTION, - 'epm()', - `avg(${SpanFields.SPAN_SELF_TIME})`, - `sum(${SpanFields.SPAN_SELF_TIME})`, - ], - aggregates: [ - 'epm()', - `avg(${SpanFields.SPAN_SELF_TIME})`, - `sum(${SpanFields.SPAN_SELF_TIME})`, - ], - columns: [SpanFields.NORMALIZED_DESCRIPTION], - orderby: `sum(${SpanFields.SPAN_SELF_TIME})`, - fieldAliases: [ - t('Query Description'), - `${t('Queries')} ${RATE_UNIT_TITLE[RateUnit.PER_MINUTE]}`, - DataTitles.avg, - DataTitles.timeSpent, - ], - linkedDashboards: [ - { - dashboardId: '-1', - field: SpanFields.NORMALIZED_DESCRIPTION, - staticDashboardId: 3, - }, - ], - }, - ], - layout: { - y: 2, - w: 6, - h: 6, - x: 0, - minH: 2, - }, - }, - ], -}; diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/querySummary.ts b/static/app/views/dashboards/utils/prebuiltConfigs/querySummary.ts deleted file mode 100644 index 084f97bd76061f..00000000000000 --- a/static/app/views/dashboards/utils/prebuiltConfigs/querySummary.ts +++ /dev/null @@ -1,236 +0,0 @@ -import {t} from 'sentry/locale'; -import {FieldKind} from 'sentry/utils/fields'; -import {DisplayType, WidgetType} from 'sentry/views/dashboards/types'; -import type {PrebuiltDashboard} from 'sentry/views/dashboards/utils/prebuiltConfigs'; -import {SpanFields} from 'sentry/views/insights/types'; - -export const QUERIES_SUMMARY_PREBUILT_CONFIG: PrebuiltDashboard = { - dateCreated: '', - projects: [], - title: 'Backend Queries', - filters: { - globalFilter: [ - { - dataset: WidgetType.SPANS, - tag: { - key: SpanFields.NORMALIZED_DESCRIPTION, - name: SpanFields.NORMALIZED_DESCRIPTION, - kind: FieldKind.TAG, - }, - value: '', - }, - { - dataset: WidgetType.ISSUE, - tag: { - key: 'message', - name: 'message', - kind: FieldKind.EVENT_FIELD, - }, - value: '', - }, - ], - }, - widgets: [ - { - id: 'metrics-throughput', - title: t('Queries Per Minute'), - description: '', - displayType: DisplayType.BIG_NUMBER, - thresholds: null, - interval: '1h', - queries: [ - { - name: '', - fields: ['epm()'], - aggregates: ['epm()'], - columns: [], - conditions: '', - orderby: '', - isHidden: false, - }, - ], - widgetType: WidgetType.SPANS, - layout: { - x: 3, - minH: 1, - w: 1, - h: 1, - y: 0, - }, - }, - { - id: 'metrics-duration', - title: 'Avg Duration', - description: '', - displayType: DisplayType.BIG_NUMBER, - thresholds: null, - interval: '1h', - queries: [ - { - name: '', - fields: [`avg(${SpanFields.SPAN_SELF_TIME})`], - aggregates: [`avg(${SpanFields.SPAN_SELF_TIME})`], - columns: [], - conditions: '', - orderby: '', - isHidden: false, - }, - ], - widgetType: WidgetType.SPANS, - layout: { - x: 4, - minH: 1, - w: 1, - h: 1, - y: 0, - }, - }, - { - id: 'metrics-time-spent', - title: 'Time Spent', - description: '', - displayType: DisplayType.BIG_NUMBER, - thresholds: null, - interval: '1h', - queries: [ - { - name: '', - fields: [`sum(${SpanFields.SPAN_SELF_TIME})`], - aggregates: [`sum(${SpanFields.SPAN_SELF_TIME})`], - columns: [], - conditions: '', - orderby: '', - isHidden: false, - }, - ], - widgetType: WidgetType.SPANS, - layout: { - x: 5, - minH: 1, - w: 1, - h: 1, - y: 0, - }, - }, - { - id: 'related-issues', - title: 'Related Issues', - description: '', - displayType: DisplayType.TABLE, - thresholds: null, - interval: '1h', - queries: [ - { - name: '', - fields: ['issue', 'assignee', 'title'], - aggregates: [], - columns: ['issue', 'assignee', 'title'], - fieldAliases: ['', '', ''], - conditions: - 'issue.type:[performance_slow_db_query,performance_n_plus_one_db_queries]', - orderby: 'date', - onDemand: [], - isHidden: false, - linkedDashboards: [], - }, - ], - widgetType: WidgetType.ISSUE, - layout: { - x: 0, - minH: 2, - w: 6, - h: 2, - y: 1, - }, - }, - { - id: 'transactions-with-query', - title: 'Transactions with query', - description: '', - displayType: DisplayType.TABLE, - thresholds: null, - interval: '1h', - queries: [ - { - name: '', - fields: ['transaction', 'epm()', `sum(${SpanFields.SPAN_SELF_TIME})`], - aggregates: ['epm()', `sum(${SpanFields.SPAN_SELF_TIME})`], - columns: [SpanFields.TRANSACTION], - fieldAliases: [t('Found In'), t('Queries Per Minute'), t('Time Spent')], - conditions: '', - orderby: `-${SpanFields.TRANSACTION}`, - onDemand: [], - isHidden: false, - linkedDashboards: [], - }, - ], - widgetType: WidgetType.SPANS, - layout: { - x: 0, - minH: 2, - w: 6, - h: 2, - y: 5, - }, - }, - { - id: 'metrics-throughput-line', - title: 'Queries Per Minute', - description: '', - displayType: DisplayType.LINE, - thresholds: null, - interval: '1h', - queries: [ - { - name: '', - fields: ['epm()'], - aggregates: ['epm()'], - columns: [], - fieldAliases: [], - conditions: '', - orderby: 'epm()', - onDemand: [], - isHidden: false, - linkedDashboards: [], - }, - ], - widgetType: WidgetType.SPANS, - layout: { - x: 0, - minH: 2, - w: 3, - h: 2, - y: 3, - }, - }, - { - id: 'metrics-duration-line', - title: 'Average Duration', - description: '', - displayType: DisplayType.LINE, - widgetType: WidgetType.SPANS, - thresholds: null, - interval: '1h', - queries: [ - { - name: '', - fields: [`avg(${SpanFields.SPAN_SELF_TIME})`], - aggregates: [`avg(${SpanFields.SPAN_SELF_TIME})`], - columns: [], - fieldAliases: [], - conditions: '', - orderby: `avg(${SpanFields.SPAN_SELF_TIME})`, - onDemand: [], - isHidden: false, - }, - ], - layout: { - x: 3, - minH: 2, - w: 3, - h: 2, - y: 3, - }, - }, - ], -}; From 17593e1ae14e6e7ead3b20cefe9048e46e15af47 Mon Sep 17 00:00:00 2001 From: Dominik Buszowiecki Date: Thu, 20 Nov 2025 14:27:26 -0500 Subject: [PATCH 2/2] add legend to queries module dashboard --- .../prebuiltConfigs/queries/constants.ts | 4 + .../utils/prebuiltConfigs/queries/queries.ts | 154 +++++++++++ .../prebuiltConfigs/queries/querySummary.ts | 240 ++++++++++++++++++ 3 files changed, 398 insertions(+) create mode 100644 static/app/views/dashboards/utils/prebuiltConfigs/queries/constants.ts create mode 100644 static/app/views/dashboards/utils/prebuiltConfigs/queries/queries.ts create mode 100644 static/app/views/dashboards/utils/prebuiltConfigs/queries/querySummary.ts diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/queries/constants.ts b/static/app/views/dashboards/utils/prebuiltConfigs/queries/constants.ts new file mode 100644 index 00000000000000..9c00f2654a2570 --- /dev/null +++ b/static/app/views/dashboards/utils/prebuiltConfigs/queries/constants.ts @@ -0,0 +1,4 @@ +import {t} from 'sentry/locale'; + +export const QUERIES_PER_MINUTE_TEXT = t('Queries Per Minute'); +export const AVERAGE_DURATION_TEXT = t('Average Duration'); diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/queries/queries.ts b/static/app/views/dashboards/utils/prebuiltConfigs/queries/queries.ts new file mode 100644 index 00000000000000..806cdaa175b6aa --- /dev/null +++ b/static/app/views/dashboards/utils/prebuiltConfigs/queries/queries.ts @@ -0,0 +1,154 @@ +import {t} from 'sentry/locale'; +import {RATE_UNIT_TITLE, RateUnit} from 'sentry/utils/discover/fields'; +import {FieldKind} from 'sentry/utils/fields'; +import {MutableSearch} from 'sentry/utils/tokenizeSearch'; +import {DisplayType, WidgetType} from 'sentry/views/dashboards/types'; +import type {PrebuiltDashboard} from 'sentry/views/dashboards/utils/prebuiltConfigs'; +import { + AVERAGE_DURATION_TEXT, + QUERIES_PER_MINUTE_TEXT, +} from 'sentry/views/dashboards/utils/prebuiltConfigs/queries/constants'; +import {DataTitles} from 'sentry/views/insights/common/views/spans/types'; +import {EXCLUDED_DB_OPS} from 'sentry/views/insights/database/settings'; +import {ModuleName, SpanFields} from 'sentry/views/insights/types'; + +const BASE_FILTERS = { + [SpanFields.SPAN_CATEGORY]: ModuleName.DB, + [`!${SpanFields.SPAN_OP}`]: `[${EXCLUDED_DB_OPS.join(',')}]`, + has: SpanFields.NORMALIZED_DESCRIPTION, +}; + +const FILTER_STRING = MutableSearch.fromQueryObject(BASE_FILTERS).formatString(); + +export const QUERIES_PREBUILT_CONFIG: PrebuiltDashboard = { + dateCreated: '', + projects: [], + title: 'Backend Queries', + filters: { + globalFilter: [ + { + dataset: WidgetType.SPANS, + tag: { + key: 'span.system', + name: 'span.system', + kind: FieldKind.TAG, + }, + value: 'span.system:postgresql', + }, + { + dataset: WidgetType.SPANS, + tag: { + key: 'span.action', + name: 'span.action', + kind: FieldKind.TAG, + }, + value: '', + }, + { + dataset: WidgetType.SPANS, + tag: { + key: 'span.domain', + name: 'span.domain', + kind: FieldKind.TAG, + }, + value: '', + }, + ], + }, + widgets: [ + { + id: 'throughput', + title: t('Queries Per Minute'), + displayType: DisplayType.LINE, + widgetType: WidgetType.SPANS, + interval: '', + queries: [ + { + name: QUERIES_PER_MINUTE_TEXT, + conditions: FILTER_STRING, + fields: ['epm()'], + aggregates: ['epm()'], + columns: [], + orderby: 'epm()', + }, + ], + layout: { + y: 0, + w: 3, + h: 2, + x: 0, + minH: 2, + }, + }, + { + id: 'duration', + title: t('Average Duration'), + displayType: DisplayType.LINE, + widgetType: WidgetType.SPANS, + interval: '', + queries: [ + { + name: AVERAGE_DURATION_TEXT, + conditions: FILTER_STRING, + fields: [`avg(${SpanFields.SPAN_SELF_TIME})`], + aggregates: [`avg(${SpanFields.SPAN_SELF_TIME})`], + columns: [], + orderby: `avg(${SpanFields.SPAN_SELF_TIME})`, + }, + ], + layout: { + y: 0, + w: 3, + h: 2, + x: 3, + minH: 2, + }, + }, + { + id: 'queries-table', + title: t('Queries List'), + displayType: DisplayType.TABLE, + widgetType: WidgetType.SPANS, + interval: '', + queries: [ + { + name: '', + conditions: FILTER_STRING, + fields: [ + SpanFields.NORMALIZED_DESCRIPTION, + 'epm()', + `avg(${SpanFields.SPAN_SELF_TIME})`, + `sum(${SpanFields.SPAN_SELF_TIME})`, + ], + aggregates: [ + 'epm()', + `avg(${SpanFields.SPAN_SELF_TIME})`, + `sum(${SpanFields.SPAN_SELF_TIME})`, + ], + columns: [SpanFields.NORMALIZED_DESCRIPTION], + orderby: `sum(${SpanFields.SPAN_SELF_TIME})`, + fieldAliases: [ + t('Query Description'), + `${t('Queries')} ${RATE_UNIT_TITLE[RateUnit.PER_MINUTE]}`, + DataTitles.avg, + DataTitles.timeSpent, + ], + linkedDashboards: [ + { + dashboardId: '-1', + field: SpanFields.NORMALIZED_DESCRIPTION, + staticDashboardId: 3, + }, + ], + }, + ], + layout: { + y: 2, + w: 6, + h: 6, + x: 0, + minH: 2, + }, + }, + ], +}; diff --git a/static/app/views/dashboards/utils/prebuiltConfigs/queries/querySummary.ts b/static/app/views/dashboards/utils/prebuiltConfigs/queries/querySummary.ts new file mode 100644 index 00000000000000..109921dc0b48ba --- /dev/null +++ b/static/app/views/dashboards/utils/prebuiltConfigs/queries/querySummary.ts @@ -0,0 +1,240 @@ +import {t} from 'sentry/locale'; +import {FieldKind} from 'sentry/utils/fields'; +import {DisplayType, WidgetType} from 'sentry/views/dashboards/types'; +import type {PrebuiltDashboard} from 'sentry/views/dashboards/utils/prebuiltConfigs'; +import { + AVERAGE_DURATION_TEXT, + QUERIES_PER_MINUTE_TEXT, +} from 'sentry/views/dashboards/utils/prebuiltConfigs/queries/constants'; +import {SpanFields} from 'sentry/views/insights/types'; + +export const QUERIES_SUMMARY_PREBUILT_CONFIG: PrebuiltDashboard = { + dateCreated: '', + projects: [], + title: 'Backend Queries', + filters: { + globalFilter: [ + { + dataset: WidgetType.SPANS, + tag: { + key: SpanFields.NORMALIZED_DESCRIPTION, + name: SpanFields.NORMALIZED_DESCRIPTION, + kind: FieldKind.TAG, + }, + value: '', + }, + { + dataset: WidgetType.ISSUE, + tag: { + key: 'message', + name: 'message', + kind: FieldKind.EVENT_FIELD, + }, + value: '', + }, + ], + }, + widgets: [ + { + id: 'metrics-throughput', + title: QUERIES_PER_MINUTE_TEXT, + description: '', + displayType: DisplayType.BIG_NUMBER, + thresholds: null, + interval: '1h', + queries: [ + { + name: QUERIES_PER_MINUTE_TEXT, + fields: ['epm()'], + aggregates: ['epm()'], + columns: [], + conditions: '', + orderby: '', + isHidden: false, + }, + ], + widgetType: WidgetType.SPANS, + layout: { + x: 3, + minH: 1, + w: 1, + h: 1, + y: 0, + }, + }, + { + id: 'metrics-duration', + title: AVERAGE_DURATION_TEXT, + description: '', + displayType: DisplayType.BIG_NUMBER, + thresholds: null, + interval: '1h', + queries: [ + { + name: AVERAGE_DURATION_TEXT, + fields: [`avg(${SpanFields.SPAN_SELF_TIME})`], + aggregates: [`avg(${SpanFields.SPAN_SELF_TIME})`], + columns: [], + conditions: '', + orderby: '', + isHidden: false, + }, + ], + widgetType: WidgetType.SPANS, + layout: { + x: 4, + minH: 1, + w: 1, + h: 1, + y: 0, + }, + }, + { + id: 'metrics-time-spent', + title: 'Time Spent', + description: '', + displayType: DisplayType.BIG_NUMBER, + thresholds: null, + interval: '1h', + queries: [ + { + name: '', + fields: [`sum(${SpanFields.SPAN_SELF_TIME})`], + aggregates: [`sum(${SpanFields.SPAN_SELF_TIME})`], + columns: [], + conditions: '', + orderby: '', + isHidden: false, + }, + ], + widgetType: WidgetType.SPANS, + layout: { + x: 5, + minH: 1, + w: 1, + h: 1, + y: 0, + }, + }, + { + id: 'related-issues', + title: 'Related Issues', + description: '', + displayType: DisplayType.TABLE, + thresholds: null, + interval: '1h', + queries: [ + { + name: '', + fields: ['issue', 'assignee', 'title'], + aggregates: [], + columns: ['issue', 'assignee', 'title'], + fieldAliases: ['', '', ''], + conditions: + 'issue.type:[performance_slow_db_query,performance_n_plus_one_db_queries]', + orderby: 'date', + onDemand: [], + isHidden: false, + linkedDashboards: [], + }, + ], + widgetType: WidgetType.ISSUE, + layout: { + x: 0, + minH: 2, + w: 6, + h: 2, + y: 1, + }, + }, + { + id: 'transactions-with-query', + title: 'Transactions with query', + description: '', + displayType: DisplayType.TABLE, + thresholds: null, + interval: '1h', + queries: [ + { + name: '', + fields: ['transaction', 'epm()', `sum(${SpanFields.SPAN_SELF_TIME})`], + aggregates: ['epm()', `sum(${SpanFields.SPAN_SELF_TIME})`], + columns: [SpanFields.TRANSACTION], + fieldAliases: [t('Found In'), t('Queries Per Minute'), t('Time Spent')], + conditions: '', + orderby: `-${SpanFields.TRANSACTION}`, + onDemand: [], + isHidden: false, + linkedDashboards: [], + }, + ], + widgetType: WidgetType.SPANS, + layout: { + x: 0, + minH: 2, + w: 6, + h: 2, + y: 5, + }, + }, + { + id: 'metrics-throughput-line', + title: 'Queries Per Minute', + description: '', + displayType: DisplayType.LINE, + thresholds: null, + interval: '1h', + queries: [ + { + name: '', + fields: ['epm()'], + aggregates: ['epm()'], + columns: [], + fieldAliases: [], + conditions: '', + orderby: 'epm()', + onDemand: [], + isHidden: false, + linkedDashboards: [], + }, + ], + widgetType: WidgetType.SPANS, + layout: { + x: 0, + minH: 2, + w: 3, + h: 2, + y: 3, + }, + }, + { + id: 'metrics-duration-line', + title: 'Average Duration', + description: '', + displayType: DisplayType.LINE, + widgetType: WidgetType.SPANS, + thresholds: null, + interval: '1h', + queries: [ + { + name: '', + fields: [`avg(${SpanFields.SPAN_SELF_TIME})`], + aggregates: [`avg(${SpanFields.SPAN_SELF_TIME})`], + columns: [], + fieldAliases: [], + conditions: '', + orderby: `avg(${SpanFields.SPAN_SELF_TIME})`, + onDemand: [], + isHidden: false, + }, + ], + layout: { + x: 3, + minH: 2, + w: 3, + h: 2, + y: 3, + }, + }, + ], +};