add labels for percentile metrics

This commit is contained in:
Qiuxia Fan 2022-03-13 15:49:54 +08:00
parent 30941d6a9d
commit 592fb8220f
10 changed files with 349 additions and 229 deletions

View File

@ -45,8 +45,6 @@ export const All = {
metrics: ["all_percentile"], metrics: ["all_percentile"],
metricTypes: ["readLabeledMetricsValues"], metricTypes: ["readLabeledMetricsValues"],
type: "Widget", type: "Widget",
metricLabels: "P50, P75, P90, P95, P99",
labelsIndex: "0, 1, 2, 3, 4",
widget: { widget: {
title: "Global Response Latency", title: "Global Response Latency",
tips: "Tooltip", tips: "Tooltip",
@ -56,6 +54,8 @@ export const All = {
}, },
standard: { standard: {
unit: "percentile in ms", unit: "percentile in ms",
metricLabels: "P50, P75, P90, P95, P99",
labelsIndex: "0, 1, 2, 3, 4",
}, },
}, },
{ {
@ -82,217 +82,274 @@ export const All = {
}, },
}; };
export const Service = { export const ServiceLayout = {
id: "1", id: "1",
configuration: { configuration: {
name: "Service", name: "Service",
isRoot: true, isRoot: true,
children: [ children: [
{ {
w: 8, x: 0,
h: 12, y: 0,
w: 24,
h: 36,
i: "0", i: "0",
metrics: ["service_apdex"], type: "Tab",
metricTypes: ["readMetricsValue"],
type: "Widget",
widget: { widget: {
title: "Service Apdex", title: "Title",
tips: "Tooltip",
},
graph: {
type: "Card",
},
standard: {
aggregation: "/",
aggregationNum: "10000",
},
},
{
w: 8,
h: 12,
i: "1",
metrics: ["service_sla"],
metricTypes: ["readMetricsValue"],
type: "Widget",
widget: {
title: "Successful Rate",
tips: "Tooltip",
},
graph: {
type: "Card",
},
standard: {
unit: "%",
aggregation: "/",
aggregationNum: "100",
},
},
{
w: 8,
h: 12,
i: "2",
metrics: ["service_cpm"],
metricTypes: ["readMetricsValue"],
type: "Widget",
widget: {
title: "Service Load",
tips: "For HTTP 1/2, gRPC, RPC services, this means Calls Per Minute (CPM), for TCP services, this means Packets Per Minute (PPM)",
},
graph: {
type: "Card",
},
standard: {
unit: "CPM / PPM",
aggregation: "/",
aggregationNum: "100",
},
},
{
w: 8,
h: 12,
i: "3",
metrics: ["service_cpm"],
metricTypes: ["readMetricsValues"],
type: "Widget",
widget: {
title: "Service cpm",
tips: "For HTTP 1/2, gRPC, RPC services, this means Calls Per Minute (CPM), for TCP services, this means Packets Per Minute (PPM)",
},
graph: {
type: "Card",
},
standard: {
unit: "CPM / PPM",
aggregation: "/",
aggregationNum: "100",
},
},
{
w: 8,
h: 12,
i: "4",
metrics: ["service_resp_time"],
metricTypes: ["readMetricsValues"],
type: "Widget",
widget: {
title: "Service Avg Response Time",
},
graph: {
type: "Line",
},
standard: {
unit: "ms",
},
},
{
w: 8,
h: 12,
i: "5",
metrics: ["service_apdex"],
metricTypes: ["readMetricsValues"],
type: "Widget",
widget: {
title: "Service Apdex",
},
graph: {
type: "Line",
},
standard: {
aggregation: "/",
aggregationNum: "10000",
},
},
{
w: 8,
h: 12,
i: "6",
metrics: ["service_percentile"],
metricTypes: ["readLabeledMetricsValues"],
type: "Widget",
metricLabels: "P50, P75, P90, P95, P99",
labelsIndex: "0, 1, 2, 3, 4",
widget: {
title: "Service Response Time Percentile",
},
graph: {
type: "Line",
},
standard: {
unit: "ms",
},
},
{
w: 8,
h: 12,
i: "7",
metrics: ["service_sla"],
metricTypes: ["readMetricsValues"],
type: "Widget",
widget: {
title: "Successful Rate",
},
graph: {
type: "Line",
},
standard: {
unit: "%",
aggregation: "/",
aggregationNum: "100",
},
},
{
w: 8,
h: 12,
i: "8",
metrics: ["service_throughput_received", "service_throughput_sent"],
metricTypes: ["readMetricsValues", "readMetricsValues"],
type: "Widget",
widget: {
title: "Service Throughput",
},
graph: {
type: "Line",
},
standard: {
unit: "Bytes",
tips: "This metrics is only avaible for TCP services",
},
},
{
w: 8,
h: 12,
i: "9",
metrics: ["service_mq_consume_count"],
metricTypes: ["readMetricsValues"],
type: "Widget",
widget: {
title: "Message Queue Consuming Count",
},
graph: {
type: "Line",
},
standard: {
tips: "The number of consumed messages.",
},
},
{
w: 8,
h: 12,
i: "10",
metrics: ["service_mq_consume_latency"],
metricTypes: ["readMetricsValues"],
type: "Widget",
widget: {
title: "Message Queue Consuming Count",
},
graph: {
type: "Line",
},
standard: {
unit: "ms",
tips: "The avg latency of message consuming. Latency = timestamp(received) - timestamp(producing)",
}, },
graph: {},
standard: {},
metrics: [""],
metricTypes: [""],
children: [
{
name: "Overview",
children: [
{
x: 0,
y: 0,
w: 8,
h: 12,
i: "6",
metrics: ["service_percentile"],
metricTypes: ["readLabeledMetricsValues"],
type: "Widget",
widget: {
title: "Service Response Time Percentile",
},
graph: {
type: "Line",
},
standard: {
unit: "ms",
metricLabels: "P50, P75, P90, P95, P99",
labelsIndex: "0, 1, 2, 3, 4",
},
},
],
},
{
name: "Trace",
children: [],
},
],
}, },
], ],
}, },
}; };
// export const ServiceLayout = {
// id: "1",
// configuration: {
// name: "Service",
// isRoot: true,
// children: [
// {
// w: 8,
// h: 12,
// i: "0",
// metrics: ["service_apdex"],
// metricTypes: ["readMetricsValue"],
// type: "Widget",
// widget: {
// title: "Service Apdex",
// tips: "Tooltip",
// },
// graph: {
// type: "Card",
// },
// standard: {
// aggregation: "/",
// aggregationNum: "10000",
// },
// },
// {
// w: 8,
// h: 12,
// i: "1",
// metrics: ["service_sla"],
// metricTypes: ["readMetricsValue"],
// type: "Widget",
// widget: {
// title: "Successful Rate",
// tips: "Tooltip",
// },
// graph: {
// type: "Card",
// },
// standard: {
// unit: "%",
// aggregation: "/",
// aggregationNum: "100",
// },
// },
// {
// w: 8,
// h: 12,
// i: "2",
// metrics: ["service_cpm"],
// metricTypes: ["readMetricsValue"],
// type: "Widget",
// widget: {
// title: "Service Load",
// tips: "For HTTP 1/2, gRPC, RPC services, this means Calls Per Minute (CPM), for TCP services, this means Packets Per Minute (PPM)",
// },
// graph: {
// type: "Card",
// },
// standard: {
// unit: "CPM / PPM",
// aggregation: "/",
// aggregationNum: "100",
// },
// },
// {
// w: 8,
// h: 12,
// i: "3",
// metrics: ["service_cpm"],
// metricTypes: ["readMetricsValues"],
// type: "Widget",
// widget: {
// title: "Service cpm",
// tips: "For HTTP 1/2, gRPC, RPC services, this means Calls Per Minute (CPM), for TCP services, this means Packets Per Minute (PPM)",
// },
// graph: {
// type: "Card",
// },
// standard: {
// unit: "CPM / PPM",
// aggregation: "/",
// aggregationNum: "100",
// },
// },
// {
// w: 8,
// h: 12,
// i: "4",
// metrics: ["service_resp_time"],
// metricTypes: ["readMetricsValues"],
// type: "Widget",
// widget: {
// title: "Service Avg Response Time",
// },
// graph: {
// type: "Line",
// },
// standard: {
// unit: "ms",
// },
// },
// {
// w: 8,
// h: 12,
// i: "5",
// metrics: ["service_apdex"],
// metricTypes: ["readMetricsValues"],
// type: "Widget",
// widget: {
// title: "Service Apdex",
// },
// graph: {
// type: "Line",
// },
// standard: {
// aggregation: "/",
// aggregationNum: "10000",
// },
// },
// {
// w: 8,
// h: 12,
// i: "6",
// metrics: ["service_percentile"],
// metricTypes: ["readLabeledMetricsValues"],
// type: "Widget",
// metricLabels: "P50, P75, P90, P95, P99",
// labelsIndex: "0, 1, 2, 3, 4",
// widget: {
// title: "Service Response Time Percentile",
// },
// graph: {
// type: "Line",
// },
// standard: {
// unit: "ms",
// },
// },
// {
// w: 8,
// h: 12,
// i: "7",
// metrics: ["service_sla"],
// metricTypes: ["readMetricsValues"],
// type: "Widget",
// widget: {
// title: "Successful Rate",
// },
// graph: {
// type: "Line",
// },
// standard: {
// unit: "%",
// aggregation: "/",
// aggregationNum: "100",
// },
// },
// {
// w: 8,
// h: 12,
// i: "8",
// metrics: ["service_throughput_received", "service_throughput_sent"],
// metricTypes: ["readMetricsValues", "readMetricsValues"],
// type: "Widget",
// widget: {
// title: "Service Throughput",
// },
// graph: {
// type: "Line",
// },
// standard: {
// unit: "Bytes",
// tips: "This metrics is only avaible for TCP services",
// },
// },
// {
// w: 8,
// h: 12,
// i: "9",
// metrics: ["service_mq_consume_count"],
// metricTypes: ["readMetricsValues"],
// type: "Widget",
// widget: {
// title: "Message Queue Consuming Count",
// },
// graph: {
// type: "Line",
// },
// standard: {
// tips: "The number of consumed messages.",
// },
// },
// {
// w: 8,
// h: 12,
// i: "10",
// metrics: ["service_mq_consume_latency"],
// metricTypes: ["readMetricsValues"],
// type: "Widget",
// widget: {
// title: "Message Queue Consuming Count",
// },
// graph: {
// type: "Line",
// },
// standard: {
// unit: "ms",
// tips: "The avg latency of message consuming. Latency = timestamp(received) - timestamp(producing)",
// },
// },
// ],
// },
// };

