Skip to content

Commit

Permalink
Adding visualizations panel to metrics (#1222)
Browse files Browse the repository at this point in the history
* adding vizualization components

Signed-off-by: Shenoy Pratik <sgguruda@amazon.com>

* added metrics layout to redux

Signed-off-by: Shenoy Pratik <sgguruda@amazon.com>

* removed comments and updated constants

Signed-off-by: Shenoy Pratik <sgguruda@amazon.com>

* remove excess console.log

Signed-off-by: Shenoy Pratik <sgguruda@amazon.com>

Signed-off-by: Shenoy Pratik <sgguruda@amazon.com>
  • Loading branch information
ps48 authored Nov 2, 2022
1 parent e64628d commit 91df39d
Show file tree
Hide file tree
Showing 13 changed files with 812 additions and 88 deletions.
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

0 comments on commit 91df39d

Please sign in to comment.