mirror of https://github.com/grafana/grafana
Live: Improve the debug panel and add a devenv dashbaord (#83350)
parent
715ea44466
commit
d122af6b97
@ -0,0 +1,447 @@ |
||||
{ |
||||
"annotations": { |
||||
"list": [ |
||||
{ |
||||
"builtIn": 1, |
||||
"datasource": { |
||||
"type": "grafana", |
||||
"uid": "-- Grafana --" |
||||
}, |
||||
"enable": true, |
||||
"hide": true, |
||||
"iconColor": "rgba(0, 211, 255, 1)", |
||||
"name": "Annotations & Alerts", |
||||
"type": "dashboard" |
||||
} |
||||
] |
||||
}, |
||||
"editable": true, |
||||
"fiscalYearStartMonth": 0, |
||||
"graphTooltip": 0, |
||||
"id": 209, |
||||
"links": [], |
||||
"panels": [ |
||||
{ |
||||
"datasource": { |
||||
"type": "datasource", |
||||
"uid": "grafana" |
||||
}, |
||||
"gridPos": { |
||||
"h": 2, |
||||
"w": 24, |
||||
"x": 0, |
||||
"y": 0 |
||||
}, |
||||
"id": 9, |
||||
"options": { |
||||
"code": { |
||||
"language": "plaintext", |
||||
"showLineNumbers": false, |
||||
"showMiniMap": false |
||||
}, |
||||
"content": "## This dashboard requires alpha panels to be enabled!", |
||||
"mode": "markdown" |
||||
}, |
||||
"pluginVersion": "11.0.0-pre", |
||||
"type": "text" |
||||
}, |
||||
{ |
||||
"datasource": { |
||||
"type": "datasource", |
||||
"uid": "grafana" |
||||
}, |
||||
"gridPos": { |
||||
"h": 4, |
||||
"w": 15, |
||||
"x": 0, |
||||
"y": 2 |
||||
}, |
||||
"id": 2, |
||||
"options": { |
||||
"channel": { |
||||
"namespace": "devenv", |
||||
"path": "weather", |
||||
"scope": "stream" |
||||
}, |
||||
"display": "none", |
||||
"json": { |
||||
"hello": "world" |
||||
}, |
||||
"message": "weather,location=west,sensor=A temperature=82\nweather,location=east,sensor=A temperature=76", |
||||
"publish": "influx" |
||||
}, |
||||
"title": "Panel Title", |
||||
"type": "live" |
||||
}, |
||||
{ |
||||
"datasource": { |
||||
"type": "datasource", |
||||
"uid": "grafana" |
||||
}, |
||||
"fieldConfig": { |
||||
"defaults": { |
||||
"color": { |
||||
"mode": "thresholds" |
||||
}, |
||||
"custom": { |
||||
"align": "auto", |
||||
"cellOptions": { |
||||
"type": "auto" |
||||
}, |
||||
"inspect": false |
||||
}, |
||||
"mappings": [], |
||||
"thresholds": { |
||||
"mode": "absolute", |
||||
"steps": [ |
||||
{ |
||||
"color": "green", |
||||
"value": null |
||||
}, |
||||
{ |
||||
"color": "red", |
||||
"value": 80 |
||||
} |
||||
] |
||||
} |
||||
}, |
||||
"overrides": [] |
||||
}, |
||||
"gridPos": { |
||||
"h": 8, |
||||
"w": 9, |
||||
"x": 15, |
||||
"y": 2 |
||||
}, |
||||
"id": 4, |
||||
"options": { |
||||
"cellHeight": "sm", |
||||
"footer": { |
||||
"countRows": false, |
||||
"fields": "", |
||||
"reducer": [ |
||||
"sum" |
||||
], |
||||
"show": false |
||||
}, |
||||
"showHeader": true, |
||||
"sortBy": [] |
||||
}, |
||||
"pluginVersion": "11.0.0-pre", |
||||
"targets": [ |
||||
{ |
||||
"channel": "stream/devenv/weather", |
||||
"datasource": { |
||||
"type": "datasource", |
||||
"uid": "grafana" |
||||
}, |
||||
"queryType": "measurements", |
||||
"refId": "A" |
||||
} |
||||
], |
||||
"title": "Weather (values)", |
||||
"transformations": [ |
||||
{ |
||||
"id": "sortBy", |
||||
"options": { |
||||
"fields": {}, |
||||
"sort": [ |
||||
{ |
||||
"desc": true, |
||||
"field": "time" |
||||
} |
||||
] |
||||
} |
||||
} |
||||
], |
||||
"type": "table" |
||||
}, |
||||
{ |
||||
"datasource": { |
||||
"type": "datasource", |
||||
"uid": "grafana" |
||||
}, |
||||
"gridPos": { |
||||
"h": 4, |
||||
"w": 15, |
||||
"x": 0, |
||||
"y": 6 |
||||
}, |
||||
"id": 5, |
||||
"options": { |
||||
"channel": { |
||||
"namespace": "devenv", |
||||
"path": "weather", |
||||
"scope": "stream" |
||||
}, |
||||
"display": "none", |
||||
"json": { |
||||
"hello": "world" |
||||
}, |
||||
"message": "weather,location=west,sensor=A temperature=90\nweather,location=east,sensor=A temperature=80", |
||||
"publish": "influx" |
||||
}, |
||||
"title": "Panel Title", |
||||
"type": "live" |
||||
}, |
||||
{ |
||||
"datasource": { |
||||
"type": "datasource", |
||||
"uid": "grafana" |
||||
}, |
||||
"fieldConfig": { |
||||
"defaults": { |
||||
"color": { |
||||
"mode": "palette-classic" |
||||
}, |
||||
"custom": { |
||||
"axisBorderShow": false, |
||||
"axisCenteredZero": false, |
||||
"axisColorMode": "text", |
||||
"axisLabel": "", |
||||
"axisPlacement": "auto", |
||||
"barAlignment": 0, |
||||
"drawStyle": "line", |
||||
"fillOpacity": 0, |
||||
"gradientMode": "none", |
||||
"hideFrom": { |
||||
"legend": false, |
||||
"tooltip": false, |
||||
"viz": false |
||||
}, |
||||
"insertNulls": false, |
||||
"lineInterpolation": "linear", |
||||
"lineWidth": 1, |
||||
"pointSize": 5, |
||||
"scaleDistribution": { |
||||
"type": "linear" |
||||
}, |
||||
"showPoints": "auto", |
||||
"spanNulls": false, |
||||
"stacking": { |
||||
"group": "A", |
||||
"mode": "none" |
||||
}, |
||||
"thresholdsStyle": { |
||||
"mode": "off" |
||||
} |
||||
}, |
||||
"mappings": [], |
||||
"thresholds": { |
||||
"mode": "absolute", |
||||
"steps": [ |
||||
{ |
||||
"color": "green", |
||||
"value": null |
||||
}, |
||||
{ |
||||
"color": "red", |
||||
"value": 80 |
||||
} |
||||
] |
||||
} |
||||
}, |
||||
"overrides": [] |
||||
}, |
||||
"gridPos": { |
||||
"h": 7, |
||||
"w": 24, |
||||
"x": 0, |
||||
"y": 10 |
||||
}, |
||||
"id": 1, |
||||
"options": { |
||||
"legend": { |
||||
"calcs": [], |
||||
"displayMode": "list", |
||||
"placement": "bottom", |
||||
"showLegend": true |
||||
}, |
||||
"tooltip": { |
||||
"mode": "single", |
||||
"sort": "none" |
||||
} |
||||
}, |
||||
"targets": [ |
||||
{ |
||||
"channel": "stream/devenv/weather", |
||||
"datasource": { |
||||
"type": "datasource", |
||||
"uid": "grafana" |
||||
}, |
||||
"queryType": "measurements", |
||||
"refId": "A" |
||||
}, |
||||
{ |
||||
"channel": "stream/devenv/weatherX", |
||||
"datasource": { |
||||
"type": "datasource", |
||||
"uid": "grafana" |
||||
}, |
||||
"hide": false, |
||||
"queryType": "measurements", |
||||
"refId": "B" |
||||
} |
||||
], |
||||
"title": "Panel Title", |
||||
"type": "timeseries" |
||||
}, |
||||
{ |
||||
"datasource": { |
||||
"type": "datasource", |
||||
"uid": "grafana" |
||||
}, |
||||
"gridPos": { |
||||
"h": 4, |
||||
"w": 15, |
||||
"x": 0, |
||||
"y": 17 |
||||
}, |
||||
"id": 6, |
||||
"options": { |
||||
"channel": { |
||||
"namespace": "devenv", |
||||
"path": "weather", |
||||
"scope": "stream" |
||||
}, |
||||
"display": "none", |
||||
"json": { |
||||
"hello": "world" |
||||
}, |
||||
"message": "weatherX,location=west,sensor=X temperature=82\nweatherX,location=east,sensor=X temperature=76", |
||||
"publish": "influx" |
||||
}, |
||||
"title": "Panel Title", |
||||
"type": "live" |
||||
}, |
||||
{ |
||||
"datasource": { |
||||
"type": "datasource", |
||||
"uid": "grafana" |
||||
}, |
||||
"fieldConfig": { |
||||
"defaults": { |
||||
"color": { |
||||
"mode": "thresholds" |
||||
}, |
||||
"custom": { |
||||
"align": "auto", |
||||
"cellOptions": { |
||||
"type": "auto" |
||||
}, |
||||
"inspect": false |
||||
}, |
||||
"mappings": [], |
||||
"thresholds": { |
||||
"mode": "absolute", |
||||
"steps": [ |
||||
{ |
||||
"color": "green", |
||||
"value": null |
||||
}, |
||||
{ |
||||
"color": "red", |
||||
"value": 80 |
||||
} |
||||
] |
||||
} |
||||
}, |
||||
"overrides": [] |
||||
}, |
||||
"gridPos": { |
||||
"h": 8, |
||||
"w": 9, |
||||
"x": 15, |
||||
"y": 17 |
||||
}, |
||||
"id": 7, |
||||
"options": { |
||||
"cellHeight": "sm", |
||||
"footer": { |
||||
"countRows": false, |
||||
"fields": "", |
||||
"reducer": [ |
||||
"sum" |
||||
], |
||||
"show": false |
||||
}, |
||||
"showHeader": true, |
||||
"sortBy": [] |
||||
}, |
||||
"pluginVersion": "11.0.0-pre", |
||||
"targets": [ |
||||
{ |
||||
"channel": "stream/devenv/weatherX", |
||||
"datasource": { |
||||
"type": "datasource", |
||||
"uid": "grafana" |
||||
}, |
||||
"queryType": "measurements", |
||||
"refId": "A" |
||||
} |
||||
], |
||||
"title": "WeatherX (values)", |
||||
"transformations": [ |
||||
{ |
||||
"id": "sortBy", |
||||
"options": { |
||||
"fields": {}, |
||||
"sort": [ |
||||
{ |
||||
"desc": true, |
||||
"field": "time" |
||||
} |
||||
] |
||||
} |
||||
} |
||||
], |
||||
"type": "table" |
||||
}, |
||||
{ |
||||
"datasource": { |
||||
"type": "datasource", |
||||
"uid": "grafana" |
||||
}, |
||||
"gridPos": { |
||||
"h": 4, |
||||
"w": 15, |
||||
"x": 0, |
||||
"y": 21 |
||||
}, |
||||
"id": 8, |
||||
"options": { |
||||
"channel": { |
||||
"namespace": "devenv", |
||||
"path": "weather", |
||||
"scope": "stream" |
||||
}, |
||||
"display": "none", |
||||
"json": { |
||||
"hello": "world" |
||||
}, |
||||
"message": "weatherX,location=west,sensor=X temperature=90\nweatherX,location=east,sensor=X temperature=22", |
||||
"publish": "influx" |
||||
}, |
||||
"title": "Panel Title", |
||||
"type": "live" |
||||
} |
||||
], |
||||
"schemaVersion": 39, |
||||
"tags": [ |
||||
"gdev", |
||||
"live-tests" |
||||
], |
||||
"templating": { |
||||
"list": [] |
||||
}, |
||||
"time": { |
||||
"from": "now-1m", |
||||
"to": "now" |
||||
}, |
||||
"timepicker": {}, |
||||
"timezone": "browser", |
||||
"title": "live test", |
||||
"uid": "addoomtlivedev", |
||||
"version": 17, |
||||
"weekStart": "" |
||||
} |
@ -0,0 +1,44 @@ |
||||
import { SelectableValue, dataFrameFromJSON } from '@grafana/data'; |
||||
import { getBackendSrv } from '@grafana/runtime'; |
||||
|
||||
interface ChannelInfo { |
||||
channel: string; |
||||
minute_rate: number; //
|
||||
data: unknown; // the last payload
|
||||
} |
||||
|
||||
interface ManagedChannels { |
||||
channels: ChannelInfo[]; |
||||
} |
||||
|
||||
interface ChannelSelectionInfo { |
||||
channels: Array<SelectableValue<string>>; |
||||
channelFields: Record<string, Array<SelectableValue<string>>>; |
||||
} |
||||
|
||||
export async function getManagedChannelInfo(): Promise<ChannelSelectionInfo> { |
||||
return getBackendSrv() |
||||
.get<ManagedChannels>('api/live/list') |
||||
.then((v) => { |
||||
const channelInfo = v.channels ?? []; |
||||
const channelFields: Record<string, Array<SelectableValue<string>>> = {}; |
||||
const channels: Array<SelectableValue<string>> = channelInfo.map((c) => { |
||||
if (c.data) { |
||||
const distinctFields = new Set<string>(); |
||||
const frame = dataFrameFromJSON(c.data); |
||||
for (const f of frame.fields) { |
||||
distinctFields.add(f.name); |
||||
} |
||||
channelFields[c.channel] = Array.from(distinctFields).map((n) => ({ |
||||
value: n, |
||||
label: n, |
||||
})); |
||||
} |
||||
return { |
||||
value: c.channel, |
||||
label: c.channel + ' [' + c.minute_rate + ' msg/min]', |
||||
}; |
||||
}); |
||||
return { channelFields, channels }; |
||||
}); |
||||
} |
@ -0,0 +1,67 @@ |
||||
import React, { useMemo } from 'react'; |
||||
|
||||
import { LiveChannelAddress, isValidLiveChannelAddress } from '@grafana/data'; |
||||
import { getBackendSrv, getGrafanaLiveSrv } from '@grafana/runtime'; |
||||
import { CodeEditor, Button } from '@grafana/ui'; |
||||
|
||||
import { MessagePublishMode } from './types'; |
||||
|
||||
interface Props { |
||||
height: number; |
||||
addr?: LiveChannelAddress; |
||||
mode: MessagePublishMode; |
||||
body?: string | object; |
||||
onSave: (v: string | object) => void; |
||||
} |
||||
|
||||
export function LivePublish({ height, mode, body, addr, onSave }: Props) { |
||||
const txt = useMemo(() => { |
||||
if (mode === MessagePublishMode.JSON) { |
||||
return body ? JSON.stringify(body, null, 2) : '{ }'; |
||||
} |
||||
return body == null ? '' : `${body}`; |
||||
}, [mode, body]); |
||||
|
||||
const doSave = (v: string) => { |
||||
if (mode === MessagePublishMode.JSON) { |
||||
onSave(JSON.parse(v)); |
||||
} else { |
||||
onSave(v); |
||||
} |
||||
}; |
||||
|
||||
const onPublishClicked = async () => { |
||||
if (mode === MessagePublishMode.Influx) { |
||||
if (addr?.scope !== 'stream') { |
||||
alert('expected stream scope!'); |
||||
return; |
||||
} |
||||
return getBackendSrv().post(`api/live/push/${addr.namespace}`, body); |
||||
} |
||||
|
||||
if (!isValidLiveChannelAddress(addr)) { |
||||
alert('invalid address'); |
||||
return; |
||||
} |
||||
|
||||
const rsp = await getGrafanaLiveSrv().publish(addr, body); |
||||
console.log('onPublishClicked (response from publish)', rsp); |
||||
}; |
||||
|
||||
return ( |
||||
<> |
||||
<CodeEditor |
||||
height={height - 32} |
||||
language={mode === MessagePublishMode.JSON ? 'json' : 'text'} |
||||
value={txt} |
||||
onBlur={doSave} |
||||
onSave={doSave} |
||||
showMiniMap={false} |
||||
showLineNumbers={true} |
||||
/> |
||||
<div style={{ height: 32 }}> |
||||
<Button onClick={onPublishClicked}>Publish</Button> |
||||
</div> |
||||
</> |
||||
); |
||||
} |
Loading…
Reference in new issue