View File

@ -35,3 +35,32 @@ export const getAllTemplates = {
} }
`, `,
}; };
export const addTemplate = {
variable: "$setting: NewDashboardSetting!",
query: `
addTemplate(setting: $setting) {
id
status
message
}`,
};
export const changeTemplate = {
variable: "$setting: DashboardSetting!",
query: `
changeTemplate(setting: $setting) {
id
status
message
}`,
};
export const deleteTemplate = {
variable: "$id: String!",
query: `
disableTemplate(id: $id) {
id
status
message
}`,
};

View File

@ -14,10 +14,23 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { OAPTimeInfo, OAPVersion, getAllTemplates } from "../fragments/app"; import {
OAPTimeInfo,
OAPVersion,
getAllTemplates,
addTemplate,
changeTemplate,
deleteTemplate,
} from "../fragments/app";
export const queryOAPTimeInfo = `query queryOAPTimeInfo {${OAPTimeInfo.query}}`; export const queryOAPTimeInfo = `query queryOAPTimeInfo {${OAPTimeInfo.query}}`;
export const queryOAPVersion = `query ${OAPVersion.query}`; export const queryOAPVersion = `query ${OAPVersion.query}`;
export const getTemplates = `query queryTemplates {${getAllTemplates.query}}`; export const getTemplates = `query queryTemplates {${getAllTemplates.query}}`;
export const addNewTemplate = `query queryAlarms(${addTemplate.variable}) {${addTemplate.query}}`;
export const updateTemplate = `query queryAlarms(${changeTemplate.variable}) {${changeTemplate.query}}`;
export const removeTemplate = `query queryAlarms(${deleteTemplate.variable}) {${deleteTemplate.query}}`;

