Debug panel: add a new alpha panel to help debugging (#32187)

This commit is contained in:
Ryan McKinley
2021-03-22 20:38:24 -07:00
committed by GitHub
parent 8c4cbd39aa
commit da987caa60
7 changed files with 174 additions and 0 deletions

View File

@@ -59,6 +59,7 @@ import * as barChartPanel from 'app/plugins/panel/barchart/module';
import * as logsPanel from 'app/plugins/panel/logs/module';
import * as newsPanel from 'app/plugins/panel/news/module';
import * as livePanel from 'app/plugins/panel/live/module';
import * as debugPanel from 'app/plugins/panel/debug/module';
import * as welcomeBanner from 'app/plugins/panel/welcome/module';
import * as nodeGraph from 'app/plugins/panel/nodeGraph/module';
@@ -96,6 +97,7 @@ const builtInPlugins: any = {
'app/plugins/panel/table-old/module': oldTablePanel,
'app/plugins/panel/news/module': newsPanel,
'app/plugins/panel/live/module': livePanel,
'app/plugins/panel/debug/module': debugPanel,
'app/plugins/panel/singlestat/module': singlestatPanel,
'app/plugins/panel/stat/module': singlestatPanel2,
'app/plugins/panel/gettingstarted/module': gettingStartedPanel,

View File

@@ -0,0 +1,109 @@
import React, { Component } from 'react';
import {
compareArrayValues,
compareDataFrameStructures,
fieldReducers,
getFieldDisplayName,
getFrameDisplayName,
PanelProps,
ReducerID,
} from '@grafana/data';
import { DebugPanelOptions, UpdateCounters, UpdateConfig } from './types';
import { IconButton } from '@grafana/ui';
type Props = PanelProps<DebugPanelOptions>;
export class DebugPanel extends Component<Props> {
// Intentionally not state to avoid overhead -- yes, things will be 1 tick behind
lastRender = Date.now();
counters: UpdateCounters = {
render: 0,
dataChanged: 0,
schemaChanged: 0,
};
shouldComponentUpdate(prevProps: Props) {
const { data, options } = this.props;
if (prevProps.data !== data) {
this.counters.dataChanged++;
if (options.counters?.schemaChanged) {
const oldSeries = prevProps.data?.series;
const series = data.series;
if (series && oldSeries) {
const sameStructure = compareArrayValues(series, oldSeries, compareDataFrameStructures);
if (!sameStructure) {
this.counters.schemaChanged++;
}
}
}
}
return true; // always render?
}
resetCounters = () => {
this.counters = {
render: 0,
dataChanged: 0,
schemaChanged: 0,
};
this.forceUpdate();
};
render() {
const { data, options } = this.props;
const showCounters = options.counters ?? ({} as UpdateConfig);
this.counters.render++;
const now = Date.now();
const elapsed = now - this.lastRender;
this.lastRender = now;
const reducer = fieldReducers.get(ReducerID.lastNotNull);
return (
<div>
<div>
<IconButton name="step-backward" title="reset counters" onClick={this.resetCounters} />
<span>
{showCounters.render && <span>Render: {this.counters.render}&nbsp;</span>}
{showCounters.dataChanged && <span>Data: {this.counters.dataChanged}&nbsp;</span>}
{showCounters.schemaChanged && <span>Schema: {this.counters.schemaChanged}&nbsp;</span>}
<span>TIME: {elapsed}ms</span>
</span>
</div>
{data.series &&
data.series.map((frame, idx) => (
<div key={`${idx}/${frame.refId}`}>
<h4>
{getFrameDisplayName(frame, idx)} ({frame.length})
</h4>
<table className="filter-table">
<thead>
<tr>
<td>Field</td>
<td>Type</td>
<td>Last</td>
</tr>
</thead>
<tbody>
{frame.fields.map((field, idx) => {
const v = reducer.reduce!(field, false, false)[reducer.id];
return (
<tr key={`${idx}/${field.name}`}>
<td>{getFieldDisplayName(field, frame, data.series)}</td>
<td>{field.type}</td>
<td>{`${v}`}</td>
</tr>
);
})}
</tbody>
</table>
</div>
))}
</div>
);
}
}

View File

@@ -0,0 +1,5 @@
# Debug Panel - Native Plugin
The Debug Panel is **included** with Grafana.
This panel shows render information helpful in debugging query execution and panel rendering performace.

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 50 50">
<defs><style>.cls-1{fill:#84aff1;}.cls-2{fill:url(#linear-gradient);}.cls-3{fill:#3865ab;}</style><linearGradient id="linear-gradient" y1="40.18" x2="82.99" y2="40.18" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f2cc0c"/><stop offset="1" stop-color="#ff9830"/></linearGradient></defs>
<path class="cls-3" d="M 25 3 C 22.635 3 20.56675 4.3915 19.59375 6.4375 C 21.19975 6.1145 22.996 5.9375 25 5.9375 C 27.006 5.9375 28.80025 6.1135 30.40625 6.4375 C 29.43725 4.3895 27.375 3 25 3 z M 25 7.9375 C 19.195 7.9375 12.9375 9.467 12.9375 15 C 12.9375 16.195 13.10125 17.219 13.40625 18.125 C 14.20925 18.204 15.03225 18.44875 16.03125 18.71875 C 17.93625 19.23375 20.821 20 25 20 C 28.805 20 31.525 19.422 33.5 19 C 34.647 18.755 35.57775 18.57225 36.46875 18.53125 C 36.87075 17.54025 37.0625 16.369 37.0625 15 C 37.0625 9.467 30.806 7.9375 25 7.9375 z M 3 8 C 2.448 8 2 8.448 2 9 C 2 14.77 3.31225 18.91575 5.90625 21.34375 C 7.4513986 22.789473 9.0884409 23.263838 10.09375 23.40625 C 10.007056 24.472235 10 25.77184 10 27.46875 C 10 27.634529 10.027237 27.80253 10.03125 27.96875 L 2 27.96875 C 1.438 27.96875 0.96875 28.437 0.96875 29 C 0.96875 29.563 1.438 30.03125 2 30.03125 L 10.15625 30.03125 C 10.37691 31.828572 10.852489 33.618858 11.53125 35.3125 C 9.0007528 35.916254 2 38.249346 2 46 C 2 46.553 2.448 47 3 47 C 3.552 47 4 46.553 4 46 C 4 39.125407 10.758973 37.430153 12.375 37.125 C 14.65344 41.474987 18.542804 44.937286 24 45.84375 L 24 29 C 24 28.447 24.448 28 25 28 C 25.552 28 26 28.447 26 29 L 26 45.84375 C 31.45746 44.937243 35.377858 41.506535 37.65625 37.15625 C 39.364052 37.487974 46 39.198801 46 46 C 46 46.553 46.447 47 47 47 C 47.553 47 48 46.553 48 46 C 48 38.249346 40.998923 35.916254 38.46875 35.3125 C 39.147511 33.618858 39.62309 31.828572 39.84375 30.03125 L 48 30.03125 C 48.563 30.03125 49.03125 29.563 49.03125 29 C 49.03125 28.437 48.563 27.96875 48 27.96875 L 39.96875 27.96875 C 39.972763 27.80253 40 27.634529 40 27.46875 C 40 25.808538 39.991566 24.475887 39.84375 23.40625 C 40.843781 23.272891 42.52025 22.816 44.09375 21.34375 C 46.68775 18.91575 48 14.77 48 9 C 48 8.448 47.553 8 47 8 C 46.86175 8 46.744672 8.043125 46.625 8.09375 C 46.505328 8.144375 46.371688 8.19075 46.28125 8.28125 C 46.100375 8.46225 46 8.724 46 9 C 46 14.086 44.89725 17.82875 42.78125 19.84375 C 41.462 21.1 40.081469 21.377406 39.4375 21.4375 C 39.293902 21.4509 39.250366 21.468597 39.1875 21.46875 C 38.71658 20.836342 37.960771 20.5 36.78125 20.5 C 36.00025 20.5 35.08625 20.71675 33.90625 20.96875 C 31.84425 21.40775 29.015 22 25 22 C 20.554 22 17.507 21.168 15.5 20.625 C 14.35 20.313 13.5455 20.09375 12.8125 20.09375 C 11.559536 20.09375 10.851243 20.484552 10.46875 21.40625 C 9.8093998 21.331293 8.5345958 21.07908 7.28125 19.90625 C 5.13825 17.90025 4 14.121 4 9 C 4 8.448 3.552 8 3 8 z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,22 @@
import { PanelPlugin } from '@grafana/data';
import { DebugPanel } from './DebugPanel';
import { DebugPanelOptions } from './types';
export const plugin = new PanelPlugin<DebugPanelOptions>(DebugPanel).useFieldConfig().setPanelOptions((builder) => {
builder
.addBooleanSwitch({
path: 'counters.render',
name: 'Render Count',
defaultValue: true,
})
.addBooleanSwitch({
path: 'counters.dataChanged',
name: 'Data Changed Count',
defaultValue: true,
})
.addBooleanSwitch({
path: 'counters.schemaChanged',
name: 'Schema Changed Count',
defaultValue: true,
});
});

View File

@@ -0,0 +1,18 @@
{
"type": "panel",
"name": "Debug",
"id": "debug",
"state": "alpha",
"info": {
"description": "Debug Panel for Grafana",
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
},
"logos": {
"small": "img/icn-debug.svg",
"large": "img/icn-debug.svg"
}
}
}

View File

@@ -0,0 +1,13 @@
export type UpdateConfig = {
[K in keyof UpdateCounters]: boolean;
};
export type UpdateCounters = {
render: number;
dataChanged: number;
schemaChanged: number;
};
export interface DebugPanelOptions {
counters?: UpdateConfig;
}