From ce4bb1ce50e191c56a82aa855e24c248dca18b48 Mon Sep 17 00:00:00 2001 From: adinhodovic Date: Fri, 1 Dec 2023 18:42:21 +0100 Subject: [PATCH] feat: Add final django request overview migration --- .lint | 2 +- dashboards/django-overview.libsonnet | 1 - dashboards/django-requests-overview.libsonnet | 1231 +++++++++------ dashboards_out/.lint | 2 +- dashboards_out/django-overview.json | 994 ++++++------ dashboards_out/django-requests-by-view.json | 874 +++++------ dashboards_out/django-requests-overview.json | 1337 +++++++++-------- jsonnetfile.json | 23 +- 8 files changed, 2223 insertions(+), 2241 deletions(-) diff --git a/.lint b/.lint index 89e3c05..dfc108c 100644 --- a/.lint +++ b/.lint @@ -1,5 +1,5 @@ exclusions: template-job-rule: panel-job-instance-rule: - rate-interval-rule: target-rate-interval-rule: + panel-datasource-rule: diff --git a/dashboards/django-overview.libsonnet b/dashboards/django-overview.libsonnet index ea4fe95..c34b488 100644 --- a/dashboards/django-overview.libsonnet +++ b/dashboards/django-overview.libsonnet @@ -29,7 +29,6 @@ local tsOverride = tsStandardOptions.override; // Table local tbOptions = tablePanel.options; -local tbStandardOptions = tablePanel.standardOptions; local tbQueryOptions = tablePanel.queryOptions; { diff --git a/dashboards/django-requests-overview.libsonnet b/dashboards/django-requests-overview.libsonnet index 2e1a110..61f18ce 100644 --- a/dashboards/django-requests-overview.libsonnet +++ b/dashboards/django-requests-overview.libsonnet @@ -1,136 +1,192 @@ -local grafana = import 'github.com/grafana/grafonnet-lib/grafonnet/grafana.libsonnet'; -local dashboard = grafana.dashboard; -local row = grafana.row; -local prometheus = grafana.prometheus; -local template = grafana.template; -local graphPanel = grafana.graphPanel; -local statPanel = grafana.statPanel; - -local paginateTable = { - pageSize: 6, -}; +local g = import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet'; + +local dashboard = g.dashboard; +local row = g.panel.row; +local grid = g.util.grid; + +local variable = dashboard.variable; +local datasource = variable.datasource; +local query = variable.query; +local prometheus = g.query.prometheus; + +local statPanel = g.panel.stat; +local timeSeriesPanel = g.panel.timeSeries; +local tablePanel = g.panel.table; + +// Stat +local stOptions = statPanel.options; +local stStandardOptions = statPanel.standardOptions; +local stQueryOptions = statPanel.queryOptions; + +// Timeseries +local tsOptions = timeSeriesPanel.options; +local tsStandardOptions = timeSeriesPanel.standardOptions; +local tsQueryOptions = timeSeriesPanel.queryOptions; +local tsFieldConfig = timeSeriesPanel.fieldConfig; +local tsCustom = tsFieldConfig.defaults.custom; +local tsLegend = tsOptions.legend; +local tsOverride = tsStandardOptions.override; + +// Table +local tbOptions = tablePanel.options; +local tbStandardOptions = tablePanel.standardOptions; +local tbQueryOptions = tablePanel.queryOptions; +local tbPanelOptions = tablePanel.panelOptions; +local tbOverride = tbStandardOptions.override; { grafanaDashboards+:: { - local prometheusTemplate = - template.datasource( + local datasourceVariable = + datasource.new( 'datasource', 'prometheus', - 'Prometheus', - label='Data Source', - hide='', - ), + ) + + datasource.generalOptions.withLabel('Data Source'), - local namespaceTemplate = - template.new( - name='namespace', - label='Namespace', - datasource='$datasource', - query='label_values(django_http_responses_total_by_status_view_method_total{}, namespace)', - current='', - hide='', - refresh=2, // On Time Range Change - multi=false, - includeAll=false, - sort=1 - ), + local namespaceVariable = + query.new( + 'namespace', + 'label_values(django_http_responses_total_by_status_view_method_total{}, namespace)' + ) + + query.withDatasourceFromVariable(datasourceVariable) + + query.withSort(1) + + query.generalOptions.withLabel('Namespace') + + query.selectionOptions.withMulti(false) + + query.selectionOptions.withIncludeAll(false) + + query.refresh.onLoad() + + query.refresh.onTime(), - local jobTemplate = - template.new( - name='job', - label='Job', - datasource='$datasource', - query='label_values(django_http_responses_total_by_status_view_method_total{namespace=~"$namespace"}, job)', - hide='', - refresh=2, // On Time Range Change - multi=false, - includeAll=false, - sort=1 - ), + + local jobVariable = + query.new( + 'job', + 'label_values(django_http_responses_total_by_status_view_method_total{namespace=~"$namespace"}, job)' + ) + + query.withDatasourceFromVariable(datasourceVariable) + + query.withSort(1) + + query.generalOptions.withLabel('Job') + + query.selectionOptions.withMulti(false) + + query.selectionOptions.withIncludeAll(false) + + query.refresh.onLoad() + + query.refresh.onTime(), local defaultFilters = 'namespace=~"$namespace", job=~"$job"', - local viewTemplate = - template.new( - name='view', - label='View', - datasource='$datasource', - query='label_values(django_http_responses_total_by_status_view_method_total{%s, view!~"%s"}, view)' % [defaultFilters, $._config.djangoIgnoredViews], - hide='', - refresh=2, // On Time Range Change - multi=true, - includeAll=true, - sort=1 - ), + local viewVariable = + query.new( + 'view', + 'label_values(django_http_responses_total_by_status_view_method_total{%s, view!~"%s"}, view)' % [defaultFilters, $._config.djangoIgnoredViews], + ) + + query.withDatasourceFromVariable(datasourceVariable) + + query.withSort(1) + + query.generalOptions.withLabel('View') + + query.selectionOptions.withMulti(true) + + query.selectionOptions.withIncludeAll(true) + + query.refresh.onLoad() + + query.refresh.onTime(), - local methodTemplate = - template.new( - name='method', - label='Method', - datasource='$datasource', - query='label_values(django_http_responses_total_by_status_view_method_total{%s, view=~"$view"}, method)' % defaultFilters, - hide='', - refresh=2, // On Time Range Change - multi=true, - includeAll=true, - sort=1 - ), + local methodVariable = + query.new( + 'method', + 'label_values(django_http_responses_total_by_status_view_method_total{%s, view=~"$view"}, method)' % defaultFilters, + ) + + query.withDatasourceFromVariable(datasourceVariable) + + query.withSort(1) + + query.generalOptions.withLabel('Method') + + query.selectionOptions.withMulti(true) + + query.selectionOptions.withIncludeAll(true) + + query.refresh.onLoad() + + query.refresh.onTime(), - local templates = [ - prometheusTemplate, - namespaceTemplate, - jobTemplate, - viewTemplate, - methodTemplate, + local variables = [ + datasourceVariable, + namespaceVariable, + jobVariable, + viewVariable, + methodVariable, ], local requestVolumeQuery = ||| round( sum( rate( - django_http_requests_total_by_view_transport_method_total{namespace=~"$namespace", job=~"$job", view=~"$view", view!~"%(djangoIgnoredViews)s", method=~"$method"}[2m] + django_http_requests_total_by_view_transport_method_total{ + namespace=~"$namespace", + job=~"$job", + view=~"$view", + view!~"%(djangoIgnoredViews)s", + method=~"$method" + }[2m] ) ), 0.001 ) ||| % $._config, + local requestVolumeStatPanel = statPanel.new( 'Request Volume', - datasource='$datasource', - unit='reqps', - reducerFunction='lastNotNull', - ) - .addTarget(prometheus.target(requestVolumeQuery)) - .addThresholds([ - { color: 'red', value: 0 }, - { color: 'green', value: 0.001 }, + ) + + stQueryOptions.withTargets( + prometheus.new( + '$datasource', + requestVolumeQuery, + ) + ) + + stStandardOptions.withUnit('reqps') + + stOptions.reduceOptions.withCalcs(['lastNotNull']) + + stStandardOptions.thresholds.withSteps([ + stStandardOptions.threshold.step.withValue(0.0) + + stStandardOptions.threshold.step.withColor('red'), + stStandardOptions.threshold.step.withValue(0.001) + + stStandardOptions.threshold.step.withColor('green'), ]), local requestSuccessRateQuery = ||| sum( rate( - django_http_responses_total_by_status_view_method_total{namespace=~"$namespace", job=~"$job", view=~"$view", view!~"%(djangoIgnoredViews)s", method=~"$method", status!~"[4-5].*"}[$__rate_interval] - ) + django_http_responses_total_by_status_view_method_total{ + namespace=~"$namespace", + job=~"$job", + view=~"$view", + view!~"%(djangoIgnoredViews)s", + method=~"$method", + status!~"[4-5].*" + }[$__rate_interval] + ) ) / sum( rate( - django_http_responses_total_by_status_view_method_total{namespace=~"$namespace", job=~"$job", view=~"$view", view!~"%(djangoIgnoredViews)s", method=~"$method"}[$__rate_interval] + django_http_responses_total_by_status_view_method_total{ + namespace=~"$namespace", + job=~"$job", + view=~"$view", + view!~"%(djangoIgnoredViews)s", + method=~"$method" + }[$__rate_interval] ) ) ||| % $._config, + local requestSuccessRateStatPanel = statPanel.new( 'Success Rate (non 4-5xx responses)', - datasource='$datasource', - unit='percentunit', - reducerFunction='lastNotNull', - ) - .addTarget(prometheus.target(requestSuccessRateQuery)) - .addThresholds([ - { color: 'red', value: 0.90 }, - { color: 'yellow', value: 0.95 }, - { color: 'green', value: 0.99 }, + ) + + stQueryOptions.withTargets( + prometheus.new( + '$datasource', + requestSuccessRateQuery, + ) + ) + + stStandardOptions.withUnit('percentunit') + + stOptions.reduceOptions.withCalcs(['lastNotNull']) + + stStandardOptions.thresholds.withSteps([ + stStandardOptions.threshold.step.withValue(0.90) + + stStandardOptions.threshold.step.withColor('red'), + stStandardOptions.threshold.step.withValue(0.95) + + stStandardOptions.threshold.step.withColor('yellow'), + stStandardOptions.threshold.step.withValue(0.99) + + stStandardOptions.threshold.step.withColor('green'), ]), local requestBytesP95Query = ||| @@ -145,47 +201,142 @@ local paginateTable = { ) by (job, le) ) ||| % $._config, + local requestBytesStatPanel = statPanel.new( 'Request Body Size (P95)', - datasource='$datasource', - unit='decbytes', - reducerFunction='lastNotNull', - ) - .addTarget(prometheus.target(requestBytesP95Query)) - .addThresholds([ - { color: 'red', value: 0.1 }, - { color: 'yellow', value: 0.2 }, - { color: 'green', value: 0.3 }, + ) + + stQueryOptions.withTargets( + prometheus.new( + '$datasource', + requestBytesP95Query, + ) + ) + + stStandardOptions.withUnit('decbytes') + + stOptions.reduceOptions.withCalcs(['lastNotNull']) + + stStandardOptions.thresholds.withSteps([ + stStandardOptions.threshold.step.withValue(0.1) + + stStandardOptions.threshold.step.withColor('red'), + stStandardOptions.threshold.step.withValue(0.2) + + stStandardOptions.threshold.step.withColor('yellow'), + stStandardOptions.threshold.step.withValue(0.3) + + stStandardOptions.threshold.step.withColor('green'), ]), local requestLatencyP95SummaryQuery = ||| histogram_quantile(0.95, sum ( irate( - django_http_requests_latency_seconds_by_view_method_bucket { - namespace=~"$namespace", - job=~"$job", - view!~"%(djangoIgnoredViews)s", - }[$__rate_interval] + django_http_requests_latency_seconds_by_view_method_bucket{ + namespace=~"$namespace", + job=~"$job", + view!~"%(djangoIgnoredViews)s", + }[$__rate_interval] ) ) by (job, le) ) ||| % $._config, + local requestLatencyP95SummaryStatPanel = statPanel.new( 'Request Latency (P95)', - datasource='$datasource', - unit='s', - reducerFunction='lastNotNull', - ) - .addTarget(prometheus.target(requestLatencyP95SummaryQuery)) - .addThresholds([ - { color: 'green', value: 0 }, - { color: 'yellow', value: 2500 }, - { color: 'red', value: 5000 }, + ) + + stQueryOptions.withTargets( + prometheus.new( + '$datasource', + requestLatencyP95SummaryQuery, + ) + ) + + stStandardOptions.withUnit('s') + + stOptions.reduceOptions.withCalcs(['lastNotNull']) + + stStandardOptions.thresholds.withSteps([ + stStandardOptions.threshold.step.withValue(0) + + stStandardOptions.threshold.step.withColor('green'), + stStandardOptions.threshold.step.withValue(2500) + + stStandardOptions.threshold.step.withColor('yellow'), + stStandardOptions.threshold.step.withValue(5000) + + stStandardOptions.threshold.step.withColor('red'), ]), + local apiResponse2xxQuery = ||| + round( + sum( + rate( + django_http_responses_total_by_status_view_method_total{ + namespace=~"$namespace", + job=~"$job", + view=~"$view", + view!~"%(djangoIgnoredViews)s", + method=~"$method", + status=~"2.*", + view!~"%(adminViewRegex)s", + }[$__rate_interval] + ) > 0 + ) by (namespace, job, view), 0.001 + ) + ||| % $._config, + local apiResponse4xxQuery = std.strReplace(apiResponse2xxQuery, '2.*', '4.*'), + local apiResponse5xxQuery = std.strReplace(apiResponse2xxQuery, '2.*', '5.*'), + + local apiResponseTimeSeriesPanel = + timeSeriesPanel.new( + 'API & Other Views Response Status', + ) + + tsQueryOptions.withTargets( + [ + prometheus.new( + '$datasource', + apiResponse2xxQuery, + ) + + prometheus.withLegendFormat( + '{{ view }} / 2xx' + ), + prometheus.new( + '$datasource', + apiResponse4xxQuery, + ) + + prometheus.withLegendFormat( + '{{ view }} / 4xx' + ), + prometheus.new( + '$datasource', + apiResponse5xxQuery, + ) + + prometheus.withLegendFormat( + '{{ view }} / 5xx' + ), + ] + ) + + tsStandardOptions.withUnit('reqps') + + tsOptions.tooltip.withMode('multi') + + tsOptions.tooltip.withSort('desc') + + tsStandardOptions.withOverrides([ + tsOverride.byName.new('2xx') + + tsOverride.byName.withPropertiesFromOptions( + tsStandardOptions.color.withMode('fixed') + + tsStandardOptions.color.withFixedColor('green') + ), + tsOverride.byName.new('4xx') + + tsOverride.byName.withPropertiesFromOptions( + tsStandardOptions.color.withMode('fixed') + + tsStandardOptions.color.withFixedColor('yellow') + ), + tsOverride.byName.new('5xx') + + tsOverride.byName.withPropertiesFromOptions( + tsStandardOptions.color.withMode('fixed') + + tsStandardOptions.color.withFixedColor('red') + ), + ]) + + tsLegend.withShowLegend(true) + + tsLegend.withDisplayMode('table') + + tsLegend.withPlacement('right') + + tsLegend.withCalcs(['mean', 'max']) + + tsLegend.withSortBy('Mean') + + tsLegend.withSortDesc(true) + + tsCustom.stacking.withMode('value') + + tsCustom.withFillOpacity(100) + + tsCustom.withSpanNulls(false), + local apiRequestLatencyP50Query = ||| histogram_quantile(0.50, sum( @@ -199,351 +350,365 @@ local paginateTable = { method=~"$method" }[$__rate_interval] ) > 0 - ) by (view, job, le) + ) by (namespace, job, view, le) ) ||| % $._config, local apiRequestLatencyP95Query = std.strReplace(apiRequestLatencyP50Query, '0.50', '0.95'), local apiRequestLatencyP99Query = std.strReplace(apiRequestLatencyP50Query, '0.50', '0.99'), local apiRequestLatencyTable = - grafana.tablePanel.new( + tablePanel.new( 'API & Other Views Request Latency', - datasource='$datasource', - sort={ - col: 3, - desc: true, - }, - styles=[ - { - alias: 'Time', - dateFormat: 'YYYY-MM-DD HH:mm:ss', - type: 'hidden', - pattern: 'Time', - }, - { - alias: 'View', - pattern: 'view', - link: true, - linkTargetBlank: true, - linkTooltip: 'Go To View', - linkUrl: $._config.requestsByViewDashboardUrl + '?var-job=$job&var-namespace=$namespace&var-view=${__cell}', - }, - { - alias: 'Namespace', - pattern: 'namespace', - }, - { - alias: 'Job', - pattern: 'job', - }, - { - alias: 'P50 Latency', - pattern: 'Value #A', - type: 'number', - unit: 'dtdurations', - }, - { - alias: 'P90 Latency', - pattern: 'Value #B', - type: 'number', - unit: 'dtdurations', - }, + ) + + tbOptions.withSortBy( + tbOptions.sortBy.withDisplayName('P50 Latency') + + tbOptions.sortBy.withDesc(true) + ) + + tbOptions.footer.TableFooterOptions.withEnablePagination(true) + + tbStandardOptions.withUnit('dtdurations') + + tbQueryOptions.withTargets( + [ + prometheus.new( + '$datasource', + apiRequestLatencyP50Query, + ) + + prometheus.withFormat('table') + + prometheus.withInstant(true), + prometheus.new( + '$datasource', + apiRequestLatencyP95Query, + ) + + prometheus.withFormat('table') + + prometheus.withInstant(true), + prometheus.new( + '$datasource', + apiRequestLatencyP99Query, + ) + + prometheus.withFormat('table') + + prometheus.withInstant(true), + ] + ) + + tbQueryOptions.withTransformations([ + tbQueryOptions.transformation.withId( + 'merge' + ), + tbQueryOptions.transformation.withId( + 'organize' + ) + + tbQueryOptions.transformation.withOptions( { - alias: 'P99 Latency', - pattern: 'Value #C', - type: 'number', - unit: 'dtdurations', - }, + renameByName: { + job: 'Job', + namespace: 'Namespace', + view: 'View', + 'Value #A': 'P50 Latency', + 'Value #B': 'P95 Latency', + 'Value #C': 'P99 Latency', + }, + indexByName: { + namespace: 0, + job: 1, + view: 2, + 'Value #A': 3, + 'Value #B': 4, + 'Value #C': 5, + }, + excludeByName: { + Time: true, + }, + } + ), + ]) + + tbStandardOptions.withOverrides([ + tbOverride.byName.new('View') + + tbOverride.byName.withPropertiesFromOptions( + tbStandardOptions.withLinks( + tbPanelOptions.link.withTitle('Go To View') + + tbPanelOptions.link.withType('dashboard') + + tbPanelOptions.link.withUrl( + '/d/%s/django-requests-by-view?var-namespace=${__data.fields.Namespace}&var-job=${__data.fields.Job}&var-view=${__data.fields.View}' % $._config.requestsByViewDashboardUid + ) + + tbPanelOptions.link.withTargetBlank(true) + ) + ), + ]), + + local adminResponse2xxQuery = std.strReplace(apiResponse2xxQuery, 'view!~"%s"' % $._config.adminViewRegex, 'view=~"%s"' % $._config.adminViewRegex), + local adminResponse4xxQuery = std.strReplace(apiResponse4xxQuery, 'view!~"%s"' % $._config.adminViewRegex, 'view=~"%s"' % $._config.adminViewRegex), + local adminResponse5xxQuery = std.strReplace(apiResponse5xxQuery, 'view!~"%s"' % $._config.adminViewRegex, 'view=~"%s"' % $._config.adminViewRegex), + + local adminResponseTimeSeriesPanel = + timeSeriesPanel.new( + 'Admin Views Response Status', + ) + + tsQueryOptions.withTargets( + [ + prometheus.new( + '$datasource', + adminResponse2xxQuery, + ) + + prometheus.withLegendFormat( + '{{ view }} / 2xx' + ), + prometheus.new( + '$datasource', + adminResponse4xxQuery, + ) + + prometheus.withLegendFormat( + '{{ view }} / 4xx' + ), + prometheus.new( + '$datasource', + adminResponse5xxQuery, + ) + + prometheus.withLegendFormat( + '{{ view }} / 5xx' + ), ] - ) - .addTarget( - prometheus.target( - apiRequestLatencyP50Query, - format='table', - instant=true - ) - ) - .addTarget( - prometheus.target( - apiRequestLatencyP95Query, - format='table', - instant=true - ) - ) - .addTarget( - prometheus.target( - apiRequestLatencyP99Query, - format='table', - instant=true - ) - ) + paginateTable, + ) + + tsStandardOptions.withUnit('reqps') + + tsOptions.tooltip.withMode('multi') + + tsOptions.tooltip.withSort('desc') + + tsStandardOptions.withOverrides([ + tsOverride.byName.new('2xx') + + tsOverride.byName.withPropertiesFromOptions( + tsStandardOptions.color.withMode('fixed') + + tsStandardOptions.color.withFixedColor('green') + ), + tsOverride.byName.new('4xx') + + tsOverride.byName.withPropertiesFromOptions( + tsStandardOptions.color.withMode('fixed') + + tsStandardOptions.color.withFixedColor('yellow') + ), + tsOverride.byName.new('5xx') + + tsOverride.byName.withPropertiesFromOptions( + tsStandardOptions.color.withMode('fixed') + + tsStandardOptions.color.withFixedColor('red') + ), + ]) + + tsLegend.withShowLegend(true) + + tsLegend.withDisplayMode('table') + + tsLegend.withPlacement('right') + + tsLegend.withCalcs(['mean', 'max']) + + tsLegend.withSortBy('Mean') + + tsLegend.withSortDesc(true) + + tsCustom.stacking.withMode('value') + + tsCustom.withFillOpacity(100) + + tsCustom.withSpanNulls(false), local adminRequestLatencyP50Query = std.strReplace(apiRequestLatencyP50Query, 'view!~"%s"' % $._config.adminViewRegex, 'view=~"%s"' % $._config.adminViewRegex), local adminRequestLatencyP95Query = std.strReplace(apiRequestLatencyP95Query, 'view!~"%s"' % $._config.adminViewRegex, 'view=~"%s"' % $._config.adminViewRegex), local adminRequestLatencyP99Query = std.strReplace(apiRequestLatencyP99Query, 'view!~"%s"' % $._config.adminViewRegex, 'view=~"%s"' % $._config.adminViewRegex), local adminRequestLatencyTable = - grafana.tablePanel.new( + tablePanel.new( 'Admin Request Latency', - datasource='$datasource', - sort={ - col: 3, - desc: true, - }, - styles=[ - { - alias: 'Time', - dateFormat: 'YYYY-MM-DD HH:mm:ss', - type: 'hidden', - pattern: 'Time', - }, - { - alias: 'View', - pattern: 'view', - link: true, - linkTargetBlank: true, - linkTooltip: 'Go To View', - linkUrl: $._config.requestsByViewDashboardUrl + '?var-job=$job&var-namespace=$namespace&var-view=${__cell}', - }, - { - alias: 'Namespace', - pattern: 'namespace', - }, - { - alias: 'Job', - pattern: 'Job', - }, - { - alias: 'P50 Latency', - pattern: 'Value #A', - type: 'number', - unit: 'dtdurations', - }, - { - alias: 'P90 Latency', - pattern: 'Value #B', - type: 'number', - unit: 'dtdurations', - }, - { - alias: 'P99 Latency', - pattern: 'Value #C', - type: 'number', - unit: 'dtdurations', - }, + ) + + tbOptions.withSortBy( + tbOptions.sortBy.withDisplayName('P50 Latency') + + tbOptions.sortBy.withDesc(true) + ) + + tbOptions.footer.TableFooterOptions.withEnablePagination(true) + + tbStandardOptions.withUnit('dtdurations') + + tbQueryOptions.withTargets( + [ + prometheus.new( + '$datasource', + adminRequestLatencyP50Query, + ) + + prometheus.withFormat('table') + + prometheus.withInstant(true), + prometheus.new( + '$datasource', + adminRequestLatencyP95Query, + ) + + prometheus.withFormat('table') + + prometheus.withInstant(true), + prometheus.new( + '$datasource', + adminRequestLatencyP99Query, + ) + + prometheus.withFormat('table') + + prometheus.withInstant(true), ] - ) - .addTarget( - prometheus.target( - adminRequestLatencyP50Query, - format='table', - instant=true - ) - ) - .addTarget( - prometheus.target( - adminRequestLatencyP95Query, - format='table', - instant=true - ) - ) - .addTarget( - prometheus.target( - adminRequestLatencyP99Query, - format='table', - instant=true - ) - ) + paginateTable, - - local apiResponse2xxQuery = ||| - round( - sum( - rate( - django_http_responses_total_by_status_view_method_total{ - namespace=~"$namespace", - job=~"$job", - view=~"$view", - view!~"%(djangoIgnoredViews)s", - method=~"$method", - status=~"2.*", - view!~"%(adminViewRegex)s", - }[$__rate_interval] - ) > 0 - ) by (namespace, job, view), 0.001 - ) - ||| % $._config, - local apiResponse4xxQuery = std.strReplace(apiResponse2xxQuery, '2.*', '4.*'), - local apiResponse5xxQuery = std.strReplace(apiResponse2xxQuery, '2.*', '5.*'), - local apiResponseGraphPanel = - graphPanel.new( - 'API & Other Views Response Status', - datasource='$datasource', - format='reqps', - legend_show=true, - legend_values=true, - legend_alignAsTable=true, - legend_rightSide=true, - legend_avg=true, - legend_max=true, - legend_hideZero=true, - legend_sort='avg', - legend_sortDesc=true, - fill=10, - stack=true, - nullPointMode='null as zero' - ) - .addTarget( - prometheus.target( - apiResponse2xxQuery, - legendFormat='{{ view }} / 2xx', - ) - ) - .addTarget( - prometheus.target( - apiResponse4xxQuery, - legendFormat='{{ view }} / 4xx', - ) - ) - .addTarget( - prometheus.target( - apiResponse5xxQuery, - legendFormat='{{ view }} / 5xx', - ) - ), - - local adminResponse2xxQuery = std.strReplace(apiResponse2xxQuery, 'view!~"%s"' % $._config.adminViewRegex, 'view=~"%s"' % $._config.adminViewRegex), - local adminResponse4xxQuery = std.strReplace(apiResponse4xxQuery, 'view!~"%s"' % $._config.adminViewRegex, 'view=~"%s"' % $._config.adminViewRegex), - local adminResponse5xxQuery = std.strReplace(apiResponse5xxQuery, 'view!~"%s"' % $._config.adminViewRegex, 'view=~"%s"' % $._config.adminViewRegex), - local adminResponseGraphPanel = - graphPanel.new( - 'Admin Views Response Status', - datasource='$datasource', - format='reqps', - legend_show=true, - legend_values=true, - legend_alignAsTable=true, - legend_rightSide=true, - legend_avg=true, - legend_max=true, - legend_hideZero=true, - legend_sort='avg', - legend_sortDesc=true, - stack=true, - fill=10, - nullPointMode='null as zero' - ) - .addTarget( - prometheus.target( - adminResponse2xxQuery, - legendFormat='{{ view }} / 2xx', - ) - ) - .addTarget( - prometheus.target( - adminResponse4xxQuery, - legendFormat='{{ view }} / 4xx', - ) - ) - .addTarget( - prometheus.target( - adminResponse5xxQuery, - legendFormat='{{ view }} / 5xx', - ) - ), + ) + + tbQueryOptions.withTransformations([ + tbQueryOptions.withTransformations([ + tbQueryOptions.transformation.withId( + 'merge' + ), + tbQueryOptions.transformation.withId( + 'organize' + ) + + tbQueryOptions.transformation.withOptions( + { + renameByName: { + job: 'Job', + namespace: 'Namespace', + view: 'View', + 'Value #A': 'P50 Latency', + 'Value #B': 'P95 Latency', + 'Value #C': 'P99 Latency', + }, + indexByName: { + namespace: 0, + job: 1, + view: 2, + 'Value #A': 3, + 'Value #B': 4, + 'Value #C': 5, + }, + excludeByName: { + Time: true, + }, + } + ), + ]), + ]) + + tbStandardOptions.withOverrides([ + tbOverride.byName.new('View') + + tbOverride.byName.withPropertiesFromOptions( + tbStandardOptions.withLinks( + tbPanelOptions.link.withTitle('Go To View') + + tbPanelOptions.link.withType('dashboard') + + tbPanelOptions.link.withUrl( + '/d/%s/django-requests-by-view?var-namespace=${__data.fields.Namespace}&var-job=${__data.fields.Job}&var-view=${__data.fields.View}' % $._config.requestsByViewDashboardUid + ) + + tbPanelOptions.link.withTargetBlank(true) + ) + ), + ]), - local topHttpExceptionsByType1wQuery = ||| + local topHttpExceptionsByView1wQuery = ||| round( topk(10, - sum by (type) ( + sum by (namespace, job, view) ( increase( - django_http_exceptions_total_by_type_total{ + django_http_exceptions_total_by_view_total{ namespace=~"$namespace", job=~"$job", + view!~"%(djangoIgnoredViews)s", }[1w] ) > 0 ) ) ) ||| % $._config, - local topHttpExceptionsByType1wTable = - grafana.tablePanel.new( - 'Top Exceptions by Type (1w)', - datasource='$datasource', - sort={ - col: 2, - desc: true, - }, - styles=[ - { - alias: 'Time', - dateFormat: 'YYYY-MM-DD HH:mm:ss', - type: 'hidden', - pattern: 'Time', - }, - { - alias: 'Type', - pattern: 'type', - }, + + local topHttpExceptionsByView1wTable = + tablePanel.new( + 'Top Exceptions by View (1w)', + ) + + tbOptions.withSortBy( + tbOptions.sortBy.withDisplayName('Value') + + tbOptions.sortBy.withDesc(true) + ) + + tbOptions.footer.TableFooterOptions.withEnablePagination(true) + + tbStandardOptions.withUnit('short') + + tbQueryOptions.withTargets( + prometheus.new( + '$datasource', + topHttpExceptionsByView1wQuery, + ) + + prometheus.withFormat('table') + + prometheus.withInstant(true), + ) + + tbQueryOptions.withTransformations([ + tbQueryOptions.transformation.withId( + 'organize' + ) + + tbQueryOptions.transformation.withOptions( { - alias: 'Value', - pattern: 'Value', - type: 'number', - }, - ] - ) - .addTarget(prometheus.target(topHttpExceptionsByType1wQuery, format='table', instant=true)) + paginateTable, + renameByName: { + job: 'Job', + namespace: 'Namespace', + view: 'View', + }, + indexByName: { + namespace: 0, + job: 1, + view: 2, + }, + excludeByName: { + Time: true, + }, + } + ), + ]) + + tbStandardOptions.withOverrides([ + tbOverride.byName.new('View') + + tbOverride.byName.withPropertiesFromOptions( + tbStandardOptions.withLinks( + tbPanelOptions.link.withTitle('Go To View') + + tbPanelOptions.link.withType('dashboard') + + tbPanelOptions.link.withUrl( + '/d/%s/django-requests-by-view?var-namespace=${__data.fields.Namespace}&var-job=${__data.fields.Job}&var-view=${__data.fields.View}' % $._config.requestsByViewDashboardUid + ) + + tbPanelOptions.link.withTargetBlank(true) + ) + ), + ]), - local topHttpExceptionsByView1wQuery = ||| + local topHttpExceptionsByType1wQuery = ||| round( topk(10, - sum by (view) ( + sum by (namespace, job, type) ( increase( - django_http_exceptions_total_by_view_total{ + django_http_exceptions_total_by_type_total{ namespace=~"$namespace", job=~"$job", - view!~"%(djangoIgnoredViews)s", }[1w] ) > 0 ) ) ) ||| % $._config, - local topHttpExceptionsByView1wTable = - grafana.tablePanel.new( - 'Top Exceptions by View (1w)', - datasource='$datasource', - sort={ - col: 2, - desc: true, - }, - styles=[ - { - alias: 'Time', - dateFormat: 'YYYY-MM-DD HH:mm:ss', - type: 'hidden', - pattern: 'Time', - }, - { - alias: 'View', - pattern: 'view', - link: true, - linkTargetBlank: true, - linkTooltip: 'Go To View', - linkUrl: $._config.requestsByViewDashboardUrl + '?var-job=$job&var-namespace=$namespace&var-view=${__cell}', - }, + + local topHttpExceptionsByType1wTable = + tablePanel.new( + 'Top Exceptions by Type (1w)', + ) + + tbOptions.withSortBy( + tbOptions.sortBy.withDisplayName('Value') + + tbOptions.sortBy.withDesc(true) + ) + + tbOptions.footer.TableFooterOptions.withEnablePagination(true) + + tbStandardOptions.withUnit('short') + + tbQueryOptions.withTargets( + prometheus.new( + '$datasource', + topHttpExceptionsByType1wQuery, + ) + + prometheus.withFormat('table') + + prometheus.withInstant(true), + ) + + tbQueryOptions.withTransformations([ + tbQueryOptions.transformation.withId( + 'organize' + ) + + tbQueryOptions.transformation.withOptions( { - alias: 'Value', - pattern: 'Value', - type: 'number', - }, - ] - ) - .addTarget(prometheus.target(topHttpExceptionsByView1wQuery, format='table', instant=true)) + paginateTable, + renameByName: { + job: 'Job', + namespace: 'Namespace', + type: 'Type', + }, + indexByName: { + namespace: 0, + job: 1, + type: 2, + }, + excludeByName: { + Time: true, + }, + } + ), + ]), local topResponseByView1wQuery = ||| round( topk(10, - sum by (view) ( + sum by (namespace, job, view) ( increase( django_http_responses_total_by_status_view_method_total{ namespace=~"$namespace", @@ -556,38 +721,65 @@ local paginateTable = { ) ) ||| % $._config, + local topResponseByView1wTable = - grafana.tablePanel.new( + tablePanel.new( 'Top Responses By View (1w)', - datasource='$datasource', - sort={ - col: 2, - desc: true, - }, - styles=[ + ) + + tbOptions.withSortBy( + tbOptions.sortBy.withDisplayName('Value') + + tbOptions.sortBy.withDesc(true) + ) + + tbOptions.footer.TableFooterOptions.withEnablePagination(true) + + tbStandardOptions.withUnit('short') + + tbQueryOptions.withTargets( + prometheus.new( + '$datasource', + topResponseByView1wQuery, + ) + + prometheus.withFormat('table') + + prometheus.withInstant(true), + ) + + tbQueryOptions.withTransformations([ + tbQueryOptions.transformation.withId( + 'organize' + ) + + tbQueryOptions.transformation.withOptions( { - alias: 'Time', - dateFormat: 'YYYY-MM-DD HH:mm:ss', - type: 'hidden', - pattern: 'Time', - }, - { - alias: 'View', - pattern: 'view', - link: true, - linkTargetBlank: true, - linkTooltip: 'Go To View', - linkUrl: $._config.requestsByViewDashboardUrl + '?var-job=$job&var-namespace=$namespace&var-view=${__cell}', - }, - ] - ) - .addTarget(prometheus.target(topResponseByView1wQuery, format='table', instant=true)) + paginateTable, - + renameByName: { + job: 'Job', + namespace: 'Namespace', + view: 'View', + }, + indexByName: { + namespace: 0, + job: 1, + view: 2, + }, + excludeByName: { + Time: true, + }, + } + ), + ]) + + tbStandardOptions.withOverrides([ + tbOverride.byName.new('View') + + tbOverride.byName.withPropertiesFromOptions( + tbStandardOptions.withLinks( + tbPanelOptions.link.withTitle('Go To View') + + tbPanelOptions.link.withType('dashboard') + + tbPanelOptions.link.withUrl( + '/d/%s/django-requests-by-view?var-namespace=${__data.fields.Namespace}&var-job=${__data.fields.Job}&var-view=${__data.fields.View}' % $._config.requestsByViewDashboardUid + ) + + tbPanelOptions.link.withTargetBlank(true) + ) + ), + ]), local topTemplates1wQuery = ||| topk(10, round( - sum by (templatename) ( + sum by (namespace, job, templatename) ( increase( django_http_responses_total_by_templatename_total{ namespace=~"$namespace", @@ -599,28 +791,47 @@ local paginateTable = { ) ) ||| % $._config, + local topTemplates1wTable = - grafana.tablePanel.new( + tablePanel.new( 'Top Templates (1w)', - datasource='$datasource', - sort={ - col: 2, - desc: true, - }, - styles=[ - { - alias: 'Time', - dateFormat: 'YYYY-MM-DD HH:mm:ss', - type: 'hidden', - pattern: 'Time', - }, + ) + + tbOptions.withSortBy( + tbOptions.sortBy.withDisplayName('Value') + + tbOptions.sortBy.withDesc(true) + ) + + tbOptions.footer.TableFooterOptions.withEnablePagination(true) + + tbStandardOptions.withUnit('short') + + tbQueryOptions.withTargets( + prometheus.new( + '$datasource', + topTemplates1wQuery, + ) + + prometheus.withFormat('table') + + prometheus.withInstant(true), + ) + + tbQueryOptions.withTransformations([ + tbQueryOptions.transformation.withId( + 'organize' + ) + + tbQueryOptions.transformation.withOptions( { - alias: 'Template Name', - pattern: 'templatename', - }, - ] - ) - .addTarget(prometheus.target(topTemplates1wQuery, format='table', instant=true)) + paginateTable, + renameByName: { + job: 'Job', + namespace: 'Namespace', + templatename: 'Template Name', + }, + indexByName: { + namespace: 0, + job: 1, + templatename: 2, + }, + excludeByName: { + Time: true, + }, + } + ), + ]), local summaryRow = row.new( @@ -643,42 +854,80 @@ local paginateTable = { ), 'django-requests-overview.json': + $._config.bypassDashboardValidation + dashboard.new( 'Django / Requests / Overview', - description='A dashboard that monitors Django which focuses on giving a overview for requests. It is created using the [Django-mixin](https://github.com/adinhodovic/django-mixin).', - uid=$._config.requestsOverviewDashboardUid, - tags=$._config.tags, - time_from='now-1h', - editable=true, - time_to='now', - timezone='utc' - ) - .addPanel(summaryRow, gridPos={ h: 1, w: 24, x: 0, y: 0 }) - .addPanel(requestVolumeStatPanel, gridPos={ h: 4, w: 6, x: 0, y: 1 }) - .addPanel(requestSuccessRateStatPanel, gridPos={ h: 4, w: 6, x: 6, y: 1 }) - .addPanel(requestLatencyP95SummaryStatPanel, gridPos={ h: 4, w: 6, x: 12, y: 1 }) - .addPanel(requestBytesStatPanel, gridPos={ h: 4, w: 6, x: 18, y: 1 }) - .addPanel(apiViewRow, gridPos={ h: 1, w: 24, x: 0, y: 5 }) - .addPanel(apiResponseGraphPanel, gridPos={ h: 10, w: 12, x: 0, y: 6 }) - .addPanel(apiRequestLatencyTable, gridPos={ h: 10, w: 12, x: 12, y: 6 }) - .addPanel(adminViewRow, gridPos={ h: 1, w: 24, x: 0, y: 16 }) - .addPanel(adminResponseGraphPanel, gridPos={ h: 10, w: 12, x: 0, y: 17 }) - .addPanel(adminRequestLatencyTable, gridPos={ h: 10, w: 12, x: 12, y: 17 }) - .addPanel(weeklyBreakdownRow, gridPos={ h: 1, w: 24, x: 0, y: 26 }) - .addPanel(topHttpExceptionsByView1wTable, gridPos={ h: 8, w: 12, x: 0, y: 27 }) - .addPanel(topHttpExceptionsByType1wTable, gridPos={ h: 8, w: 12, x: 12, y: 27 }) - .addPanel(topResponseByView1wTable, gridPos={ h: 8, w: 12, x: 0, y: 35 }) - .addPanel(topTemplates1wTable, gridPos={ h: 8, w: 12, x: 12, y: 35 }) - + - { templating+: { list+: templates } } + + ) + + dashboard.withDescription('A dashboard that monitors Django which focuses on giving a overview for requests. It is created using the [Django-mixin](https://github.com/adinhodovic/django-mixin).') + + dashboard.withUid($._config.requestsOverviewDashboardUid) + + dashboard.withTags($._config.tags) + + dashboard.withTimezone('utc') + + dashboard.withEditable(true) + + dashboard.time.withFrom('now-1h') + + dashboard.time.withTo('now') + + dashboard.withVariables(variables) + + dashboard.withLinks( + [ + dashboard.link.dashboards.new('Django Dashboards', $._config.tags) + + dashboard.link.link.options.withTargetBlank(true), + ] + ) + + dashboard.withPanels( + [ + summaryRow + + row.gridPos.withX(0) + + row.gridPos.withY(0) + + row.gridPos.withW(24) + + row.gridPos.withH(1), + ] + + grid.makeGrid( + [requestVolumeStatPanel, requestSuccessRateStatPanel, requestLatencyP95SummaryStatPanel, requestBytesStatPanel], + panelWidth=6, + panelHeight=4, + startY=1 + ) + + [ + apiViewRow + + row.gridPos.withX(0) + + row.gridPos.withY(5) + + row.gridPos.withW(24) + + row.gridPos.withH(1), + ] + + grid.makeGrid( + [apiResponseTimeSeriesPanel, apiRequestLatencyTable], + panelWidth=12, + panelHeight=10, + startY=6 + ) + + [ + adminViewRow + + row.gridPos.withX(0) + + row.gridPos.withY(16) + + row.gridPos.withW(24) + + row.gridPos.withH(1), + ] + + grid.makeGrid( + [adminResponseTimeSeriesPanel, adminRequestLatencyTable], + panelWidth=12, + panelHeight=10, + startY=17 + ) + + [ + weeklyBreakdownRow + + row.gridPos.withX(0) + + row.gridPos.withY(26) + + row.gridPos.withW(24) + + row.gridPos.withH(1), + ] + + grid.makeGrid( + [topHttpExceptionsByView1wTable, topHttpExceptionsByType1wTable, topResponseByView1wTable, topTemplates1wTable], + panelWidth=12, + panelHeight=8, + startY=27 + ) + ) + if $._config.annotation.enabled then - { - annotations: { - list: [ - $._config.customAnnotation, - ], - }, - } + dashboard.withAnnotations($._config.customAnnotation) else {}, }, } diff --git a/dashboards_out/.lint b/dashboards_out/.lint index 89e3c05..dfc108c 100644 --- a/dashboards_out/.lint +++ b/dashboards_out/.lint @@ -1,5 +1,5 @@ exclusions: template-job-rule: panel-job-instance-rule: - rate-interval-rule: target-rate-interval-rule: + panel-datasource-rule: diff --git a/dashboards_out/django-overview.json b/dashboards_out/django-overview.json index beb1ebd..adc619d 100644 --- a/dashboards_out/django-overview.json +++ b/dashboards_out/django-overview.json @@ -1,44 +1,39 @@ { "__inputs": [ ], "__requires": [ ], - "annotations": { - "list": [ ] - }, "description": "A dashboard that monitors Django which focuses on giving a overview for the system (requests, db, cache). It is created using the [Django-mixin](https://github.com/adinhodovic/django-mixin).", "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ ], + "links": [ + { + "tags": [ + "django", + "django-mixin" + ], + "targetBlank": true, + "title": "Django Dashboards", + "type": "dashboards" + } + ], "panels": [ { - "collapse": false, - "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, - "id": 2, - "panels": [ ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, + "id": 1, "title": "Summary", - "titleSize": "h6", "type": "row" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { "color": "red", @@ -46,7 +41,7 @@ }, { "color": "green", - "value": 0.001 + "value": 0.10000000000000001 } ] }, @@ -55,52 +50,47 @@ }, "gridPos": { "h": 4, - "w": 12, + "w": 8, "x": 0, "y": 1 }, - "id": 3, - "links": [ ], + "id": 2, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "round(\n sum(\n rate(\n django_http_requests_total_by_view_transport_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n }[2m]\n )\n ), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "round(\n sum(\n rate(\n django_http_requests_total_by_view_transport_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n }[2m]\n )\n ), 0.001\n)\n" } ], "title": "Request Volume", - "transparent": false, "type": "stat" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { - "color": "green", + "color": "red", "value": 0 + }, + { + "color": "green", + "value": 0.10000000000000001 } ] }, @@ -109,52 +99,47 @@ }, "gridPos": { "h": 4, - "w": 6, - "x": 12, + "w": 8, + "x": 8, "y": 1 }, - "id": 4, - "links": [ ], + "id": 3, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "sum (\n rate (\n django_db_execute_total {\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n )\n) by (namespace, job)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum (\n rate (\n django_db_execute_total {\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n )\n) by (namespace, job)\n" } ], "title": "Database Ops", - "transparent": false, "type": "stat" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { - "color": "green", + "color": "red", "value": 0 + }, + { + "color": "green", + "value": 0.10000000000000001 } ] }, @@ -163,177 +148,199 @@ }, "gridPos": { "h": 4, - "w": 6, - "x": 18, + "w": 8, + "x": 16, "y": 1 }, - "id": 5, - "links": [ ], + "id": 4, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "sum (\n rate (\n django_cache_get_hits_total {\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[30m]\n )\n) by (namespace, job)\n/\nsum (\n rate (\n django_cache_get_total {\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[30m]\n )\n) by (namespace, job)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum (\n rate (\n django_cache_get_hits_total {\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[30m]\n )\n) by (namespace, job)\n/\nsum (\n rate (\n django_cache_get_total {\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[30m]\n )\n) by (namespace, job)\n" } ], "title": "Cache Hitrate [30m]", - "transparent": false, "type": "stat" }, { - "aliasColors": { }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "spanNulls": false, + "stacking": { + "mode": "percent" + } + }, + "unit": "reqps" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "2xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "3xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "4xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "5xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + } + ] + }, "gridPos": { "h": 6, "w": 24, "x": 0, "y": 5 }, - "id": 6, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideZero": true, - "max": true, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "avg", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ ], - "nullPointMode": "null as zero", - "percentage": true, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ ], - "spaceLength": 10, - "stack": true, - "steppedLine": false, + "id": 5, + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v10.1.0", "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n status=~\"2.*\",\n }[$__rate_interval]\n ) > 0\n ) by (job), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "2xx", - "refId": "A" + "legendFormat": "2xx" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n status=~\"3.*\",\n }[$__rate_interval]\n ) > 0\n ) by (job), 0.001\n)\n", + "legendFormat": "3xx" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n status=~\"4.*\",\n }[$__rate_interval]\n ) > 0\n ) by (job), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "4xx", - "refId": "B" + "legendFormat": "4xx" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n status=~\"5.*\",\n }[$__rate_interval]\n ) > 0\n ) by (job), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "5xx", - "refId": "C" + "legendFormat": "5xx" } ], - "thresholds": [ ], - "timeFrom": null, - "timeShift": null, "title": "Responses", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ ] - }, - "yaxes": [ - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] + "type": "timeseries" }, { - "collapse": false, - "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 11 }, - "id": 7, - "panels": [ ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, + "id": 6, "title": "Database", - "titleSize": "h6", "type": "row" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { "color": "green", "value": 0 } ] - }, - "unit": "none" + } } }, "gridPos": { @@ -342,44 +349,35 @@ "x": 0, "y": 12 }, - "id": 8, - "links": [ ], + "id": 7, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "max (\n django_migrations_applied_total {\n namespace=\"$namespace\",\n job=\"$job\"\n }\n) by (namespace, job)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "max (\n django_migrations_applied_total {\n namespace=\"$namespace\",\n job=\"$job\"\n }\n) by (namespace, job)\n" } ], "title": "Migrations Applied", - "transparent": false, "type": "stat" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { "color": "green", @@ -390,8 +388,7 @@ "value": 0.10000000000000001 } ] - }, - "unit": "none" + } } }, "gridPos": { @@ -400,390 +397,288 @@ "x": 6, "y": 12 }, - "id": 9, - "links": [ ], + "id": 8, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "max (\n django_migrations_unapplied_total {\n namespace=\"$namespace\",\n job=\"$job\"\n }\n) by (namespace, job)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "max (\n django_migrations_unapplied_total {\n namespace=\"$namespace\",\n job=\"$job\"\n }\n) by (namespace, job)\n" } ], "title": "Migrations Unapplied", - "transparent": false, "type": "stat" }, { - "columns": [ ], - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 15 }, - "id": 10, - "links": [ ], - "sort": { - "col": 2, - "desc": true + "id": 9, + "options": { + "sortBy": [ + { + "displayName": "Type" + } + ] }, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Type", - "pattern": "type" - } - ], + "pluginVersion": "v10.1.0", "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n topk(10,\n sum by (type) (\n increase(\n django_db_errors_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[1w]\n ) > 0\n )\n )\n)\n", "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "instant": true } ], - "timeFrom": null, - "timeShift": null, "title": "Top Database Errors (1w)", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true + }, + "indexByName": { + "job": 1, + "namespace": 0, + "type": 2 + }, + "renameByName": { + "job": "Job", + "namespace": "Namespace", + "type": "Type" + } + } + } + ], "type": "table" }, { - "aliasColors": { }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "spanNulls": false + }, + "unit": "short" + } + }, "gridPos": { "h": 6, "w": 12, "x": 12, "y": 12 }, - "id": 11, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideZero": true, - "max": true, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "histogram_quantile(0.50,\n sum(\n irate(\n django_db_query_duration_seconds_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n ) > 0\n ) by (vendor, namespace, job, le)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "50 - {{ vendor }}", - "refId": "A" - }, - { - "expr": "histogram_quantile(0.95,\n sum(\n irate(\n django_db_query_duration_seconds_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n ) > 0\n ) by (vendor, namespace, job, le)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "95 - {{ vendor }}", - "refId": "B" - }, - { - "expr": "histogram_quantile(0.99,\n sum(\n irate(\n django_db_query_duration_seconds_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n ) > 0\n ) by (vendor, namespace, job, le)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "99 - {{ vendor }}", - "refId": "C" + "id": 10, + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true }, - { - "expr": "histogram_quantile(0.999,\n sum(\n irate(\n django_db_query_duration_seconds_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n ) > 0\n ) by (vendor, namespace, job, le)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "99.9 - {{ vendor }}", - "refId": "D" + "tooltip": { + "mode": "multi", + "sort": "desc" } - ], - "thresholds": [ ], - "timeFrom": null, - "timeShift": null, - "title": "DB Latency", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ ] - }, - "yaxes": [ - { - "format": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, + }, + "pluginVersion": "v10.1.0", + "targets": [ { - "format": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "round(\n sum(\n increase(\n django_db_new_connections_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, vendor)\n)\n", + "legendFormat": "{{ vendor }}" } - ] + ], + "title": "Database Connections", + "type": "timeseries" }, { - "aliasColors": { }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "spanNulls": false + }, + "unit": "s" + } + }, "gridPos": { "h": 6, "w": 12, "x": 12, "y": 18 }, - "id": 12, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideZero": true, - "max": true, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, + "id": 11, + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "round(\n sum(\n increase(\n django_db_new_connections_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, vendor)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{ vendor }}", - "refId": "A" - } - ], - "thresholds": [ ], - "timeFrom": null, - "timeShift": null, - "title": "DB Connections", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ ] - }, - "yaxes": [ + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.50,\n sum(\n irate(\n django_db_query_duration_seconds_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n ) > 0\n ) by (vendor, namespace, job, le)\n)\n", + "legendFormat": "50 - {{ vendor }}" + }, + { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.95,\n sum(\n irate(\n django_db_query_duration_seconds_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n ) > 0\n ) by (vendor, namespace, job, le)\n)\n", + "legendFormat": "95 - {{ vendor }}" + }, { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.99,\n sum(\n irate(\n django_db_query_duration_seconds_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n ) > 0\n ) by (vendor, namespace, job, le)\n)\n", + "legendFormat": "99 - {{ vendor }}" }, { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.999,\n sum(\n irate(\n django_db_query_duration_seconds_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n ) > 0\n ) by (vendor, namespace, job, le)\n)\n", + "legendFormat": "99.9 - {{ vendor }}" } - ] + ], + "title": "Database Latency", + "type": "timeseries" }, { - "collapse": false, - "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 24 }, - "id": 13, - "panels": [ ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, + "id": 12, "title": "Cache", - "titleSize": "h6", "type": "row" }, { - "aliasColors": { }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "spanNulls": false, + "stacking": { + "mode": "percent" + } + }, + "unit": "ops" + } + }, "gridPos": { "h": 6, "w": 24, "x": 0, "y": 25 }, - "id": 14, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideZero": true, - "max": true, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "avg", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ ], - "spaceLength": 10, - "stack": true, - "steppedLine": false, + "id": 13, + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v10.1.0", "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "sum(\n rate(\n django_cache_get_hits_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n ) > 0\n) by (namespace, job, backend)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Hit - {{ backend }}", - "refId": "A" + "legendFormat": "Hit - {{ backend }}" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "sum(\n rate(\n django_cache_get_misses_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n ) > 0\n) by (namespace, job, backend)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "Miss - {{ backend }}", - "refId": "B" + "legendFormat": "Miss - {{ backend }}" } ], - "thresholds": [ ], - "timeFrom": null, - "timeShift": null, "title": "Cache Get", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ ] - }, - "yaxes": [ - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "ops", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] + "type": "timeseries" } ], - "refresh": "", - "rows": [ ], - "schemaVersion": 14, - "style": "dark", + "schemaVersion": 36, "tags": [ "django", "django-mixin" @@ -791,61 +686,38 @@ "templating": { "list": [ { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, "label": "Data Source", "name": "datasource", - "options": [ ], "query": "prometheus", - "refresh": 1, - "regex": "", "type": "datasource" }, { - "allValue": null, - "current": { - "text": "", - "value": "" + "datasource": { + "type": "prometheus", + "uid": "${datasource}" }, - "datasource": "$datasource", - "hide": 0, "includeAll": false, "label": "Namespace", "multi": false, "name": "namespace", - "options": [ ], "query": "label_values(django_http_responses_total_by_status_view_method_total{}, namespace)", - "refresh": 1, - "regex": "", + "refresh": 2, "sort": 1, - "tagValuesQuery": "", - "tags": [ ], - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" }, { - "allValue": null, - "current": { }, - "datasource": "$datasource", - "hide": 0, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, "includeAll": false, "label": "Job", "multi": false, "name": "job", - "options": [ ], "query": "label_values(django_http_responses_total_by_status_view_method_total{namespace=~\"$namespace\"}, job)", - "refresh": 1, - "regex": "", + "refresh": 2, "sort": 1, - "tagValuesQuery": "", - "tags": [ ], - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" } ] }, @@ -853,33 +725,7 @@ "from": "now-6h", "to": "now" }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ] - }, "timezone": "utc", "title": "Django / Overview", - "uid": "django-overview-jkwq", - "version": 0 + "uid": "django-overview-jkwq" } diff --git a/dashboards_out/django-requests-by-view.json b/dashboards_out/django-requests-by-view.json index dcfdbf1..6ca779c 100644 --- a/dashboards_out/django-requests-by-view.json +++ b/dashboards_out/django-requests-by-view.json @@ -1,44 +1,39 @@ { "__inputs": [ ], "__requires": [ ], - "annotations": { - "list": [ ] - }, "description": "A dashboard that monitors Django which focuses on breaking down requests by view. It is created using the [Django-mixin](https://github.com/adinhodovic/django-mixin).", "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ ], + "links": [ + { + "tags": [ + "django", + "django-mixin" + ], + "targetBlank": true, + "title": "Django Dashboards", + "type": "dashboards" + } + ], "panels": [ { - "collapse": false, - "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, - "id": 2, - "panels": [ ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, + "id": 1, "title": "Summary", - "titleSize": "h6", "type": "row" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { "color": "red", @@ -63,48 +58,39 @@ "x": 0, "y": 1 }, - "id": 3, - "links": [ ], + "id": 2, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "sum(\n rate(\n django_http_responses_total_by_status_view_method_total{namespace=~\"$namespace\", job=~\"$job\", view=\"$view\", method=~\"$method\", status!~\"[4-5].*\"}[1w]\n )\n) /\nsum(\n rate(\n django_http_responses_total_by_status_view_method_total{namespace=~\"$namespace\", job=~\"$job\", view=\"$view\", method=~\"$method\"}[1w]\n )\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n method=~\"$method\",\n status!~\"[4-5].*\"\n }[1w]\n )\n) /\nsum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n method=~\"$method\"\n }[1w]\n )\n)\n" } ], "title": "Success Rate (non 4xx-5xx responses) [1w]", - "transparent": false, "type": "stat" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { "color": "green", - "value": 0.10000000000000001 + "value": 1 }, { "color": "yellow", @@ -115,8 +101,7 @@ "value": 100 } ] - }, - "unit": "none" + } } }, "gridPos": { @@ -125,44 +110,35 @@ "x": 6, "y": 1 }, - "id": 4, - "links": [ ], + "id": 3, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "sum by (view) (\n increase(\n django_http_exceptions_total_by_view_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n }[1w]\n ) > 0\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum by (view) (\n increase(\n django_http_exceptions_total_by_view_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n }[1w]\n ) > 0\n)\n" } ], "title": "HTTP Exceptions [1w]", - "transparent": false, "type": "stat" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { "color": "green", @@ -187,44 +163,35 @@ "x": 12, "y": 1 }, - "id": 5, - "links": [ ], + "id": 4, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "histogram_quantile(0.50,\n sum (\n rate (\n django_http_requests_latency_seconds_by_view_method_bucket {\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n method=~\"$method\"\n }[$__range]\n )\n ) by (job, le)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.50,\n sum (\n rate (\n django_http_requests_latency_seconds_by_view_method_bucket {\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n method=~\"$method\"\n }[$__range]\n )\n ) by (job, le)\n)\n" } ], "title": "Average Request Latency (P50) [1w]", - "transparent": false, "type": "stat" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { "color": "green", @@ -249,469 +216,379 @@ "x": 18, "y": 1 }, - "id": 6, - "links": [ ], + "id": 5, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "histogram_quantile(0.95,\n sum (\n rate (\n django_http_requests_latency_seconds_by_view_method_bucket {\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n method=~\"$method\"\n }[$__range]\n )\n ) by (job, le)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.95,\n sum (\n rate (\n django_http_requests_latency_seconds_by_view_method_bucket {\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n method=~\"$method\"\n }[$__range]\n )\n ) by (job, le)\n)\n" } ], - "title": "Request Latency (P95) [1w]", - "transparent": false, + "title": "Average Request Latency (P95) [1w]", "type": "stat" }, { - "collapse": false, - "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 5 }, - "id": 7, - "panels": [ ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, + "id": 6, "title": "Request & Responses", - "titleSize": "h6", "type": "row" }, { - "aliasColors": { }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "spanNulls": false + }, + "unit": "reqps" + } + }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 6 }, - "id": 8, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideZero": true, - "max": true, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, + "id": 7, + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v10.1.0", "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_requests_total_by_view_transport_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\"\n }[$__rate_interval]\n ) > 0\n ) by (job), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "reqps", - "refId": "A" + "legendFormat": "reqps" } ], - "thresholds": [ ], - "timeFrom": null, - "timeShift": null, "title": "Requests", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ ] - }, - "yaxes": [ - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] + "type": "timeseries" }, { - "aliasColors": { }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "spanNulls": false, + "stacking": { + "mode": "percent" + } + }, + "unit": "reqps" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "2xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "3xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "4xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "5xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + } + ] + }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 6 }, - "id": 9, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideZero": true, - "max": true, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "avg", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ ], - "nullPointMode": "null as zero", - "percentage": true, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ ], - "spaceLength": 10, - "stack": true, - "steppedLine": false, + "id": 8, + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v10.1.0", "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n status=~\"2.*\",\n }[$__rate_interval]\n ) > 0\n ) by (job), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "2xx", - "refId": "A" + "legendFormat": "2xx" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n status=~\"3.*\",\n }[$__rate_interval]\n ) > 0\n ) by (job), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "3xx", - "refId": "B" + "legendFormat": "3xx" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n status=~\"4.*\",\n }[$__rate_interval]\n ) > 0\n ) by (job), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "4xx", - "refId": "C" + "legendFormat": "4xx" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n status=~\"5.*\",\n }[$__rate_interval]\n ) > 0\n ) by (job), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "5xx", - "refId": "D" + "legendFormat": "5xx" } ], - "thresholds": [ ], - "timeFrom": null, - "timeShift": null, "title": "Responses", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ ] - }, - "yaxes": [ - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] + "type": "timeseries" }, { - "collapse": false, - "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 14 }, - "id": 10, - "panels": [ ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, + "id": 9, "title": "Latency & Status Codes", - "titleSize": "h6", "type": "row" }, { - "aliasColors": { }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "spanNulls": false, + "stacking": { + "mode": "value" + } + }, + "unit": "reqps" + } + }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 15 }, - "id": 11, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideZero": true, - "max": true, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "avg", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ ], - "spaceLength": 10, - "stack": true, - "steppedLine": false, + "id": 10, + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v10.1.0", "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n method=~\"$method\",\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view, status, method), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{ view }} / {{ status }} / {{ method }}", - "refId": "A" + "legendFormat": "{{ view }} / {{ status }} / {{ method }}" } ], - "thresholds": [ ], - "timeFrom": null, - "timeShift": null, - "title": "Response Status Codes", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ ] - }, - "yaxes": [ - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] + "title": "Responses Status Codes", + "type": "timeseries" }, { - "aliasColors": { }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 1, - "fillGradient": 0, + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 10, + "spanNulls": false + }, + "unit": "s" + } + }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 15 }, - "id": 12, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideZero": true, - "max": true, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "links": [ ], - "nullPointMode": "null", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ ], - "spaceLength": 10, - "stack": false, - "steppedLine": false, + "id": 11, + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "v10.1.0", "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "histogram_quantile(0.50,\n sum(\n irate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (view, le)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "50 - {{ view }}", - "refId": "A" + "legendFormat": "50 - {{ view }}" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "histogram_quantile(0.95,\n sum(\n irate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (view, le)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "95 - {{ view }}", - "refId": "B" + "legendFormat": "95 - {{ view }}" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "histogram_quantile(0.99,\n sum(\n irate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (view, le)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "99 - {{ view }}", - "refId": "C" + "legendFormat": "99 - {{ view }}" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "histogram_quantile(0.999,\n sum(\n irate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=\"$view\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (view, le)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "99.9 - {{ view }}", - "refId": "D" + "legendFormat": "99.9 - {{ view }}" } ], - "thresholds": [ ], - "timeFrom": null, - "timeShift": null, "title": "Request Latency", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ ] - }, - "yaxes": [ - { - "format": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "s", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] + "type": "timeseries" } ], - "refresh": "", - "rows": [ ], - "schemaVersion": 14, - "style": "dark", + "schemaVersion": 36, "tags": [ "django", "django-mixin" @@ -719,101 +596,66 @@ "templating": { "list": [ { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, "label": "Data Source", "name": "datasource", - "options": [ ], "query": "prometheus", - "refresh": 1, - "regex": "", "type": "datasource" }, { - "allValue": null, - "current": { }, - "datasource": "$datasource", - "hide": 0, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, "includeAll": false, "label": "Namespace", "multi": false, "name": "namespace", - "options": [ ], "query": "label_values(django_http_responses_total_by_status_view_method_total{}, namespace)", "refresh": 2, - "regex": "", "sort": 1, - "tagValuesQuery": "", - "tags": [ ], - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" }, { - "allValue": null, - "current": { }, - "datasource": "$datasource", - "hide": 0, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, "includeAll": false, "label": "Job", "multi": false, "name": "job", - "options": [ ], "query": "label_values(django_http_responses_total_by_status_view_method_total{namespace=~\"$namespace\"}, job)", "refresh": 2, - "regex": "", "sort": 1, - "tagValuesQuery": "", - "tags": [ ], - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" }, { - "allValue": null, - "current": { }, - "datasource": "$datasource", - "hide": 0, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, "includeAll": false, "label": "View", "multi": false, "name": "view", - "options": [ ], "query": "label_values(django_http_responses_total_by_status_view_method_total{namespace=~\"$namespace\", job=~\"$job\", view!~\"|health_check:health_check_home|prometheus-django-metrics\"}, view)", "refresh": 2, - "regex": "", "sort": 1, - "tagValuesQuery": "", - "tags": [ ], - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" }, { - "allValue": null, - "current": { - "text": "", - "value": "" + "datasource": { + "type": "prometheus", + "uid": "${datasource}" }, - "datasource": "$datasource", - "hide": 0, "includeAll": true, "label": "Method", "multi": true, "name": "method", - "options": [ ], "query": "label_values(django_http_responses_total_by_status_view_method_total{namespace=~\"$namespace\", job=~\"$job\", view=~\"$view\"}, method)", "refresh": 2, - "regex": "", "sort": 1, - "tagValuesQuery": "", - "tags": [ ], - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" } ] }, @@ -821,33 +663,7 @@ "from": "now-6h", "to": "now" }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ] - }, "timezone": "utc", "title": "Django / Requests / By View", - "uid": "django-requests-by-view-jkwq", - "version": 0 + "uid": "django-requests-by-view-jkwq" } diff --git a/dashboards_out/django-requests-overview.json b/dashboards_out/django-requests-overview.json index 2b8b143..4f515ec 100644 --- a/dashboards_out/django-requests-overview.json +++ b/dashboards_out/django-requests-overview.json @@ -1,44 +1,39 @@ { "__inputs": [ ], "__requires": [ ], - "annotations": { - "list": [ ] - }, "description": "A dashboard that monitors Django which focuses on giving a overview for requests. It is created using the [Django-mixin](https://github.com/adinhodovic/django-mixin).", "editable": true, - "gnetId": null, - "graphTooltip": 0, - "hideControls": false, - "id": null, - "links": [ ], + "links": [ + { + "tags": [ + "django", + "django-mixin" + ], + "targetBlank": true, + "title": "Django Dashboards", + "type": "dashboards" + } + ], "panels": [ { - "collapse": false, - "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, - "id": 2, - "panels": [ ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, + "id": 1, "title": "Summary", - "titleSize": "h6", "type": "row" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { "color": "red", @@ -59,44 +54,35 @@ "x": 0, "y": 1 }, - "id": 3, - "links": [ ], + "id": 2, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "round(\n sum(\n rate(\n django_http_requests_total_by_view_transport_method_total{namespace=~\"$namespace\", job=~\"$job\", view=~\"$view\", view!~\"|health_check:health_check_home|prometheus-django-metrics\", method=~\"$method\"}[2m]\n )\n ), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "round(\n sum(\n rate(\n django_http_requests_total_by_view_transport_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n method=~\"$method\"\n }[2m]\n )\n ), 0.001\n)\n" } ], "title": "Request Volume", - "transparent": false, "type": "stat" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { "color": "red", @@ -121,44 +107,35 @@ "x": 6, "y": 1 }, - "id": 4, - "links": [ ], + "id": 3, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "sum(\n rate(\n django_http_responses_total_by_status_view_method_total{namespace=~\"$namespace\", job=~\"$job\", view=~\"$view\", view!~\"|health_check:health_check_home|prometheus-django-metrics\", method=~\"$method\", status!~\"[4-5].*\"}[$__rate_interval]\n )\n) /\nsum(\n rate(\n django_http_responses_total_by_status_view_method_total{namespace=~\"$namespace\", job=~\"$job\", view=~\"$view\", view!~\"|health_check:health_check_home|prometheus-django-metrics\", method=~\"$method\"}[$__rate_interval]\n )\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n method=~\"$method\",\n status!~\"[4-5].*\"\n }[$__rate_interval]\n )\n) /\nsum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n method=~\"$method\"\n }[$__rate_interval]\n )\n)\n" } ], "title": "Success Rate (non 4-5xx responses)", - "transparent": false, "type": "stat" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { "color": "green", @@ -183,44 +160,35 @@ "x": 12, "y": 1 }, - "id": 5, - "links": [ ], + "id": 4, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "histogram_quantile(0.95,\n sum (\n irate(\n django_http_requests_latency_seconds_by_view_method_bucket {\n namespace=~\"$namespace\",\n job=~\"$job\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n }[$__rate_interval]\n )\n ) by (job, le)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.95,\n sum (\n irate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n }[$__rate_interval]\n )\n ) by (job, le)\n)\n" } ], "title": "Request Latency (P95)", - "transparent": false, "type": "stat" }, { - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, "fieldConfig": { "defaults": { - "links": [ ], - "mappings": [ ], "thresholds": { - "mode": "absolute", "steps": [ { "color": "red", @@ -245,670 +213,818 @@ "x": 18, "y": 1 }, - "id": 6, - "links": [ ], + "id": 5, "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", "reduceOptions": { "calcs": [ "lastNotNull" - ], - "fields": "", - "values": false - }, - "textMode": "auto" + ] + } }, - "pluginVersion": "7", + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "histogram_quantile(0.95,\n sum (\n rate (\n django_http_requests_body_total_bytes_bucket {\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n )\n ) by (job, le)\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.95,\n sum (\n rate (\n django_http_requests_body_total_bytes_bucket {\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[$__rate_interval]\n )\n ) by (job, le)\n)\n" } ], "title": "Request Body Size (P95)", - "transparent": false, "type": "stat" }, { - "collapse": false, - "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 5 }, - "id": 7, - "panels": [ ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, + "id": 6, "title": "API Views & Other", - "titleSize": "h6", "type": "row" }, { - "aliasColors": { }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "spanNulls": false, + "stacking": { + "mode": "value" + } + }, + "unit": "reqps" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "2xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "4xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "5xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + } + ] + }, "gridPos": { "h": 10, "w": 12, "x": 0, "y": 6 }, - "id": 8, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideZero": true, - "max": true, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "avg", - "sortDesc": true, - "total": false, - "values": true + "id": 7, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } }, - "lines": true, - "linewidth": 1, - "links": [ ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ ], - "spaceLength": 10, - "stack": true, - "steppedLine": false, + "pluginVersion": "v10.1.0", "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n method=~\"$method\",\n status=~\"2.*\",\n view!~\"admin.*\",\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{ view }} / 2xx", - "refId": "A" + "legendFormat": "{{ view }} / 2xx" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n method=~\"$method\",\n status=~\"4.*\",\n view!~\"admin.*\",\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{ view }} / 4xx", - "refId": "B" + "legendFormat": "{{ view }} / 4xx" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n method=~\"$method\",\n status=~\"5.*\",\n view!~\"admin.*\",\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{ view }} / 5xx", - "refId": "C" + "legendFormat": "{{ view }} / 5xx" } ], - "thresholds": [ ], - "timeFrom": null, - "timeShift": null, "title": "API & Other Views Response Status", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ ] - }, - "yaxes": [ - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] + "type": "timeseries" }, { - "columns": [ ], - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "dtdurations" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "View" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Go To View", + "type": "dashboard", + "url": "/d/django-requests-by-view-jkwq/django-requests-by-view?var-namespace=${__data.fields.Namespace}&var-job=${__data.fields.Job}&var-view=${__data.fields.View}" + } + ] + } + ] + } + ] + }, "gridPos": { "h": 10, "w": 12, "x": 12, "y": 6 }, - "id": 9, - "links": [ ], - "pageSize": 6, - "sort": { - "col": 3, - "desc": true - }, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "View", - "link": true, - "linkTargetBlank": true, - "linkTooltip": "Go To View", - "linkUrl": "https://grafana.com/d/django-requests-by-view-jkwq/django-requests-by-view?var-job=$job&var-namespace=$namespace&var-view=${__cell}", - "pattern": "view" - }, - { - "alias": "Namespace", - "pattern": "namespace" - }, - { - "alias": "Job", - "pattern": "job" - }, - { - "alias": "P50 Latency", - "pattern": "Value #A", - "type": "number", - "unit": "dtdurations" - }, - { - "alias": "P90 Latency", - "pattern": "Value #B", - "type": "number", - "unit": "dtdurations" + "id": 8, + "options": { + "footer": { + "enablePagination": true }, - { - "alias": "P99 Latency", - "pattern": "Value #C", - "type": "number", - "unit": "dtdurations" - } - ], + "sortBy": [ + { + "desc": true, + "displayName": "P50 Latency" + } + ] + }, + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "histogram_quantile(0.50,\n sum(\n rate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics|\",\n view!~\"admin.*\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (view, job, le)\n)\n", + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.50,\n sum(\n rate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics|\",\n view!~\"admin.*\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view, le)\n)\n", "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "instant": true }, { - "expr": "histogram_quantile(0.95,\n sum(\n rate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics|\",\n view!~\"admin.*\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (view, job, le)\n)\n", + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.95,\n sum(\n rate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics|\",\n view!~\"admin.*\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view, le)\n)\n", "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B" + "instant": true }, { - "expr": "histogram_quantile(0.99,\n sum(\n rate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics|\",\n view!~\"admin.*\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (view, job, le)\n)\n", + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.99,\n sum(\n rate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics|\",\n view!~\"admin.*\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view, le)\n)\n", "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C" + "instant": true } ], - "timeFrom": null, - "timeShift": null, "title": "API & Other Views Request Latency", + "transformations": [ + { + "id": "merge" + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true + }, + "indexByName": { + "Value #A": 3, + "Value #B": 4, + "Value #C": 5, + "job": 1, + "namespace": 0, + "view": 2 + }, + "renameByName": { + "Value #A": "P50 Latency", + "Value #B": "P95 Latency", + "Value #C": "P99 Latency", + "job": "Job", + "namespace": "Namespace", + "view": "View" + } + } + } + ], "type": "table" }, { - "collapse": false, - "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 16 }, - "id": 10, - "panels": [ ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, + "id": 9, "title": "Admin Views", - "titleSize": "h6", "type": "row" }, { - "aliasColors": { }, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": "$datasource", - "fill": 10, - "fillGradient": 0, + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "custom": { + "fillOpacity": 100, + "spanNulls": false, + "stacking": { + "mode": "value" + } + }, + "unit": "reqps" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "2xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "4xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "5xx" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + } + ] + }, "gridPos": { "h": 10, "w": 12, "x": 0, "y": 17 }, - "id": 11, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideZero": true, - "max": true, - "min": false, - "rightSide": true, - "show": true, - "sideWidth": null, - "sort": "avg", - "sortDesc": true, - "total": false, - "values": true + "id": 10, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } }, - "lines": true, - "linewidth": 1, - "links": [ ], - "nullPointMode": "null as zero", - "percentage": false, - "pointradius": 5, - "points": false, - "renderer": "flot", - "repeat": null, - "seriesOverrides": [ ], - "spaceLength": 10, - "stack": true, - "steppedLine": false, + "pluginVersion": "v10.1.0", "targets": [ { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n method=~\"$method\",\n status=~\"2.*\",\n view=~\"admin.*\",\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{ view }} / 2xx", - "refId": "A" + "legendFormat": "{{ view }} / 2xx" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n method=~\"$method\",\n status=~\"4.*\",\n view=~\"admin.*\",\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{ view }} / 4xx", - "refId": "B" + "legendFormat": "{{ view }} / 4xx" }, { + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, "expr": "round(\n sum(\n rate(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n method=~\"$method\",\n status=~\"5.*\",\n view=~\"admin.*\",\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view), 0.001\n)\n", - "format": "time_series", - "intervalFactor": 2, - "legendFormat": "{{ view }} / 5xx", - "refId": "C" + "legendFormat": "{{ view }} / 5xx" } ], - "thresholds": [ ], - "timeFrom": null, - "timeShift": null, "title": "Admin Views Response Status", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [ ] - }, - "yaxes": [ - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - }, - { - "format": "reqps", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ] + "type": "timeseries" }, { - "columns": [ ], - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "dtdurations" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "View" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Go To View", + "type": "dashboard", + "url": "/d/django-requests-by-view-jkwq/django-requests-by-view?var-namespace=${__data.fields.Namespace}&var-job=${__data.fields.Job}&var-view=${__data.fields.View}" + } + ] + } + ] + } + ] + }, "gridPos": { "h": 10, "w": 12, "x": 12, "y": 17 }, - "id": 12, - "links": [ ], - "pageSize": 6, - "sort": { - "col": 3, - "desc": true - }, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "View", - "link": true, - "linkTargetBlank": true, - "linkTooltip": "Go To View", - "linkUrl": "https://grafana.com/d/django-requests-by-view-jkwq/django-requests-by-view?var-job=$job&var-namespace=$namespace&var-view=${__cell}", - "pattern": "view" - }, - { - "alias": "Namespace", - "pattern": "namespace" - }, - { - "alias": "Job", - "pattern": "Job" - }, - { - "alias": "P50 Latency", - "pattern": "Value #A", - "type": "number", - "unit": "dtdurations" - }, - { - "alias": "P90 Latency", - "pattern": "Value #B", - "type": "number", - "unit": "dtdurations" + "id": 11, + "options": { + "footer": { + "enablePagination": true }, - { - "alias": "P99 Latency", - "pattern": "Value #C", - "type": "number", - "unit": "dtdurations" - } - ], + "sortBy": [ + { + "desc": true, + "displayName": "P50 Latency" + } + ] + }, + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "histogram_quantile(0.50,\n sum(\n rate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics|\",\n view=~\"admin.*\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (view, job, le)\n)\n", + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.50,\n sum(\n rate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics|\",\n view=~\"admin.*\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view, le)\n)\n", "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "instant": true }, { - "expr": "histogram_quantile(0.95,\n sum(\n rate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics|\",\n view=~\"admin.*\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (view, job, le)\n)\n", + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.95,\n sum(\n rate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics|\",\n view=~\"admin.*\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view, le)\n)\n", "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "B" + "instant": true }, { - "expr": "histogram_quantile(0.99,\n sum(\n rate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics|\",\n view=~\"admin.*\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (view, job, le)\n)\n", + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "histogram_quantile(0.99,\n sum(\n rate(\n django_http_requests_latency_seconds_by_view_method_bucket{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view=~\"$view\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics|\",\n view=~\"admin.*\",\n method=~\"$method\"\n }[$__rate_interval]\n ) > 0\n ) by (namespace, job, view, le)\n)\n", "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "C" + "instant": true } ], - "timeFrom": null, - "timeShift": null, "title": "Admin Request Latency", + "transformations": [ + { + "transformations": [ + { + "id": "merge" + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true + }, + "indexByName": { + "Value #A": 3, + "Value #B": 4, + "Value #C": 5, + "job": 1, + "namespace": 0, + "view": 2 + }, + "renameByName": { + "Value #A": "P50 Latency", + "Value #B": "P95 Latency", + "Value #C": "P99 Latency", + "job": "Job", + "namespace": "Namespace", + "view": "View" + } + } + } + ] + } + ], "type": "table" }, { - "collapse": false, - "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 26 }, - "id": 13, - "panels": [ ], - "repeat": null, - "repeatIteration": null, - "repeatRowId": null, - "showTitle": true, + "id": 12, "title": "Weekly Breakdown", - "titleSize": "h6", "type": "row" }, { - "columns": [ ], - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "View" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Go To View", + "type": "dashboard", + "url": "/d/django-requests-by-view-jkwq/django-requests-by-view?var-namespace=${__data.fields.Namespace}&var-job=${__data.fields.Job}&var-view=${__data.fields.View}" + } + ] + } + ] + } + ] + }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 27 }, - "id": 14, - "links": [ ], - "pageSize": 6, - "sort": { - "col": 2, - "desc": true - }, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "View", - "link": true, - "linkTargetBlank": true, - "linkTooltip": "Go To View", - "linkUrl": "https://grafana.com/d/django-requests-by-view-jkwq/django-requests-by-view?var-job=$job&var-namespace=$namespace&var-view=${__cell}", - "pattern": "view" + "id": 13, + "options": { + "footer": { + "enablePagination": true }, - { - "alias": "Value", - "pattern": "Value", - "type": "number" - } - ], + "sortBy": [ + { + "desc": true, + "displayName": "Value" + } + ] + }, + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "round(\n topk(10,\n sum by (view) (\n increase(\n django_http_exceptions_total_by_view_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n }[1w]\n ) > 0\n )\n )\n)\n", + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "round(\n topk(10,\n sum by (namespace, job, view) (\n increase(\n django_http_exceptions_total_by_view_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n }[1w]\n ) > 0\n )\n )\n)\n", "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "instant": true } ], - "timeFrom": null, - "timeShift": null, "title": "Top Exceptions by View (1w)", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true + }, + "indexByName": { + "job": 1, + "namespace": 0, + "view": 2 + }, + "renameByName": { + "job": "Job", + "namespace": "Namespace", + "view": "View" + } + } + } + ], "type": "table" }, { - "columns": [ ], - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + } + }, "gridPos": { "h": 8, "w": 12, "x": 12, "y": 27 }, - "id": 15, - "links": [ ], - "pageSize": 6, - "sort": { - "col": 2, - "desc": true - }, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" - }, - { - "alias": "Type", - "pattern": "type" + "id": 14, + "options": { + "footer": { + "enablePagination": true }, - { - "alias": "Value", - "pattern": "Value", - "type": "number" - } - ], + "sortBy": [ + { + "desc": true, + "displayName": "Value" + } + ] + }, + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "round(\n topk(10,\n sum by (type) (\n increase(\n django_http_exceptions_total_by_type_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[1w]\n ) > 0\n )\n )\n)\n", + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "round(\n topk(10,\n sum by (namespace, job, type) (\n increase(\n django_http_exceptions_total_by_type_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n }[1w]\n ) > 0\n )\n )\n)\n", "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "instant": true } ], - "timeFrom": null, - "timeShift": null, "title": "Top Exceptions by Type (1w)", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true + }, + "indexByName": { + "job": 1, + "namespace": 0, + "type": 2 + }, + "renameByName": { + "job": "Job", + "namespace": "Namespace", + "type": "Type" + } + } + } + ], "type": "table" }, { - "columns": [ ], - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "View" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Go To View", + "type": "dashboard", + "url": "/d/django-requests-by-view-jkwq/django-requests-by-view?var-namespace=${__data.fields.Namespace}&var-job=${__data.fields.Job}&var-view=${__data.fields.View}" + } + ] + } + ] + } + ] + }, "gridPos": { "h": 8, "w": 12, "x": 0, - "y": 35 - }, - "id": 16, - "links": [ ], - "pageSize": 6, - "sort": { - "col": 2, - "desc": true + "y": 36 }, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" + "id": 15, + "options": { + "footer": { + "enablePagination": true }, - { - "alias": "View", - "link": true, - "linkTargetBlank": true, - "linkTooltip": "Go To View", - "linkUrl": "https://grafana.com/d/django-requests-by-view-jkwq/django-requests-by-view?var-job=$job&var-namespace=$namespace&var-view=${__cell}", - "pattern": "view" - } - ], + "sortBy": [ + { + "desc": true, + "displayName": "Value" + } + ] + }, + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "round(\n topk(10,\n sum by (view) (\n increase(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n method=~\"$method\"\n }[1w]\n ) > 0\n )\n )\n)\n", + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "round(\n topk(10,\n sum by (namespace, job, view) (\n increase(\n django_http_responses_total_by_status_view_method_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n view!~\"|health_check:health_check_home|prometheus-django-metrics\",\n method=~\"$method\"\n }[1w]\n ) > 0\n )\n )\n)\n", "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "instant": true } ], - "timeFrom": null, - "timeShift": null, "title": "Top Responses By View (1w)", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true + }, + "indexByName": { + "job": 1, + "namespace": 0, + "view": 2 + }, + "renameByName": { + "job": "Job", + "namespace": "Namespace", + "view": "View" + } + } + } + ], "type": "table" }, { - "columns": [ ], - "datasource": "$datasource", + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + } + }, "gridPos": { "h": 8, "w": 12, "x": 12, - "y": 35 - }, - "id": 17, - "links": [ ], - "pageSize": 6, - "sort": { - "col": 2, - "desc": true + "y": 36 }, - "styles": [ - { - "alias": "Time", - "dateFormat": "YYYY-MM-DD HH:mm:ss", - "pattern": "Time", - "type": "hidden" + "id": 16, + "options": { + "footer": { + "enablePagination": true }, - { - "alias": "Template Name", - "pattern": "templatename" - } - ], + "sortBy": [ + { + "desc": true, + "displayName": "Value" + } + ] + }, + "pluginVersion": "v10.1.0", "targets": [ { - "expr": "topk(10,\n round(\n sum by (templatename) (\n increase(\n django_http_responses_total_by_templatename_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n templatename!~\".*'health_check/index.html'.*|None\"\n }[1w]\n ) > 0\n )\n )\n)\n", + "datasource": { + "type": "prometheus", + "uid": "$datasource" + }, + "expr": "topk(10,\n round(\n sum by (namespace, job, templatename) (\n increase(\n django_http_responses_total_by_templatename_total{\n namespace=~\"$namespace\",\n job=~\"$job\",\n templatename!~\".*'health_check/index.html'.*|None\"\n }[1w]\n ) > 0\n )\n )\n)\n", "format": "table", - "instant": true, - "intervalFactor": 2, - "legendFormat": "", - "refId": "A" + "instant": true } ], - "timeFrom": null, - "timeShift": null, "title": "Top Templates (1w)", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true + }, + "indexByName": { + "job": 1, + "namespace": 0, + "templatename": 2 + }, + "renameByName": { + "job": "Job", + "namespace": "Namespace", + "templatename": "Template Name" + } + } + } + ], "type": "table" } ], - "refresh": "", - "rows": [ ], - "schemaVersion": 14, - "style": "dark", + "schemaVersion": 36, "tags": [ "django", "django-mixin" @@ -916,101 +1032,66 @@ "templating": { "list": [ { - "current": { - "text": "Prometheus", - "value": "Prometheus" - }, - "hide": 0, "label": "Data Source", "name": "datasource", - "options": [ ], "query": "prometheus", - "refresh": 1, - "regex": "", "type": "datasource" }, { - "allValue": null, - "current": { - "text": "", - "value": "" + "datasource": { + "type": "prometheus", + "uid": "${datasource}" }, - "datasource": "$datasource", - "hide": 0, "includeAll": false, "label": "Namespace", "multi": false, "name": "namespace", - "options": [ ], "query": "label_values(django_http_responses_total_by_status_view_method_total{}, namespace)", "refresh": 2, - "regex": "", "sort": 1, - "tagValuesQuery": "", - "tags": [ ], - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" }, { - "allValue": null, - "current": { }, - "datasource": "$datasource", - "hide": 0, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, "includeAll": false, "label": "Job", "multi": false, "name": "job", - "options": [ ], "query": "label_values(django_http_responses_total_by_status_view_method_total{namespace=~\"$namespace\"}, job)", "refresh": 2, - "regex": "", "sort": 1, - "tagValuesQuery": "", - "tags": [ ], - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" }, { - "allValue": null, - "current": { }, - "datasource": "$datasource", - "hide": 0, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, "includeAll": true, "label": "View", "multi": true, "name": "view", - "options": [ ], "query": "label_values(django_http_responses_total_by_status_view_method_total{namespace=~\"$namespace\", job=~\"$job\", view!~\"|health_check:health_check_home|prometheus-django-metrics\"}, view)", "refresh": 2, - "regex": "", "sort": 1, - "tagValuesQuery": "", - "tags": [ ], - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" }, { - "allValue": null, - "current": { }, - "datasource": "$datasource", - "hide": 0, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, "includeAll": true, "label": "Method", "multi": true, "name": "method", - "options": [ ], "query": "label_values(django_http_responses_total_by_status_view_method_total{namespace=~\"$namespace\", job=~\"$job\", view=~\"$view\"}, method)", "refresh": 2, - "regex": "", "sort": 1, - "tagValuesQuery": "", - "tags": [ ], - "tagsQuery": "", - "type": "query", - "useTags": false + "type": "query" } ] }, @@ -1018,33 +1099,7 @@ "from": "now-1h", "to": "now" }, - "timepicker": { - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ] - }, "timezone": "utc", "title": "Django / Requests / Overview", - "uid": "django-requests-jkwq", - "version": 0 + "uid": "django-requests-jkwq" } diff --git a/jsonnetfile.json b/jsonnetfile.json index 5d0a248..7ca7792 100644 --- a/jsonnetfile.json +++ b/jsonnetfile.json @@ -18,7 +18,24 @@ } }, "version": "main" + }, + { + "source": { + "git": { + "remote": "https://github.com/jsonnet-libs/docsonnet.git", + "subdir": "doc-util" + } + }, + "version": "master" + }, + { + "source": { + "git": { + "remote": "https://github.com/jsonnet-libs/xtd.git", + "subdir": "" + } + }, + "version": "master" } - ], - "legacyImports": false -} + ] +} \ No newline at end of file