View File

@ -20,6 +20,7 @@ import { useDashboardStore } from "@/store/modules/dashboard";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { Instance, Endpoint, Service } from "@/types/selector"; import { Instance, Endpoint, Service } from "@/types/selector";
import { StandardConfig } from "@/types/dashboard";
export function useQueryProcessor(config: any) { export function useQueryProcessor(config: any) {
if (!(config.metrics && config.metrics[0])) { if (!(config.metrics && config.metrics[0])) {
@ -46,7 +47,6 @@ export function useQueryProcessor(config: any) {
} }
const fragment = config.metrics.map((name: string, index: number) => { const fragment = config.metrics.map((name: string, index: number) => {
const metricType = config.metricTypes[index] || ""; const metricType = config.metricTypes[index] || "";
const labels = ["0", "1", "2", "3", "4"];
if ( if (
[ [
MetricQueryTypes.ReadSampledRecords, MetricQueryTypes.ReadSampledRecords,
@ -66,6 +66,9 @@ export function useQueryProcessor(config: any) {
}; };
} else { } else {
if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) { if (metricType === MetricQueryTypes.ReadLabeledMetricsValues) {
const labels = (config.labelsIndex || "")
.split(",")
.map((item: string) => item.replace(/^\s*|\s*$/g, ""));
variables.push(`$labels${index}: [String!]!`); variables.push(`$labels${index}: [String!]!`);
conditions[`labels${index}`] = labels; conditions[`labels${index}`] = labels;
} }
@ -121,7 +124,11 @@ export function useQueryProcessor(config: any) {
} }
export function useSourceProcessor( export function useSourceProcessor(
resp: { errors: string; data: { [key: string]: any } }, resp: { errors: string; data: { [key: string]: any } },
config: { metrics: string[]; metricTypes: string[] } config: {
metrics: string[];
metricTypes: string[];
standard: StandardConfig;
}
) { ) {
if (resp.errors) { if (resp.errors) {
ElMessage.error(resp.errors); ElMessage.error(resp.errors);
@ -140,8 +147,12 @@ export function useSourceProcessor(
} }
if (type === MetricQueryTypes.ReadLabeledMetricsValues) { if (type === MetricQueryTypes.ReadLabeledMetricsValues) {
const resVal = Object.values(resp.data)[0] || []; const resVal = Object.values(resp.data)[0] || [];
const labelsIdx = ["0", "1", "2", "3", "4"]; const labels = (config.standard.metricLabels || "")
const labels = ["P50", "P75", "P90", "P95", "P99"]; .split(",")
.map((item: string) => item.replace(/^\s*|\s*$/g, ""));
const labelsIdx = (config.standard.labelsIndex || "")
.split(",")
.map((item: string) => item.replace(/^\s*|\s*$/g, ""));
for (const item of resVal) { for (const item of resVal) {
const values = item.values.values.map( const values = item.values.values.map(
(d: { value: number }) => d.value (d: { value: number }) => d.value

View File

@ -20,7 +20,6 @@ import { LayoutConfig } from "@/types/dashboard";
import graphql from "@/graphql"; import graphql from "@/graphql";
import query from "@/graphql/fetch"; import query from "@/graphql/fetch";
import { import {
ConfigData,
ConfigData1, ConfigData1,
ConfigData2, ConfigData2,
ConfigData3, ConfigData3,
@ -28,6 +27,7 @@ import {
ConfigData5, ConfigData5,
ConfigData6, ConfigData6,
} from "../data"; } from "../data";
import { ServiceLayout } from "@/constants/templates";
import { useAppStoreWithOut } from "@/store/modules/app"; import { useAppStoreWithOut } from "@/store/modules/app";
import { useSelectorStore } from "@/store/modules/selectors"; import { useSelectorStore } from "@/store/modules/selectors";
import { NewControl } from "../data"; import { NewControl } from "../data";
@ -49,7 +49,7 @@ interface DashboardState {
export const dashboardStore = defineStore({ export const dashboardStore = defineStore({
id: "dashboard", id: "dashboard",
state: (): DashboardState => ({ state: (): DashboardState => ({
layout: [ConfigData], layout: ServiceLayout.configuration.children,
showConfig: false, showConfig: false,
selectedGrid: null, selectedGrid: null,
entity: "", entity: "",
@ -240,7 +240,7 @@ export const dashboardStore = defineStore({
this.layout = ConfigData3; this.layout = ConfigData3;
} }
if (type == "Service") { if (type == "Service") {
this.layout = [ConfigData]; this.layout = ServiceLayout.configuration.children;
} }
if (type == "ServiceRelation") { if (type == "ServiceRelation") {
this.layout = [ConfigData4]; this.layout = [ConfigData4];

View File

@ -38,8 +38,8 @@ export interface WidgetConfig {
export interface StandardConfig { export interface StandardConfig {
sortOrder?: string; sortOrder?: string;
unit?: string; unit?: string;
max?: string; labelsIndex?: string;
min?: string; metricLabels?: string;
plus?: string; plus?: string;
minus?: string; minus?: string;
multiply?: string; multiply?: string;

View File

@ -199,7 +199,10 @@ function changeChartType(item: Option) {
} }
} }
function changeMetrics(index: number, arr: (Option & { type: string })[]) { function changeMetrics(
index: number,
arr: (Option & { type: string })[] | any
) {
if (!arr.length) { if (!arr.length) {
states.metricTypeList = []; states.metricTypeList = [];
states.metricTypes = []; states.metricTypes = [];
@ -224,7 +227,7 @@ function changeMetrics(index: number, arr: (Option & { type: string })[]) {
queryMetrics(); queryMetrics();
} }
function changeMetricType(index: number, opt: Option[]) { function changeMetricType(index: number, opt: Option[] | any) {
const metric = const metric =
states.metricList.filter( states.metricList.filter(
(d: Option) => states.metrics[index] === d.value (d: Option) => states.metrics[index] === d.value
@ -266,7 +269,8 @@ async function queryMetrics() {
ElMessage.error(json.errors); ElMessage.error(json.errors);
return; return;
} }
const source = useSourceProcessor(json, states); const { standard } = dashboardStore.selectedGrid;
const source = useSourceProcessor(json, { ...states, standard });
emit("update", source); emit("update", source);
} }

View File

@ -35,23 +35,23 @@ limitations under the License. -->
/> />
</div> </div>
<div class="item"> <div class="item">
<span class="label">{{ t("max") }}</span> <span class="label">{{ t("labels") }}</span>
<el-input <el-input
class="input" class="input"
v-model="state.max" v-model="state.metricLabels"
size="small" size="small"
placeholder="auto" placeholder="auto"
@change="changeStandardOpt({ max: state.max })" @change="changeStandardOpt({ metricLabels: state.metricLabels })"
/> />
</div> </div>
<div class="item"> <div class="item">
<span class="label">{{ t("min") }}</span> <span class="label">{{ t("labelsIndex") }}</span>
<el-input <el-input
class="input" class="input"
v-model="state.min" v-model="state.labelsIndex"
size="small" size="small"
placeholder="auto" placeholder="auto"
@change="changeStandardOpt({ min: state.min })" @change="changeStandardOpt({ labelsIndex: state.labelsIndex })"
/> />
</div> </div>
<div class="item"> <div class="item">
@ -126,8 +126,8 @@ const { selectedGrid } = dashboardStore;
const { t } = useI18n(); const { t } = useI18n();
const state = reactive({ const state = reactive({
unit: selectedGrid.standard.unit, unit: selectedGrid.standard.unit,
max: "", labelsIndex: selectedGrid.standard.labelsIndex,
min: "", metricLabels: selectedGrid.standard.metricLabels,
plus: "", plus: "",
minus: "", minus: "",
multiply: "", multiply: "",

View File

@ -84,7 +84,6 @@ limitations under the License. -->
:row-height="10" :row-height="10"
:is-draggable="true" :is-draggable="true"
:is-resizable="true" :is-resizable="true"
:responsive="true"
@layout-updated="layoutUpdatedEvent" @layout-updated="layoutUpdatedEvent"
> >
<grid-item <grid-item
@ -144,9 +143,11 @@ export default defineComponent({
const l = dashboardStore.layout.findIndex( const l = dashboardStore.layout.findIndex(
(d: LayoutConfig) => d.i === props.data.i (d: LayoutConfig) => d.i === props.data.i
); );
dashboardStore.setCurrentTabItems( if (dashboardStore.layout[l].children.length) {
dashboardStore.layout[l].children[activeTabIndex.value].children dashboardStore.setCurrentTabItems(
); dashboardStore.layout[l].children[activeTabIndex.value].children
);
}
function clickTabs(e: Event, idx: number) { function clickTabs(e: Event, idx: number) {
e.stopPropagation(); e.stopPropagation();

View File

@ -111,7 +111,12 @@ export default defineComponent({
if (!json) { if (!json) {
return; return;
} }
state.source = useSourceProcessor(json, props.data); const d = {
metrics: props.data.metrics,
metricTypes: props.data.metricTypes,
standard: props.data.standard,
};
state.source = useSourceProcessor(json, d);
} }
function removeWidget() { function removeWidget() {