diff --git a/common/constants/shared.ts b/common/constants/shared.ts index dea36e4ae9..b2ae0dcdbe 100644 --- a/common/constants/shared.ts +++ b/common/constants/shared.ts @@ -2,7 +2,7 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ -import CSS from 'csstype'; +/* eslint-disable no-unused-vars */ // Client route export const PPL_BASE = '/api/ppl'; @@ -81,6 +81,7 @@ export const OTEL_DATE_FORMAT = 'YYYY-MM-DDTHH:mm:ss'; export const SPAN_REGEX = /span/; export const PROMQL_METRIC_SUBTYPE = 'promqlmetric'; +export const OTEL_METRIC_SUBTYPE = 'openTelemetryMetric'; export const PPL_METRIC_SUBTYPE = 'metric'; export const PPL_SPAN_REGEX = /by\s*span/i; diff --git a/public/components/custom_panels/helpers/utils.tsx b/public/components/custom_panels/helpers/utils.tsx index 5e030f275b..47f40edd6d 100644 --- a/public/components/custom_panels/helpers/utils.tsx +++ b/public/components/custom_panels/helpers/utils.tsx @@ -2,8 +2,11 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ +/* eslint-disable no-unused-vars */ +/* eslint-disable no-prototype-builtins */ import { ShortDate } from '@elastic/eui'; +// eslint-disable-next-line import/no-unresolved import { DurationRange } from '@elastic/eui/src/components/date_picker/types'; import _, { forEach, isEmpty, min } from 'lodash'; import { Moment } from 'moment-timezone'; @@ -12,6 +15,7 @@ import { Layout } from 'react-grid-layout'; import { CoreStart } from '../../../../../../src/core/public'; import { OBSERVABILITY_BASE, + OTEL_METRIC_SUBTYPE, PPL_DATE_FORMAT, PPL_INDEX_REGEX, PPL_WHERE_CLAUSE_REGEX, @@ -33,6 +37,7 @@ import { Visualization } from '../../visualizations/visualization'; import { MetricType } from '../../../../common/types/metrics'; import { convertDateTime, updateCatalogVisualizationQuery } from '../../common/query_utils'; import { coreRefs } from '../../../framework/core_refs'; +import { ConsoleAppender } from '../../../../../../src/core/server/logging/appenders/console/console_appender'; /* * "Utils" This file contains different reused functions in operational panels @@ -342,6 +347,7 @@ export const renderCatalogVisualization = async ({ queryMetaData?: MetricType; visualization: SavedVisualizationType; }) => { + console.log('visualization in catalog: ', visualization); setIsLoading(true); setIsError({} as VizContainerError); @@ -394,14 +400,15 @@ const createOtelVisualizationMetaData = ( documentName: string, visualizationType: string, startTime: string, - endTime: string + endTime: string, + queryData: object ) => { return { name: documentName, description: '', query: '', type: visualizationType, - metricType: 'otel', + metricType: OTEL_METRIC_SUBTYPE, selected_date_range: { start: startTime, end: endTime, @@ -415,6 +422,9 @@ const createOtelVisualizationMetaData = ( text: '', tokens: [], }, + userConfigs: { + layout: dynamicLayoutFromQueryData(queryData), + }, }; }; @@ -481,34 +491,47 @@ const extractIndexAndDocumentName = (metricString: string): [string, string] | n } }; -export const renderOpenTelemetryVisualization = async ( - savedVisualizationId: string, - startTime: string, - endTime: string, - spanParam: string | undefined, - setVisualizationTitle: React.Dispatch>, - setVisualizationType: React.Dispatch>, - setVisualizationData: React.Dispatch>, - setVisualizationMetaData: React.Dispatch>, - setIsLoading: React.Dispatch>, - setIsError: React.Dispatch>, - panelVisualization: any, - spanResolution?: string -) => { - startTime = 'now-15y'; - endTime = 'now'; +export const renderOpenTelemetryVisualization = async ({ + startTime, + endTime, + setVisualizationTitle, + setVisualizationType, + setVisualizationData, + setVisualizationMetaData, + setIsLoading, + setIsError, + visualization, +}: { + startTime: string; + endTime: string; + setVisualizationTitle: React.Dispatch>; + setVisualizationType: React.Dispatch>; + setVisualizationData: React.Dispatch>; + setVisualizationMetaData: React.Dispatch>; + setIsLoading: React.Dispatch>; + setIsError: React.Dispatch>; + visualization: any; +}) => { + setIsLoading(true); + setIsError({} as VizContainerError); + const { http } = coreRefs; const visualizationType = 'bar'; - let index = panelVisualization?.metric?.index; + let index = visualization?.index; + let documentName = visualization?.name; + console.log('index: ', index); if (index === undefined) { - const indexAndDocumentName = extractIndexAndDocumentName(panelVisualization.name); + const indexAndDocumentName = extractIndexAndDocumentName(visualization.name); index = indexAndDocumentName[0]; - savedVisualizationId = indexAndDocumentName[1]; + documentName = indexAndDocumentName[1]; } - const fetchSampleDocument = await fetchSampleOTDocument(index, http, savedVisualizationId)(); - + const fetchSampleDocument = await fetchSampleOTDocument(index, http, documentName)(); const source = fetchSampleDocument.hits[0]._source; + + setVisualizationType(visualizationType); + setVisualizationTitle(source.name); + const dataBinsPromises = source.buckets.map(async (bucket: any) => { try { const formattedStartTime = convertDateTime(startTime, false, false, false, true); @@ -518,19 +541,13 @@ export const renderOpenTelemetryVisualization = async ( bucket.max.toString(), formattedStartTime, formattedEndTime, - savedVisualizationId, + documentName, http, index, setIsError, setIsLoading )(); - function getRandomInt(min: number, max: number) { - // The maximum is exclusive and the minimum is inclusive - min = Math.ceil(min); - max = Math.floor(max); - return Math.floor(Math.random() * (max - min)) + min; - } return { xAxis: bucket.min + ' - ' + bucket.max, 'count()': fetchingAggregatedBinCount?.nested_buckets?.bucket_range?.bucket_count?.value, @@ -545,18 +562,14 @@ export const renderOpenTelemetryVisualization = async ( return { dataBins: { jsonData } }; }; const formatedJsonData = formatDataBinsName().dataBins; - - setVisualizationType(visualizationType); - setVisualizationTitle(source.name); - setVisualizationData(formatedJsonData); - const visualizationMetaData = createOtelVisualizationMetaData( - savedVisualizationId, + documentName, visualizationType, startTime, - endTime + endTime, + formatedJsonData ); - + setVisualizationData(formatedJsonData); setVisualizationMetaData(visualizationMetaData); }; @@ -593,7 +606,7 @@ export const parseSavedVisualizations = ( subType: visualization.savedVisualization.hasOwnProperty('subType') ? visualization.savedVisualization.subType : '', - metric_type: visualization.savedVisualization.hasOwnProperty('metric_type') + metricType: visualization.savedVisualization.hasOwnProperty('metricType') ? visualization.savedVisualization.metricType : '', units_of_measure: visualization.savedVisualization.hasOwnProperty('units_of_measure') @@ -732,7 +745,7 @@ export const displayVisualization = (metaData: any, data: any, type: string) => finalDataConfig = { ...finalDataConfig, ...processMetricsData(data.schema, finalDataConfig) }; // add otel metric specific overriding - if (metaData?.metricType === 'otel') { + if (metaData?.metricType === OTEL_METRIC_SUBTYPE) { finalDataConfig = { ...finalDataConfig, ...constructOtelMetricsMetaData() }; } @@ -748,6 +761,8 @@ export const displayVisualization = (metaData: any, data: any, type: string) => }, }; + console.log('type in displayVisualization: ', type); + return ( { }; const loadVizComponents = () => { + console.log('panelVisualizations[0]: ', panelVisualizations[0]); const gridDataComps = panelVisualizations.map( (panelVisualization: VisualizationType, index) => ( { - return savedVisualizationId - ? await fetchVisualizationById(http, savedVisualizationId, setIsError) - : inputMetaData; + try { + return savedVisualizationId + ? await fetchVisualizationById(http, savedVisualizationId, setIsError) + : inputMetaData; + } catch (error) { + setIsError({ error }); + return null; + } }; const loadVisaulization = async () => { const visualization = await fetchVisualization(); setVisualizationMetaData(visualization); + console.log('visualization: ', visualization); if (!visualization && !savedVisualizationId) return; - // console.log('panelViz: ', panelVisualization); - // if (panelVisualization.metricType === undefined) { - // const fetchedVisualization = await fetchVisualizationById( - // http, - // savedVisualizationId, - // setIsError - // ); - // console.log('fetchedVisualization in if: ', fetchedVisualization); - // metricType = fetchedVisualization.metric_type; - - // if (metricType === 'openTelemetryMetric') panelVisualization = fetchedVisualization; - // } - if (metricType === 'openTelemetryMetric') - await renderOpenTelemetryVisualization( - savedVisualizationId, - fromTime, - toTime, - spanParam, + if (visualization.metricType === OTEL_METRIC_SUBTYPE) + await renderOpenTelemetryVisualization({ + visualization, + startTime: fromTime, + endTime: toTime, setVisualizationTitle, setVisualizationType, setVisualizationData, setVisualizationMetaData, setIsLoading, setIsError, - panelVisualization - ); - else if (visualization.subType === PROMQL_METRIC_SUBTYPE) - renderCatalogVisualization({ + }); + else if (visualization.metricType === PROMQL_METRIC_SUBTYPE) + renderCatalogVisualization({ visualization, http, pplService, @@ -299,7 +293,7 @@ export const VisualizationContainer = ({ setIsError, queryMetaData, }); - else + else await renderSavedVisualization({ visualization, http, @@ -356,6 +350,10 @@ export const VisualizationContainer = ({ loadVisaulization(); }, [onRefresh, inputMetaData, span, resolution, fromTime, toTime]); + useEffect(() => { + console.log('visualizationType: ' + visualizationType); + }, [visualizationType]); + const metricVisCssClassName = catalogVisualization ? 'metricVis' : ''; return ( diff --git a/public/components/metrics/helpers/utils.tsx b/public/components/metrics/helpers/utils.tsx index 122252016b..5927f60909 100644 --- a/public/components/metrics/helpers/utils.tsx +++ b/public/components/metrics/helpers/utils.tsx @@ -2,13 +2,19 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ +/* eslint-disable no-unused-vars */ import { ShortDate } from '@elastic/eui'; +// eslint-disable-next-line import/no-unresolved import { DurationRange } from '@elastic/eui/src/components/date_picker/types'; import React from 'react'; import { Layout } from 'react-grid-layout'; import { VISUALIZATION } from '../../../../common/constants/metrics'; -import { PROMQL_METRIC_SUBTYPE } from '../../../../common/constants/shared'; +import { + OTEL_METRIC_SUBTYPE, + PROMQL_METRIC_SUBTYPE, + PPL_METRIC_SUBTYPE, +} from '../../../../common/constants/shared'; import PPLService from '../../../services/requests/ppl'; import { MetricType } from '../../../../common/types/metrics'; import { VisualizationType } from '../../../../common/types/custom_panels'; @@ -74,7 +80,11 @@ export const sortMetricLayout = (metricsLayout: MetricType[]) => { }); }; -export const visualizationFromMetric = (metric, span, resolution): SavedVisualizationType => { +export const visualizationFromPrometheusMetric = ( + metric, + span, + resolution +): SavedVisualizationType => { const userConfigs = JSON.stringify({ dataConfig: { chartStyles: { @@ -95,7 +105,8 @@ export const visualizationFromMetric = (metric, span, resolution): SavedVisualiz resolution, }, type: 'line', - subType: PROMQL_METRIC_SUBTYPE, + subType: PPL_METRIC_SUBTYPE, + metricType: PROMQL_METRIC_SUBTYPE, userConfigs: JSON.stringify(userConfigs), }; }; @@ -113,31 +124,23 @@ export const createOtelMetric = (metric: any) => { tokens: [], }, sub_type: 'metric', - metric_type: 'openTelemetryMetric', + metric_type: OTEL_METRIC_SUBTYPE, user_configs: {}, }; }; -export const updateOpenTelemetryMetricsWithSelections = ( - savedVisualization: any, - startTime: ShortDate, - endTime: ShortDate -) => { - console.log( - 'savedVisualization in updateOpenTelemetryMetricsWithSelections: ', - savedVisualization - ); +export const visualizationFromOtelMetric = (metric: any) => { + console.log('savedVisualization in updateOpenTelemetryMetricsWithSelections: ', metric); return { query: '', - index: savedVisualization.index, - documentName: savedVisualization.documentName, - fields: savedVisualization.selected_fields.tokens, - dateRange: [startTime, endTime], - name: savedVisualization.name, - description: savedVisualization.description, + index: metric.index, + documentName: metric.documentName, + dateRange: ['now-1d', 'now'], + name: '[Otel Metric] ' + metric.index + '.' + metric.name, + description: metric.description, type: 'bar', - subType: 'metric', - metricType: 'openTelemetryMetric', - userConfigs: JSON.stringify(savedVisualization.user_configs), + subType: PPL_METRIC_SUBTYPE, + metricType: OTEL_METRIC_SUBTYPE, + userConfigs: JSON.stringify(metric.user_configs), }; }; diff --git a/public/components/metrics/index.tsx b/public/components/metrics/index.tsx index 3733d43f05..5238452999 100644 --- a/public/components/metrics/index.tsx +++ b/public/components/metrics/index.tsx @@ -2,11 +2,13 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ +/* eslint-disable no-unused-vars */ import './index.scss'; import { EuiPage, EuiPageBody, EuiResizableContainer } from '@elastic/eui'; -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import { HashRouter, Route, RouteComponentProps, StaticContext } from 'react-router-dom'; +import { useSelector } from 'react-redux'; import { ChromeBreadcrumb } from '../../../../../src/core/public'; import { Sidebar } from './sidebar/sidebar'; import PPLService from '../../services/requests/ppl'; @@ -50,9 +52,9 @@ export const Home = ({ chrome, parentBreadcrumb }: MetricsProps) => { setToasts([...toasts, { id: new Date().toISOString(), title, text, color } as Toast]); }; - const onEditClick = (savedVisualizationId: string) => { - window.location.assign(`${observabilityLogsID}#/explorer/${savedVisualizationId}`); - }; + // const onEditClick = (savedVisualizationId: string) => { + // window.location.assign(`${observabilityLogsID}#/explorer/${savedVisualizationId}`); + // }; useEffect(() => { chrome.setBreadcrumbs([ diff --git a/public/components/metrics/redux/slices/metrics_slice.ts b/public/components/metrics/redux/slices/metrics_slice.ts index 7a20f9fc8e..4921764fd2 100644 --- a/public/components/metrics/redux/slices/metrics_slice.ts +++ b/public/components/metrics/redux/slices/metrics_slice.ts @@ -2,6 +2,7 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ +/* eslint-disable no-unused-vars */ import { createSlice } from '@reduxjs/toolkit'; import { keyBy, mergeWith, pick, sortBy } from 'lodash'; @@ -11,7 +12,6 @@ import { PPL_DATASOURCES_REQUEST, REDUX_SLICE_METRICS, SAVED_VISUALIZATION, - OBSERVABILITY_CUSTOM_METRIC, } from '../../../../../common/constants/metrics'; import { MetricType } from '../../../../../common/types/metrics'; import { SavedObjectsActions } from '../../../../services/saved_objects/saved_object_client/saved_objects_actions'; @@ -49,8 +49,8 @@ export interface DateSpanFilter { const initialState = { metrics: {}, - selectedIds: [], - sortedIds: [], + selectedIds: [], // selected IDs + sortedIds: [], // all avaliable metrics search: '', metricsLayout: [], dataSources: [OBSERVABILITY_CUSTOM_METRIC], @@ -101,14 +101,16 @@ export const loadMetrics = () => async (dispatch) => { const remoteDataRequests = await fetchRemoteMetrics(remoteDataSources); const metricsResultSet = await Promise.all([customDataRequest, ...remoteDataRequests]); + // console.log('metricsResultSet: ', metricsResultSet); const metricsResult = metricsResultSet.flat(); - + // console.log('metricsResult: ', metricsResult); const metricsMapById = keyBy(metricsResult.flat(), 'id'); dispatch(mergeMetrics(metricsMapById)); const sortedIds = sortBy(metricsResult, 'catalog', 'id').map((m) => m.id); + // console.log('sortedIds: ', sortedIds); await dispatch(setSortedIds(sortedIds)); - await dispatch(setOtelIndices(fetchOTindices)); + // await dispatch(setOtelIndices(fetchOTindices)); }; export const loadOTIndices = () => async (dispatch) => { @@ -123,7 +125,7 @@ const fetchCustomMetrics = async () => { const savedMetrics = dataSet.observabilityObjectList.filter((obj) => [PROMQL_METRIC_SUBTYPE, PPL_METRIC_SUBTYPE].includes(obj.savedVisualization?.subType) ); - + console.log('savedMetrics: ', savedMetrics); return savedMetrics.map((obj: any) => ({ id: obj.objectId, savedVisualizationId: obj.objectId, @@ -132,6 +134,7 @@ const fetchCustomMetrics = async () => { catalog: OBSERVABILITY_CUSTOM_METRIC, type: obj.savedVisualization.type, subType: obj.savedVisualization.subType, + metricType: 'customMetric', aggregation: obj.savedVisualization.queryMetaData?.aggregation ?? 'avg', availableAttributes: [], attributesGroupBy: obj.savedVisualization.queryMetaData?.attributesGroupBy ?? [], @@ -164,12 +167,12 @@ const fetchRemoteMetrics = (remoteDataSources: string[]) => attributesGroupBy: [], availableAttributes: [], type: 'line', - subType: PROMQL_METRIC_SUBTYPE, + subType: PPL_METRIC_SUBTYPE, + metricType: PROMQL_METRIC_SUBTYPE, recentlyCreated: false, })) ) ); -}; export const fetchOpenTelemetryIndices = async () => { const { http } = coreRefs; @@ -319,7 +322,7 @@ export const { /** private actions */ -const { setMetrics, setMetric, setSortedIds } = metricSlice.actions; +export const { setMetrics, setMetric, setSortedIds } = metricSlice.actions; const getAvailableAttributes = (id, metricIndex) => async (dispatch, getState) => { const { toasts } = coreRefs; @@ -342,7 +345,9 @@ const getAvailableAttributes = (id, metricIndex) => async (dispatch, getState) = }; export const addSelectedMetric = (metric: MetricType) => async (dispatch, getState) => { + // console.log('metric in addSelectedMetric: ', metric); const currentSelectedIds = getState().metrics.selectedIds; + // console.log('currentSelectedIds: ', currentSelectedIds); if (currentSelectedIds.includes(metric.id)) return; if (metric.subType === PROMQL_METRIC_SUBTYPE) { diff --git a/public/components/metrics/sidebar/index_picker.tsx b/public/components/metrics/sidebar/index_picker.tsx index 4cc30ca6f9..71f05bf396 100644 --- a/public/components/metrics/sidebar/index_picker.tsx +++ b/public/components/metrics/sidebar/index_picker.tsx @@ -17,6 +17,7 @@ export const IndexPicker = (props) => { // eslint-disable-next-line no-shadow selectedIndex: React.SetStateAction> ) => { + console.log(selectedIndex); setSelectedIndex(selectedIndex); setSelectedOTIndex(selectedIndex); }; diff --git a/public/components/metrics/sidebar/sidebar.tsx b/public/components/metrics/sidebar/sidebar.tsx index e17c56f3e8..82d891c345 100644 --- a/public/components/metrics/sidebar/sidebar.tsx +++ b/public/components/metrics/sidebar/sidebar.tsx @@ -2,6 +2,7 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ +/* eslint-disable no-unused-vars */ import './sidebar.scss'; @@ -9,6 +10,7 @@ import React, { useEffect, useRef, useState, useMemo } from 'react'; import { EuiSpacer } from '@elastic/eui'; import { I18nProvider } from '@osd/i18n/react'; import { batch, useDispatch, useSelector } from 'react-redux'; +import { keyBy, mergeWith, pick, sortBy, merge } from 'lodash'; import { addSelectedMetric, availableMetricsSelector, @@ -21,15 +23,23 @@ import { otelIndexSelector, setDataSourceIcons, coloredIconsFrom, - setMetrics, + // setMetrics, loadOTIndices, fetchOpenTelemetryDocumentNames, + mergeMetrics, + setSortedIds, + // selectedDataSourcesSelector, } from '../redux/slices/metrics_slice'; import { MetricsAccordion } from './metrics_accordion'; import { SearchBar } from './search_bar'; import { DataSourcePicker } from './data_source_picker'; import { IndexPicker } from './index_picker'; import { OptionType } from '../../../../common/types/metrics'; +import { + OTEL_METRIC_SUBTYPE, + PPL_INDEX_REGEX, + PPL_METRIC_SUBTYPE, +} from '../../../../common/constants/shared'; interface SideBarMenuProps { selectedDataSource: OptionType[]; @@ -59,7 +69,7 @@ export const Sidebar = ({ const additionalMetric = useSelector(selectMetricByIdSelector(additionalSelectedMetricId)); - const dataSource = useSelector(selectedDataSourcesSelector); + // const dataSource = useSelector(selectedDataSourcesSelector); const otelIndices = useSelector(otelIndexSelector); useEffect(() => { @@ -110,25 +120,36 @@ export const Sidebar = ({ const fetchOtelDocuments = async () => { try { const documentNames = await fetchOpenTelemetryDocumentNames(selectedOTIndex[0]?.label)(); + console.log('documentNames: ', documentNames); const availableOtelDocuments = documentNames?.aggregations?.distinct_names?.buckets.map( (item: any) => { return { id: item.key, name: item.key, catalog: 'OpenTelemetry', + subType: PPL_METRIC_SUBTYPE, + metricType: OTEL_METRIC_SUBTYPE, type: 'Histogram', index: selectedOTIndex[0]?.label, }; } ); + console.log('availableOtelDocuments: ', availableOtelDocuments); setAvailableOTDocuments(availableOtelDocuments); - dispatch(setMetrics(availableOtelDocuments)); + const metricsMapById = keyBy(availableOtelDocuments, 'id'); + // console.log('metricsMapById: ', metricsMapById); + + dispatch(mergeMetrics(metricsMapById)); + + const sortedIds = sortBy(availableOtelDocuments, 'catalog', 'id').map((m) => m.id); + // console.log('sortedIds: ', sortedIds); + dispatch(setSortedIds(sortedIds)); + // dispatch(setMetrics(availableOtelDocuments)); dispatch(setDataSourceIcons(coloredIconsFrom(['OpenTelemetry']))); } catch (error) { console.error('Error fetching OpenTelemetry documents:', error); } }; - fetchOtelDocuments(); } }, [dispatch, selectedDataSource, selectedOTIndex]); @@ -149,7 +170,7 @@ export const Sidebar = ({ const handleAddMetric = (metric: any) => { console.log('handle add metrics: ', metric); - dispatch(selectMetric(metric)); + dispatch(addSelectedMetric(metric)); }; const handleRemoveMetric = (metric: any) => { @@ -177,7 +198,7 @@ export const Sidebar = ({ /> { useEffect(() => { if (selectedMetrics && selectedMetricsIds) { const metricsArray = selectedMetricsIds.map((id) => selectedMetrics[id]); + console.log('metricsArray: ', metricsArray); setMetricsToExport(metricsArray); } }, [selectedMetrics, selectedMetricsIds]); @@ -140,30 +150,44 @@ const MetricsExportPopOver = () => { ]); const createSavedVisualization = async (metric): Promise => { - const [ds, index] = metric.index.split('.'); - const queryMetaData = { - catalogSourceName: ds, - catalogTableName: index, - aggregation: metric.aggregation, - attributesGroupBy: metric.attributesGroupBy, - }; - const visMetaData = visualizationFromMetric( - { + console.log('metric in createSavedVisualization: ', metric); + let visMetaData; + if (metric.metricType === OTEL_METRIC_SUBTYPE) { + visMetaData = visualizationFromOtelMetric({ ...metric, - dataSources: datasourceMetaFrom(metric.catalog), - query: updateCatalogVisualizationQuery({ - ...queryMetaData, - ...dateSpanFilter, - }), - queryMetaData, - subType: PROMQL_METRIC_SUBTYPE, + query: '', + subType: PPL_METRIC_SUBTYPE, + metricType: OTEL_METRIC_SUBTYPE, dateRange: ['now-1d', 'now'], - fields: ['@value'], timestamp: '@timestamp', - }, - dateSpanFilter.span, - dateSpanFilter.reoslution - ); + }); + } else { + const [ds, index] = metric.index.split('.'); + const queryMetaData = { + catalogSourceName: ds, + catalogTableName: index, + aggregation: metric.aggregation, + attributesGroupBy: metric.attributesGroupBy, + }; + visMetaData = visualizationFromPrometheusMetric( + { + ...metric, + dataSources: datasourceMetaFrom(metric.catalog), + query: updateCatalogVisualizationQuery({ + ...queryMetaData, + ...dateSpanFilter, + }), + queryMetaData, + subType: PPL_METRIC_SUBTYPE, + metricType: PROMQL_METRIC_SUBTYPE, + dateRange: ['now-1d', 'now'], + fields: ['@value'], + timestamp: '@timestamp', + }, + dateSpanFilter.span, + dateSpanFilter.reoslution + ); + } const savedObject = await OSDSavedVisualizationClient.getInstance().create(visMetaData); return savedObject; diff --git a/public/components/metrics/view/metrics_grid.tsx b/public/components/metrics/view/metrics_grid.tsx index 1ad5cf76a4..b7ef86dfae 100644 --- a/public/components/metrics/view/metrics_grid.tsx +++ b/public/components/metrics/view/metrics_grid.tsx @@ -2,6 +2,7 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ +/* eslint-disable no-unused-vars */ import React, { useEffect, useMemo } from 'react'; import { EuiContextMenuItem, EuiDragDropContext, EuiDraggable, EuiDroppable } from '@elastic/eui'; @@ -21,9 +22,14 @@ import { import './metrics_grid.scss'; import { coreRefs } from '../../../framework/core_refs'; -import { PROMQL_METRIC_SUBTYPE } from '../../../../common/constants/shared'; +import { + PROMQL_METRIC_SUBTYPE, + OTEL_METRIC_SUBTYPE, + observabilityLogsID, +} from '../../../../common/constants/shared'; import { MetricsEditInline } from '../sidebar/metrics_edit_inline'; import { EmptyMetricsView } from './empty_view'; +// import { SavedVisualizationType } from '../../../../common/types/custom_panels'; // HOC container to provide dynamic width for Grid layout @@ -32,9 +38,10 @@ interface MetricsGridProps { moveToEvents: (savedVisualizationId: string) => any; } -const visualizationFromMetric = (metric, dateSpanFilter): SavedVisualizationType => ({ +const visualizationFromPromethesMetric = (metric, dateSpanFilter): SavedVisualizationType => ({ ...metric, query: updateCatalogVisualizationQuery({ ...metric, ...dateSpanFilter }), + metricType: PROMQL_METRIC_SUBTYPE, queryMetaData: { catalogSourceName: metric.catalogSourceName, catalogTableName: metric.catalogTableName, @@ -65,6 +72,30 @@ const promQLActionMenu = [ View query , ]; +const visualizationFromOtelMetric = (metric, dateSpanFilter): SavedVisualizationType => ({ + ...metric, + name: metric.name, + description: '', + query: '', + type: 'bar', + metricType: OTEL_METRIC_SUBTYPE, + selected_date_range: { + start: dateSpanFilter.start, + end: dateSpanFilter.end, + text: '', + }, + userConfigs: { + dataConfig: { + type: 'bar', + }, + }, +}); + +const visualizationFromMetric = (metric: any, dateSpanFilter: any) => { + if (metric.metricType === OTEL_METRIC_SUBTYPE) + return visualizationFromOtelMetric(metric, dateSpanFilter); + return visualizationFromPromethesMetric(metric, dateSpanFilter); +}; const navigateToEventExplorerVisualization = (savedVisualizationId: string) => { window.location.assign(`${observabilityLogsID}#/explorer/${savedVisualizationId}`); @@ -72,7 +103,10 @@ const navigateToEventExplorerVisualization = (savedVisualizationId: string) => { export const InnerGridVisualization = ({ id, idx, dateSpanFilter, metric, refresh }) => { if (!metric) return <>; - + console.log('metric in inner grid visualization: ', metric); + console.log('idx: ', idx); + console.log('id: ', id); + console.log('dateSpanFilter: ', dateSpanFilter); return ( } actionMenuType="metricsGrid" - metricType={metric.metricType} + metricType={metric.subType} panelVisualization={metric} /> diff --git a/public/components/visualizations/charts/vis_types.ts b/public/components/visualizations/charts/vis_types.ts index f6858519b1..4a873de181 100644 --- a/public/components/visualizations/charts/vis_types.ts +++ b/public/components/visualizations/charts/vis_types.ts @@ -32,5 +32,7 @@ export const VIS_TYPES = { }; export const getVisType = (visType: string, params: any = {}) => { + console.log('visType: ', visType); + console.log('params: ', params); return VIS_TYPES[visType](params); }; diff --git a/public/services/saved_objects/event_analytics/saved_objects.ts b/public/services/saved_objects/event_analytics/saved_objects.ts index c13f3df054..22267611ae 100644 --- a/public/services/saved_objects/event_analytics/saved_objects.ts +++ b/public/services/saved_objects/event_analytics/saved_objects.ts @@ -2,9 +2,10 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ +/* eslint-disable no-unused-vars */ import { has, isArray, isEmpty } from 'lodash'; -import { IField } from 'common/types/explorer'; +import { IField } from '../../../../common/types/explorer'; import { EVENT_ANALYTICS, OBSERVABILITY_BASE, @@ -100,7 +101,7 @@ export default class SavedObjects { } if (!isEmpty(metricType)) { - objRequest.object.metric_type = metricType; + objRequest.object.metricType = metricType; } if (!isEmpty(unitsOfMeasure)) { diff --git a/public/services/saved_objects/saved_object_client/osd_saved_objects/osd_saved_object_client.ts b/public/services/saved_objects/saved_object_client/osd_saved_objects/osd_saved_object_client.ts index 37e775cc71..28c6563347 100644 --- a/public/services/saved_objects/saved_object_client/osd_saved_objects/osd_saved_object_client.ts +++ b/public/services/saved_objects/saved_object_client/osd_saved_objects/osd_saved_object_client.ts @@ -2,6 +2,7 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ +/* eslint-disable no-unused-vars */ import { isEmpty } from 'lodash'; import { @@ -120,7 +121,7 @@ export abstract class OSDSavedObjectClient extends SavedObjectClientBase { } if (!isEmpty(metricType)) { - objRequest.object.metric_type = metricType; + objRequest.object.metricType = metricType; } if (!isEmpty(unitsOfMeasure)) { diff --git a/public/services/saved_objects/saved_object_client/ppl/ppl_client.ts b/public/services/saved_objects/saved_object_client/ppl/ppl_client.ts index bc905f2ec2..eb14198543 100644 --- a/public/services/saved_objects/saved_object_client/ppl/ppl_client.ts +++ b/public/services/saved_objects/saved_object_client/ppl/ppl_client.ts @@ -2,6 +2,7 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ +/* eslint-disable no-unused-vars */ import { has, isArray, isEmpty } from 'lodash'; import { HttpStart } from '../../../../../../../src/core/public'; @@ -125,7 +126,7 @@ export class PPLSavedObjectClient extends SavedObjectClientBase implements ISave } if (!isEmpty(metricType)) { - objRequest.object.metric_type = metricType; + objRequest.object.metricType = metricType; } if (!isEmpty(unitsOfMeasure)) { diff --git a/server/adaptors/custom_panels/custom_panel_adaptor.ts b/server/adaptors/custom_panels/custom_panel_adaptor.ts index d49d4c50fa..5087a309e8 100644 --- a/server/adaptors/custom_panels/custom_panel_adaptor.ts +++ b/server/adaptors/custom_panels/custom_panel_adaptor.ts @@ -2,6 +2,8 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ +/* eslint-disable no-unused-vars */ +/* eslint-disable no-prototype-builtins */ import { v4 as uuidv4 } from 'uuid'; import { PanelType, VisualizationType } from '../../../common/types/custom_panels'; @@ -228,8 +230,8 @@ export class CustomPanelsAdaptor { subType: visualization.savedVisualization.hasOwnProperty('subType') ? visualization.savedVisualization.subType : '', - metric_type: visualization.savedVisualization.hasOwnProperty('metric_type') - ? visualization.savedVisualization.metric_type + metricType: visualization.savedVisualization.hasOwnProperty('metricType') + ? visualization.savedVisualization.metricType : '', units_of_measure: visualization.savedVisualization.hasOwnProperty('units_of_measure') ? visualization.savedVisualization.units_of_measure diff --git a/server/routes/event_analytics/event_analytics_router.ts b/server/routes/event_analytics/event_analytics_router.ts index 284de447ab..46a25169c0 100644 --- a/server/routes/event_analytics/event_analytics_router.ts +++ b/server/routes/event_analytics/event_analytics_router.ts @@ -2,6 +2,7 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ +/* eslint-disable no-unused-vars */ import { schema } from '@osd/config-schema'; import { @@ -137,14 +138,9 @@ export const registerEventAnalyticsRouter = ({ name: schema.string(), description: schema.string(), application_id: schema.maybe(schema.string()), -<<<<<<< HEAD userConfigs: schema.maybe(schema.string()), subType: schema.maybe(schema.string()), -======= - user_configs: schema.maybe(schema.string()), - sub_type: schema.maybe(schema.string()), - metric_type: schema.maybe(schema.string()), ->>>>>>> 2ba09f94 (View otel metric in dashboards) + metricType: schema.maybe(schema.string()), units_of_measure: schema.maybe(schema.string()), selected_labels: schema.maybe( schema.object({ @@ -239,7 +235,7 @@ export const registerEventAnalyticsRouter = ({ application_id: schema.maybe(schema.string()), userConfigs: schema.maybe(schema.string()), subType: schema.maybe(schema.string()), - metric_type: schema.maybe(schema.string()), + metricType: schema.maybe(schema.string()), units_of_measure: schema.maybe(schema.string()), selected_labels: schema.maybe( schema.object({