Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding visualizations panel to metrics #1222

Merged
merged 5 commits into from
Nov 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions dashboards-observability/common/constants/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,16 @@ export const PPL_PROMETHEUS_CATALOG_REQUEST =

// redux
export const REDUX_SLICE_METRICS = 'metrics';

export const resolutionOptions = [
{ value: 's', text: 'seconds' },
{ value: 'm', text: 'minutes' },
{ value: 'h', text: 'hours' },
{ value: 'd', text: 'days' },
{ value: 'M', text: 'Months' },
{ value: 'q', text: 'quarters' },
{ value: 'y', text: 'years' },
];

export const DEFAULT_METRIC_HEIGHT = 2;
export const DEFAULT_METRIC_WIDTH = 12;
22 changes: 22 additions & 0 deletions dashboards-observability/common/types/metrics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { VisualizationType } from './custom_panels';

export interface MetricData {
metricId: string;
metricType: 'savedCustomMetric' | 'prometheusMetric';
metricName: string;
}

export interface MetricType extends VisualizationType {
id: string;
savedVisualizationId: string;
x: number;
y: number;
w: number;
h: number;
metricType: 'savedCustomMetric' | 'prometheusMetric';
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ const queryAccumulator = (
timestampField: string,
startTime: string,
endTime: string,
panelFilterQuery: string
panelFilterQuery: string,
spanParam: string | undefined
) => {
const indexMatchArray = originalQuery.match(PPL_INDEX_REGEX);
if (indexMatchArray == null) {
Expand All @@ -100,7 +101,15 @@ const queryAccumulator = (
startTime
)}' and ${timestampField} <= '${convertDateTime(endTime, false)}'`;
const pplFilterQuery = panelFilterQuery === '' ? '' : ` | ${panelFilterQuery}`;
return indexPartOfQuery + timeQueryFilter + pplFilterQuery + filterPartOfQuery;
const finalQuery = indexPartOfQuery + timeQueryFilter + pplFilterQuery + filterPartOfQuery;
if (spanParam === undefined) {
return finalQuery;
} else {
return finalQuery.replace(
new RegExp(`span\\(${timestampField},(.*?)\\)`),
`span(${timestampField},${spanParam})`
);
}
};

// PPL Service requestor
Expand Down Expand Up @@ -154,6 +163,7 @@ export const getQueryResponse = (
type: string,
startTime: string,
endTime: string,
spanParam: string | undefined,
setVisualizationData: React.Dispatch<React.SetStateAction<any[]>>,
setIsLoading: React.Dispatch<React.SetStateAction<boolean>>,
setIsError: React.Dispatch<React.SetStateAction<string>>,
Expand All @@ -165,7 +175,14 @@ export const getQueryResponse = (

let finalQuery = '';
try {
finalQuery = queryAccumulator(query, timestampField, startTime, endTime, filterQuery);
finalQuery = queryAccumulator(
query,
timestampField,
startTime,
endTime,
filterQuery,
spanParam
);
} catch (error) {
const errorMessage = 'Issue in building final query';
setIsError(errorMessage);
Expand All @@ -185,6 +202,7 @@ export const renderSavedVisualization = async (
startTime: string,
endTime: string,
filterQuery: string,
spanParam: string | undefined,
setVisualizationTitle: React.Dispatch<React.SetStateAction<string>>,
setVisualizationType: React.Dispatch<React.SetStateAction<string>>,
setVisualizationData: React.Dispatch<React.SetStateAction<Plotly.Data[]>>,
Expand Down Expand Up @@ -219,6 +237,7 @@ export const renderSavedVisualization = async (
visualization.type,
startTime,
endTime,
spanParam,
setVisualizationData,
setIsLoading,
setIsError,
Expand All @@ -227,6 +246,83 @@ export const renderSavedVisualization = async (
);
};

const createCatalogVisualizationMetaData = (
catalogSource: string,
visualizationQuery: string,
visualizationType: string,
visualizationTimeField: string
) => {
return {
name: catalogSource,
description: '',
query: visualizationQuery,
type: visualizationType,
selected_date_range: {
start: 'now/y',
end: 'now',
text: '',
},
selected_timestamp: {
name: visualizationTimeField,
type: 'timestamp',
},
selected_fields: {
text: '',
tokens: [],
},
};
};

//Creates a catalogVisualization for a runtime catalog based PPL query and runs getQueryResponse
export const renderCatalogVisualization = async (
http: CoreStart['http'],
pplService: PPLService,
catalogSource: string,
startTime: string,
endTime: string,
filterQuery: string,
spanParam: string | undefined,
setVisualizationTitle: React.Dispatch<React.SetStateAction<string>>,
setVisualizationType: React.Dispatch<React.SetStateAction<string>>,
setVisualizationData: React.Dispatch<React.SetStateAction<Plotly.Data[]>>,
setVisualizationMetaData: React.Dispatch<React.SetStateAction<undefined>>,
setIsLoading: React.Dispatch<React.SetStateAction<boolean>>,
setIsError: React.Dispatch<React.SetStateAction<string>>,
spanResolution?: string
) => {
setIsLoading(true);
setIsError('');

const visualizationType = 'line';
const visualizationTimeField = '@timestamp';
const visualizationQuery = `source = ${catalogSource} | stats avg(@value) by span(${visualizationTimeField},1h)`;

const visualizationMetaData = createCatalogVisualizationMetaData(
catalogSource,
visualizationQuery,
visualizationType,
visualizationTimeField
);
setVisualizationTitle(catalogSource);
setVisualizationType(visualizationType);

setVisualizationMetaData(visualizationMetaData);

getQueryResponse(
pplService,
visualizationQuery,
visualizationType,
startTime,
endTime,
spanParam,
setVisualizationData,
setIsLoading,
setIsError,
filterQuery,
visualizationTimeField
);
};

// Function to store recently used time filters and set start and end time.
export const onTimeChange = (
start: ShortDate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import {
import React, { useEffect, useMemo, useState } from 'react';
import { CoreStart } from '../../../../../../../src/core/public';
import PPLService from '../../../../services/requests/ppl';
import { displayVisualization, renderSavedVisualization } from '../../helpers/utils';
import {
displayVisualization,
renderCatalogVisualization,
renderSavedVisualization,
} from '../../helpers/utils';
import './visualization_container.scss';

/*
Expand All @@ -40,6 +44,8 @@ import './visualization_container.scss';
* pplFilterValue: string with panel PPL filter value
* showFlyout: function to show the flyout
* removeVisualization: function to remove all the visualizations
* catalogVisualization: boolean pointing if the container is used for catalog metrics
* spanParam: Override the span(timestamp, 1h) in visualization to span(timestamp, spanParam)
*/

interface Props {
Expand All @@ -57,6 +63,8 @@ interface Props {
cloneVisualization?: (visualzationTitle: string, savedVisualizationId: string) => void;
showFlyout?: (isReplacement?: boolean | undefined, replaceVizId?: string | undefined) => void;
removeVisualization?: (visualizationId: string) => void;
catalogVisualization?: boolean;
spanParam?: string;
}

export const VisualizationContainer = ({
Expand All @@ -74,6 +82,8 @@ export const VisualizationContainer = ({
cloneVisualization,
showFlyout,
removeVisualization,
catalogVisualization,
spanParam,
}: Props) => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const [disablePopover, setDisablePopover] = useState(false);
Expand Down Expand Up @@ -125,20 +135,38 @@ export const VisualizationContainer = ({
}

const loadVisaulization = async () => {
await renderSavedVisualization(
http,
pplService,
savedVisualizationId,
fromTime,
toTime,
pplFilterValue,
setVisualizationTitle,
setVisualizationType,
setVisualizationData,
setVisualizationMetaData,
setIsLoading,
setIsError
);
if (catalogVisualization)
await renderCatalogVisualization(
http,
pplService,
savedVisualizationId,
fromTime,
toTime,
pplFilterValue,
spanParam,
setVisualizationTitle,
setVisualizationType,
setVisualizationData,
setVisualizationMetaData,
setIsLoading,
setIsError
);
else
await renderSavedVisualization(
http,
pplService,
savedVisualizationId,
fromTime,
toTime,
pplFilterValue,
spanParam,
setVisualizationTitle,
setVisualizationType,
setVisualizationData,
setVisualizationMetaData,
setIsLoading,
setIsError
);
};

const memoisedVisualizationBox = useMemo(
Expand Down
Loading