diff --git a/CHANGELOG.md b/CHANGELOG.md index cc8d05814..8d3b2c66e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ NOTE: As semantic versioning states all 0.y.z releases can contain breaking chan ### Changed +- [#46](https://github.com/kobsio/kobs/pull/46): Support multiple types for the legend in a Prometheus chart and use a custom component to render the legend. + ## [v0.2.0](https://github.com/kobsio/kobs/releases/tag/v0.2.0) (2021-04-23) ### Added diff --git a/app/src/plugins/prometheus/PrometheusAutocomplete.tsx b/app/src/plugins/prometheus/PrometheusAutocomplete.tsx index e1be416e8..5920f7ee5 100644 --- a/app/src/plugins/prometheus/PrometheusAutocomplete.tsx +++ b/app/src/plugins/prometheus/PrometheusAutocomplete.tsx @@ -22,7 +22,7 @@ export const PrometheusAutocomplete: React.FunctionComponent { +}: IPrometheusAutocomplete) => { const inputRef = useRef(null); const [data, setData] = useState([]); const [inputFocused, setInputFocused] = useState(false); diff --git a/app/src/plugins/prometheus/PrometheusChartDefault.tsx b/app/src/plugins/prometheus/PrometheusChartDefault.tsx index bfde835c4..58151982b 100644 --- a/app/src/plugins/prometheus/PrometheusChartDefault.tsx +++ b/app/src/plugins/prometheus/PrometheusChartDefault.tsx @@ -14,6 +14,7 @@ import React, { useEffect, useRef, useState } from 'react'; import { Data, Metrics } from 'proto/prometheus_grpc_web_pb'; import { IData, transformData } from 'plugins/prometheus/helpers'; +import PrometheusChartDefaultLegend from 'plugins/prometheus/PrometheusChartDefaultLegend'; import { formatTime } from 'utils/helpers'; interface ILabels { @@ -24,7 +25,7 @@ export interface IPrometheusChartDefaultProps { type: string; unit: string; stacked: boolean; - disableLegend?: boolean; + legend: string; metrics: Metrics.AsObject[]; } @@ -42,12 +43,25 @@ const PrometheusChartDefault: React.FunctionComponent { const refChart = useRef(null); const [width, setWidth] = useState(0); const [height, setHeight] = useState(0); + const [hiddenMetrics, setHiddenMetrics] = useState([]); + + const toogleMetric = (index: string): void => { + let tmpHiddenMetrics = [...hiddenMetrics]; + + if (tmpHiddenMetrics.includes(index)) { + tmpHiddenMetrics = tmpHiddenMetrics.filter((f) => f !== index); + } else { + tmpHiddenMetrics.push(index); + } + + setHiddenMetrics(tmpHiddenMetrics); + }; // useEffect is executed on every render of this component. This is needed, so that we are able to use a width of 100% // and a static height for the chart. @@ -64,45 +78,70 @@ const PrometheusChartDefault: React.FunctionComponent ({ childName: `index${index}`, name: metric.label })); const series = metrics.map((metric, index) => type === 'area' ? ( - + ) : type === 'bar' ? ( - + ) : ( - + ), ); return ( -
- (datum.y ? `${datum.y} ${unit}` : 'N/A')} - labelComponent={ - formatTime(Math.floor(point.x / 1000))} - /> - } - mouseFollowTooltips - voronoiDimension="x" - voronoiPadding={0} - /> - } - height={height} - legendData={legendData} - legendPosition={disableLegend ? undefined : 'bottom'} - padding={{ bottom: disableLegend ? 0 : 60, left: 60, right: 0, top: 0 }} - scale={{ x: 'time', y: 'linear' }} - themeColor={ChartThemeColor.multiOrdered} - width={width} + +
- - - {stacked ? {series} : {series}} - -
+ (datum.y ? `${datum.y} ${unit}` : null)} + labelComponent={ + formatTime(Math.floor(point.x / 1000))} + /> + } + mouseFollowTooltips + voronoiDimension="x" + voronoiPadding={{ bottom: 30, left: 60, right: 0, top: 0 }} + /> + } + height={height} + legendPosition={undefined} + padding={{ bottom: 30, left: 60, right: 0, top: 0 }} + scale={{ x: 'time', y: 'linear' }} + themeColor={ChartThemeColor.multiOrdered} + width={width} + > + + + {stacked ? {series} : {series}} + +
+ + ); }; diff --git a/app/src/plugins/prometheus/PrometheusChartDefaultLegend.tsx b/app/src/plugins/prometheus/PrometheusChartDefaultLegend.tsx new file mode 100644 index 000000000..95d8dde52 --- /dev/null +++ b/app/src/plugins/prometheus/PrometheusChartDefaultLegend.tsx @@ -0,0 +1,123 @@ +import { Button, ButtonVariant } from '@patternfly/react-core'; +import { ChartThemeColor, getDarkThemeColors } from '@patternfly/react-charts'; +import { EyeSlashIcon, SquareIcon } from '@patternfly/react-icons'; +import { TableComposable, TableVariant, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table'; +import React from 'react'; + +import { Metrics } from 'proto/prometheus_grpc_web_pb'; + +// colors is an array with all the supported colors for a chart. These are the same colors as they are used for the +// bars, lines, areas in a chart. +export const colors = getDarkThemeColors(ChartThemeColor.multiOrdered).area.colorScale; + +// getLegendColorClass returns the color class for an item in the legend. When we have more series then colors, we start +// again with the first color. +const getLegendColorClass = (index: number): string => { + return colors[index % colors.length]; +}; + +interface ILegendItem { + childName: string; + name: string; +} + +export interface IPrometheusChartDefaultLegendProps { + legend: string; + legendData: ILegendItem[]; + metrics: Metrics.AsObject[]; + hiddenMetrics: string[]; + toogleMetric: (index: string) => void; +} + +// +const PrometheusChartDefaultLegend: React.FunctionComponent = ({ + legend, + legendData, + metrics, + hiddenMetrics, + toogleMetric, +}: IPrometheusChartDefaultLegendProps) => { + if (legend === 'disabled') { + return null; + } + + if (legend === 'table') { + return ( +
+ + + + Name + Min + Max + Avg + Current + + + + {legendData.map((legend, index) => ( + + + + + + {metrics[index].min} + + + {metrics[index].max} + + + {metrics[index].avg} + + + {metrics[index].dataList[metrics[index].dataList.length - 1].y} + + + ))} + + +
+ ); + } + + return ( +
+ {legendData.map((legend, index) => ( + + ))} +
+ ); +}; + +export default PrometheusChartDefaultLegend; diff --git a/app/src/plugins/prometheus/PrometheusPageData.tsx b/app/src/plugins/prometheus/PrometheusPageData.tsx index 7c0261656..4395ddcf0 100644 --- a/app/src/plugins/prometheus/PrometheusPageData.tsx +++ b/app/src/plugins/prometheus/PrometheusPageData.tsx @@ -68,7 +68,7 @@ const PrometheusPageData: React.FunctionComponent = ({ type={type} unit="" stacked={stacked} - disableLegend={true} + legend="disabled" metrics={selectedMetrics.length === 0 ? metrics : selectedMetrics} /> diff --git a/app/src/plugins/prometheus/PrometheusPluginChart.tsx b/app/src/plugins/prometheus/PrometheusPluginChart.tsx index e63c5077e..67a805b1f 100644 --- a/app/src/plugins/prometheus/PrometheusPluginChart.tsx +++ b/app/src/plugins/prometheus/PrometheusPluginChart.tsx @@ -135,7 +135,13 @@ const PrometheusPluginChart: React.FunctionComponent ) : ( - + )} diff --git a/app/src/plugins/prometheus/helpers.ts b/app/src/plugins/prometheus/helpers.ts index 90a290974..47154ae33 100644 --- a/app/src/plugins/prometheus/helpers.ts +++ b/app/src/plugins/prometheus/helpers.ts @@ -115,8 +115,8 @@ export interface IData { // transformData is used to transform the returned data from the API. This is needed because, the API returns a NaN // value for missing values, but Victory requires a null value. // See: https://formidable.com/open-source/victory/gallery/victory-line-with-null-data/ -export const transformData = (data: Data.AsObject[]): IData[] => { +export const transformData = (data: Data.AsObject[], isHidden?: boolean): IData[] => { return data.map((d) => { - return { x: d.x, y: isNaN(d.y) ? null : d.y }; + return { x: d.x, y: isNaN(d.y) || isHidden ? null : d.y }; }); }; diff --git a/app/src/proto/prometheus_pb.d.ts b/app/src/proto/prometheus_pb.d.ts index d70a763b6..f9b72a9e8 100644 --- a/app/src/proto/prometheus_pb.d.ts +++ b/app/src/proto/prometheus_pb.d.ts @@ -329,6 +329,9 @@ export class Chart extends jspb.Message { getSize(): number; setSize(value: number): void; + getLegend(): string; + setLegend(value: string): void; + getMappingsMap(): jspb.Map; clearMappingsMap(): void; clearQueriesList(): void; @@ -353,6 +356,7 @@ export namespace Chart { unit: string, stacked: boolean, size: number, + legend: string, mappingsMap: Array<[string, string]>, queriesList: Array, } diff --git a/app/src/proto/prometheus_pb.js b/app/src/proto/prometheus_pb.js index f322275eb..659ea115d 100644 --- a/app/src/proto/prometheus_pb.js +++ b/app/src/proto/prometheus_pb.js @@ -2541,7 +2541,7 @@ proto.plugins.prometheus.Variable.prototype.setValue = function(value) { * @private {!Array} * @const */ -proto.plugins.prometheus.Chart.repeatedFields_ = [7]; +proto.plugins.prometheus.Chart.repeatedFields_ = [8]; @@ -2579,6 +2579,7 @@ proto.plugins.prometheus.Chart.toObject = function(includeInstance, msg) { unit: jspb.Message.getFieldWithDefault(msg, 3, ""), stacked: jspb.Message.getBooleanFieldWithDefault(msg, 4, false), size: jspb.Message.getFieldWithDefault(msg, 5, 0), + legend: jspb.Message.getFieldWithDefault(msg, 6, ""), mappingsMap: (f = msg.getMappingsMap()) ? f.toObject(includeInstance, undefined) : [], queriesList: jspb.Message.toObjectList(msg.getQueriesList(), proto.plugins.prometheus.Query.toObject, includeInstance) @@ -2639,12 +2640,16 @@ proto.plugins.prometheus.Chart.deserializeBinaryFromReader = function(msg, reade msg.setSize(value); break; case 6: + var value = /** @type {string} */ (reader.readString()); + msg.setLegend(value); + break; + case 7: var value = msg.getMappingsMap(); reader.readMessage(value, function(message, reader) { jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readString, null, "", ""); }); break; - case 7: + case 8: var value = new proto.plugins.prometheus.Query; reader.readMessage(value,proto.plugins.prometheus.Query.deserializeBinaryFromReader); msg.addQueries(value); @@ -2713,14 +2718,21 @@ proto.plugins.prometheus.Chart.serializeBinaryToWriter = function(message, write f ); } + f = message.getLegend(); + if (f.length > 0) { + writer.writeString( + 6, + f + ); + } f = message.getMappingsMap(true); if (f && f.getLength() > 0) { - f.serializeBinary(6, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeString); + f.serializeBinary(7, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeString); } f = message.getQueriesList(); if (f.length > 0) { writer.writeRepeatedMessage( - 7, + 8, f, proto.plugins.prometheus.Query.serializeBinaryToWriter ); @@ -2819,14 +2831,32 @@ proto.plugins.prometheus.Chart.prototype.setSize = function(value) { /** - * map mappings = 6; + * optional string legend = 6; + * @return {string} + */ +proto.plugins.prometheus.Chart.prototype.getLegend = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, "")); +}; + + +/** + * @param {string} value + * @return {!proto.plugins.prometheus.Chart} returns this + */ +proto.plugins.prometheus.Chart.prototype.setLegend = function(value) { + return jspb.Message.setProto3StringField(this, 6, value); +}; + + +/** + * map mappings = 7; * @param {boolean=} opt_noLazyCreate Do not create the map if * empty, instead returning `undefined` * @return {!jspb.Map} */ proto.plugins.prometheus.Chart.prototype.getMappingsMap = function(opt_noLazyCreate) { return /** @type {!jspb.Map} */ ( - jspb.Message.getMapField(this, 6, opt_noLazyCreate, + jspb.Message.getMapField(this, 7, opt_noLazyCreate, null)); }; @@ -2841,12 +2871,12 @@ proto.plugins.prometheus.Chart.prototype.clearMappingsMap = function() { /** - * repeated Query queries = 7; + * repeated Query queries = 8; * @return {!Array} */ proto.plugins.prometheus.Chart.prototype.getQueriesList = function() { return /** @type{!Array} */ ( - jspb.Message.getRepeatedWrapperField(this, proto.plugins.prometheus.Query, 7)); + jspb.Message.getRepeatedWrapperField(this, proto.plugins.prometheus.Query, 8)); }; @@ -2855,7 +2885,7 @@ proto.plugins.prometheus.Chart.prototype.getQueriesList = function() { * @return {!proto.plugins.prometheus.Chart} returns this */ proto.plugins.prometheus.Chart.prototype.setQueriesList = function(value) { - return jspb.Message.setRepeatedWrapperField(this, 7, value); + return jspb.Message.setRepeatedWrapperField(this, 8, value); }; @@ -2865,7 +2895,7 @@ proto.plugins.prometheus.Chart.prototype.setQueriesList = function(value) { * @return {!proto.plugins.prometheus.Query} */ proto.plugins.prometheus.Chart.prototype.addQueries = function(opt_value, opt_index) { - return jspb.Message.addToRepeatedWrapperField(this, 7, opt_value, proto.plugins.prometheus.Query, opt_index); + return jspb.Message.addToRepeatedWrapperField(this, 8, opt_value, proto.plugins.prometheus.Query, opt_index); }; diff --git a/deploy/helm/kobs/Chart.yaml b/deploy/helm/kobs/Chart.yaml index e5059375f..5961eb217 100644 --- a/deploy/helm/kobs/Chart.yaml +++ b/deploy/helm/kobs/Chart.yaml @@ -4,5 +4,5 @@ description: Kubernetes Observability Platform type: application home: https://kobs.io icon: https://kobs.io/assets/images/logo.svg -version: 0.3.2 +version: 0.3.3 appVersion: v0.2.0 diff --git a/deploy/helm/kobs/templates/customresourcedefinition.yaml b/deploy/helm/kobs/templates/customresourcedefinition.yaml index 24d4d0dbc..59db01209 100644 --- a/deploy/helm/kobs/templates/customresourcedefinition.yaml +++ b/deploy/helm/kobs/templates/customresourcedefinition.yaml @@ -177,6 +177,8 @@ spec: are executed against the datasource (e.g. For Prometheus this will be a list of PromQL queries). properties: + legend: + type: string mappings: additionalProperties: type: string @@ -336,6 +338,8 @@ spec: datasource (e.g. For Prometheus this will be a list of PromQL queries). properties: + legend: + type: string mappings: additionalProperties: type: string diff --git a/deploy/kustomize/crds/kobs.io_applications.yaml b/deploy/kustomize/crds/kobs.io_applications.yaml index fab9619d5..bf11ee185 100644 --- a/deploy/kustomize/crds/kobs.io_applications.yaml +++ b/deploy/kustomize/crds/kobs.io_applications.yaml @@ -177,6 +177,8 @@ spec: are executed against the datasource (e.g. For Prometheus this will be a list of PromQL queries). properties: + legend: + type: string mappings: additionalProperties: type: string @@ -336,6 +338,8 @@ spec: datasource (e.g. For Prometheus this will be a list of PromQL queries). properties: + legend: + type: string mappings: additionalProperties: type: string diff --git a/docs/plugins/prometheus.md b/docs/plugins/prometheus.md index e80d754b9..a637c17b2 100644 --- a/docs/plugins/prometheus.md +++ b/docs/plugins/prometheus.md @@ -33,6 +33,7 @@ The following specification can be used, within an application. | unit | string | An optional unit for the y axis of the chart. | No | | stacked | boolean | When this is `true` all time series in the chart will be stacked. | No | | size | number | An optional size for the chart. Must be a number between `1` and `12`. This is used to customize the grid of charts in the Prometheus tab. | No | +| legend | string | The type which should be used for the legend. Must be `bottom`, `table` or `disabled`. The default is `bottom` | No | | mappings | map | Specify value mappings for your data. **Note:** The value must be provided as string (e.g. `"1": "Green"`). | No | | queries | [[]Query](#query) | A list of queries, which are used to get the data for the chart. | Yes | diff --git a/pkg/api/plugins/prometheus/proto/prometheus.pb.go b/pkg/api/plugins/prometheus/proto/prometheus.pb.go index 0c7716cef..24c9a0dcf 100644 --- a/pkg/api/plugins/prometheus/proto/prometheus.pb.go +++ b/pkg/api/plugins/prometheus/proto/prometheus.pb.go @@ -707,8 +707,9 @@ type Chart struct { Unit string `protobuf:"bytes,3,opt,name=unit,proto3" json:"unit,omitempty"` Stacked bool `protobuf:"varint,4,opt,name=stacked,proto3" json:"stacked,omitempty"` Size int64 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"` - Mappings map[string]string `protobuf:"bytes,6,rep,name=mappings,proto3" json:"mappings,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - Queries []*Query `protobuf:"bytes,7,rep,name=queries,proto3" json:"queries,omitempty"` + Legend string `protobuf:"bytes,6,opt,name=legend,proto3" json:"legend,omitempty"` + Mappings map[string]string `protobuf:"bytes,7,rep,name=mappings,proto3" json:"mappings,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Queries []*Query `protobuf:"bytes,8,rep,name=queries,proto3" json:"queries,omitempty"` } func (x *Chart) Reset() { @@ -778,6 +779,13 @@ func (x *Chart) GetSize() int64 { return 0 } +func (x *Chart) GetLegend() string { + if x != nil { + return x.Legend + } + return "" +} + func (x *Chart) GetMappings() map[string]string { if x != nil { return x.Mappings @@ -930,53 +938,54 @@ var file_prometheus_proto_rawDesc = []byte{ 0x08, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x41, 0x6c, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xaa, 0x02, 0x0a, 0x05, 0x43, 0x68, 0x61, 0x72, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc2, 0x02, 0x0a, 0x05, 0x43, 0x68, 0x61, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x43, 0x0a, - 0x08, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x27, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, - 0x68, 0x65, 0x75, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x2e, 0x4d, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x73, 0x12, 0x33, 0x0a, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x07, - 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x61, 0x70, 0x70, 0x69, - 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0x33, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x32, 0xb5, 0x02, 0x0a, 0x0a, 0x50, 0x72, - 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x12, 0x63, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x56, - 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x27, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x47, 0x65, - 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x6d, - 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, - 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x25, 0x2e, 0x70, 0x6c, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, + 0x65, 0x67, 0x65, 0x6e, 0x64, 0x12, 0x43, 0x0a, 0x08, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, + 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x43, 0x68, 0x61, + 0x72, 0x74, 0x2e, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x08, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x33, 0x0a, 0x07, 0x71, 0x75, + 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, - 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x0c, - 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x12, 0x27, 0x2e, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, - 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6b, 0x6f, 0x62, 0x73, 0x69, 0x6f, 0x2f, 0x6b, 0x6f, 0x62, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x6d, - 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x1a, + 0x3b, 0x0a, 0x0d, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x33, 0x0a, 0x05, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x32, 0xb5, 0x02, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, + 0x12, 0x63, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x12, 0x27, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, + 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x47, + 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x73, 0x12, 0x25, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, + 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4c, 0x6f, + 0x6f, 0x6b, 0x75, 0x70, 0x12, 0x27, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, + 0x75, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x6f, 0x62, 0x73, 0x69, 0x6f, 0x2f, 0x6b, + 0x6f, 0x62, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/prometheus.proto b/proto/prometheus.proto index 14697ed4b..287551f1f 100644 --- a/proto/prometheus.proto +++ b/proto/prometheus.proto @@ -104,8 +104,9 @@ message Chart { string unit = 3; bool stacked = 4; int64 size = 5; - map mappings = 6; - repeated Query queries = 7; + string legend = 6; + map mappings = 7; + repeated Query queries = 8; } // Query presents a single query to get the data, which should be shown in the chart for the metrics section. A query