From f1f27397e5e5c06726f8d0f231896833a7c2752e Mon Sep 17 00:00:00 2001 From: Julian Quispel Date: Fri, 2 Feb 2024 11:05:30 +0100 Subject: [PATCH 01/12] Add configuration for multi-tenancy Signed-off-by: Julian Quispel --- server/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/index.ts b/server/index.ts index 42810e059..833f238da 100644 --- a/server/index.ts +++ b/server/index.ts @@ -39,6 +39,9 @@ const observabilityConfig = { schema.maybe(schema.string()) ), }), + multitenancy: schema.object({ + enabled: schema.boolean({ defaultValue: false }), + }), }), }; @@ -49,5 +52,6 @@ export const config: PluginConfigDescriptor = { exposeToBrowser: { query_assist: true, summarize: true, + multitenancy: true, }, }; From 882b2b6042a87e61cd941b5ec5b0bd07337aaa50 Mon Sep 17 00:00:00 2001 From: Julian Quispel Date: Fri, 2 Feb 2024 14:03:06 +0100 Subject: [PATCH 02/12] Update indices route to support tenants Signed-off-by: Julian Quispel --- common/utils/tenant_index_name.ts | 17 +++++++++++++ server/routes/trace_analytics_dsl_router.ts | 28 +++++++++++++++++---- 2 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 common/utils/tenant_index_name.ts diff --git a/common/utils/tenant_index_name.ts b/common/utils/tenant_index_name.ts new file mode 100644 index 000000000..697ec7fdd --- /dev/null +++ b/common/utils/tenant_index_name.ts @@ -0,0 +1,17 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export function getTenantIndexName(indexName: string, tenantName?: string) { + if (indexName.charAt(indexName.length - 1) === '*') { + indexName = indexName.slice(0, -1); + } + + if (tenantName) { + if (indexName.charAt(indexName.length - 1) !== '-') indexName += '-'; + indexName += `${tenantName.toLowerCase()}`; + } + + return indexName + '*'; +} diff --git a/server/routes/trace_analytics_dsl_router.ts b/server/routes/trace_analytics_dsl_router.ts index 171483fd9..8c7782dba 100644 --- a/server/routes/trace_analytics_dsl_router.ts +++ b/server/routes/trace_analytics_dsl_router.ts @@ -16,16 +16,25 @@ import { TRACE_ANALYTICS_JAEGER_INDICES_ROUTE, } from '../../common/constants/trace_analytics'; import { addRequestToMetric } from '../common/metrics/metrics_helper'; +import { getTenantIndexName } from '../../common/utils/tenant_index_name'; export function registerTraceAnalyticsDslRouter(router: IRouter) { router.post( { path: TRACE_ANALYTICS_DATA_PREPPER_INDICES_ROUTE, - validate: false, + validate: { + body: schema.object({ + tenant: schema.maybe(schema.string()), + }), + }, }, async (context, request, response) => { + const { tenant } = request.body; const params: RequestParams.IndicesExists = { - index: [DATA_PREPPER_INDEX_NAME, DATA_PREPPER_SERVICE_INDEX_NAME], + index: [ + getTenantIndexName(DATA_PREPPER_INDEX_NAME, tenant), + getTenantIndexName(DATA_PREPPER_SERVICE_INDEX_NAME, tenant), + ], allow_no_indices: false, }; try { @@ -48,11 +57,19 @@ export function registerTraceAnalyticsDslRouter(router: IRouter) { router.post( { path: TRACE_ANALYTICS_JAEGER_INDICES_ROUTE, - validate: false, + validate: { + body: schema.object({ + tenant: schema.maybe(schema.string()), + }), + }, }, async (context, request, response) => { + const { tenant } = request.body; const params: RequestParams.IndicesExists = { - index: [JAEGER_INDEX_NAME, JAEGER_SERVICE_INDEX_NAME], + index: [ + getTenantIndexName(JAEGER_INDEX_NAME, tenant), + getTenantIndexName(JAEGER_SERVICE_INDEX_NAME, tenant), + ], allow_no_indices: false, }; try { @@ -78,6 +95,7 @@ export function registerTraceAnalyticsDslRouter(router: IRouter) { validate: { body: schema.object({ index: schema.maybe(schema.string()), + tenant: schema.maybe(schema.string()), from: schema.maybe(schema.number()), size: schema.number(), query: schema.maybe( @@ -109,7 +127,7 @@ export function registerTraceAnalyticsDslRouter(router: IRouter) { addRequestToMetric('trace_analytics', 'get', 'count'); const { index, size, ...rest } = request.body; const params: RequestParams.Search = { - index: index || DATA_PREPPER_INDEX_NAME, + index: index || getTenantIndexName(DATA_PREPPER_INDEX_NAME, tenant), size, body: rest, }; From 8787067853276e700d2ec0a3a3937f04c774c193 Mon Sep 17 00:00:00 2001 From: Julian Quispel Date: Fri, 2 Feb 2024 14:24:04 +0100 Subject: [PATCH 03/12] Update components to be aware of the current tenant Signed-off-by: Julian Quispel --- public/components/app.tsx | 6 +- .../config_components/service_config.tsx | 3 +- .../service_detail_flyout.tsx | 3 +- .../flyout_components/trace_detail_render.tsx | 24 ++- public/components/index.tsx | 7 +- .../helper_functions.test.tsx.snap | 27 +++ .../__tests__/helper_functions.test.tsx | 9 +- .../components/common/helper_functions.tsx | 23 ++- .../components/common/indices.ts | 41 ++++ .../dashboard/dashboard_content.tsx | 36 +--- .../components/services/service_view.tsx | 11 +- .../components/services/services_content.tsx | 9 +- .../components/services/services_table.tsx | 4 +- .../components/traces/span_detail_panel.tsx | 97 +++++---- .../components/traces/trace_view.tsx | 16 +- .../components/traces/traces.tsx | 1 + .../components/traces/traces_content.tsx | 13 +- .../components/traces/traces_table.tsx | 159 +++++++------- public/components/trace_analytics/home.tsx | 72 ++++--- .../requests/dashboard_request_handler.ts | 132 +++++++++--- .../requests/queries/dashboard_queries.ts | 194 +++++++++--------- .../requests/queries/services_queries.ts | 54 +++-- .../requests/queries/traces_queries.ts | 36 ++-- .../requests/request_handler.ts | 31 ++- .../requests/services_request_handler.ts | 36 +++- .../requests/traces_request_handler.ts | 84 +++++--- public/plugin.ts | 8 +- 27 files changed, 721 insertions(+), 415 deletions(-) create mode 100644 public/components/trace_analytics/components/common/indices.ts diff --git a/public/components/app.tsx b/public/components/app.tsx index 4569c4261..eba2135bf 100644 --- a/public/components/app.tsx +++ b/public/components/app.tsx @@ -20,6 +20,7 @@ import { Home as MetricsHome } from './metrics/index'; import { Main as NotebooksHome } from './notebooks/components/main'; import { Home as TraceAnalyticsHome } from './trace_analytics/home'; import { Home as DataConnectionsHome } from './datasources/home'; +import { PublicConfig } from '../plugin'; interface ObservabilityAppDeps { CoreStartProp: CoreStart; @@ -27,6 +28,7 @@ interface ObservabilityAppDeps { pplService: any; dslService: any; savedObjects: any; + config: PublicConfig; timestampUtils: any; queryManager: QueryManager; startPage: string; @@ -54,12 +56,13 @@ export const App = ({ pplService, dslService, savedObjects, + config, timestampUtils, queryManager, startPage, dataSourcePluggables, }: ObservabilityAppDeps) => { - const { chrome, http, notifications, savedObjects: coreSavedObjects } = CoreStartProp; + const { chrome, http, notifications } = CoreStartProp; const parentBreadcrumb = { text: observabilityTitle, href: `${observabilityID}#/`, @@ -83,6 +86,7 @@ export const App = ({ pplService={pplService} dslService={dslService} savedObjects={savedObjects} + config={config} timestampUtils={timestampUtils} queryManager={queryManager} parentBreadcrumb={parentBreadcrumb} diff --git a/public/components/application_analytics/components/config_components/service_config.tsx b/public/components/application_analytics/components/config_components/service_config.tsx index bfeb5029f..09222fb0d 100644 --- a/public/components/application_analytics/components/config_components/service_config.tsx +++ b/public/components/application_analytics/components/config_components/service_config.tsx @@ -24,6 +24,7 @@ import { handleServiceMapRequest } from '../../../trace_analytics/requests/servi import { AppAnalyticsComponentDeps } from '../../home'; import { OptionType } from '../../../../../common/types/application_analytics'; import { getClearModal } from '../../helpers/modal_containers'; +import { tenantName } from '../../../../components/trace_analytics/components/common/indices'; interface ServiceConfigProps extends AppAnalyticsComponentDeps { dslService: DSLService; @@ -50,7 +51,7 @@ export const ServiceConfig = (props: ServiceConfigProps) => { const [modalLayout, setModalLayout] = useState(); useEffect(() => { - handleServiceMapRequest(http, dslService, mode, setServiceMap); + handleServiceMapRequest(http, dslService, mode, setServiceMap, undefined, tenantName); }, []); useEffect(() => { diff --git a/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx b/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx index f17d46e1d..455643123 100644 --- a/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx +++ b/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx @@ -28,6 +28,7 @@ import { ServiceObject } from '../../../../../public/components/trace_analytics/ import { SpanDetailTable } from '../../../../../public/components/trace_analytics/components/traces/span_detail_table'; import { TraceAnalyticsComponentDeps } from '../../../../../public/components/trace_analytics/home'; import { getListItem } from '../../helpers/utils'; +import { tenantName } from '../../../../components/trace_analytics/components/common/indices'; interface ServiceFlyoutProps extends TraceAnalyticsComponentDeps { serviceName: string; @@ -131,7 +132,7 @@ export function ServiceDetailFlyout(props: ServiceFlyoutProps) { appConfigs ); handleServiceViewRequest(serviceName, http, serviceDSL, setFields, mode); - handleServiceMapRequest(http, serviceDSL, mode, setServiceMap, serviceName); + handleServiceMapRequest(http, serviceDSL, mode, setServiceMap, serviceName, tenantName); const spanDSL = filtersToDsl(mode, filters, query, startTime, endTime, 'app', appConfigs); spanDSL.query.bool.must.push({ term: { diff --git a/public/components/application_analytics/components/flyout_components/trace_detail_render.tsx b/public/components/application_analytics/components/flyout_components/trace_detail_render.tsx index bb55a94d9..7ee6f8e54 100644 --- a/public/components/application_analytics/components/flyout_components/trace_detail_render.tsx +++ b/public/components/application_analytics/components/flyout_components/trace_detail_render.tsx @@ -20,10 +20,17 @@ interface TraceDetailRenderProps { traceId: string; http: HttpStart; openSpanFlyout: (spanId: string) => void; - mode : TraceAnalyticsMode + mode: TraceAnalyticsMode; + tenant?: string; } -export const TraceDetailRender = ({ traceId, http, openSpanFlyout, mode }: TraceDetailRenderProps) => { +export const TraceDetailRender = ({ + traceId, + http, + openSpanFlyout, + mode, + tenant, +}: TraceDetailRenderProps) => { const [fields, setFields] = useState({}); const [serviceBreakdownData, setServiceBreakdownData] = useState([]); const [payloadData, setPayloadData] = useState(''); @@ -86,9 +93,16 @@ export const TraceDetailRender = ({ traceId, http, openSpanFlyout, mode }: Trace }, [traceId, fields, serviceBreakdownData, colorMap, payloadData]); useEffect(() => { - handleTraceViewRequest(traceId, http, fields, setFields, mode); - handleServicesPieChartRequest(traceId, http, setServiceBreakdownData, setColorMap, mode); - handlePayloadRequest(traceId, http, payloadData, setPayloadData, mode); + handleTraceViewRequest(traceId, http, fields, setFields, mode, tenant); + handleServicesPieChartRequest( + traceId, + http, + setServiceBreakdownData, + setColorMap, + mode, + tenant + ); + handlePayloadRequest(traceId, http, payloadData, setPayloadData, mode, tenant); }, [traceId]); return renderContent; diff --git a/public/components/index.tsx b/public/components/index.tsx index 1058af43a..5797aad77 100644 --- a/public/components/index.tsx +++ b/public/components/index.tsx @@ -7,8 +7,9 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { QueryManager } from 'common/query_manager'; import { AppMountParameters, CoreStart } from '../../../../src/core/public'; -import { AppPluginStartDependencies, SetupDependencies } from '../types'; +import { AppPluginStartDependencies } from '../types'; import { App } from './app'; +import { PublicConfig } from '../plugin'; export const Observability = ( CoreStartProp: CoreStart, @@ -20,7 +21,8 @@ export const Observability = ( timestampUtils: any, queryManager: QueryManager, startPage: string, - dataSourcePluggables + dataSourcePluggables, + config: PublicConfig ) => { ReactDOM.render( `; +exports[`Helper functions renders no match and missing configuration messages 3`] = ` + + + Learn more + + } + body={ + + The indices required for trace analytics (otel-v1-apm-span-test* and otel-v1-apm-service-map-test*) do not exist or you do not have permission to access them. + + } + title={ +

+ Trace Analytics not set up +

+ } + /> +
+`; + exports[`Helper functions renders panel title 1`] = ` { it('renders no match and missing configuration messages', () => { const noMatchMessage = shallow(); - const missingConfigurationMessage = shallow() + const missingConfigurationMessage = shallow( + + ); + const missingConfigurationMessageWithTenant = shallow( + + ); expect(noMatchMessage).toMatchSnapshot(); expect(missingConfigurationMessage).toMatchSnapshot(); + expect(missingConfigurationMessageWithTenant).toMatchSnapshot(); }); it('renders benchmark', () => { diff --git a/public/components/trace_analytics/components/common/helper_functions.tsx b/public/components/trace_analytics/components/common/helper_functions.tsx index 3e996b0aa..2f5f09b47 100644 --- a/public/components/trace_analytics/components/common/helper_functions.tsx +++ b/public/components/trace_analytics/components/common/helper_functions.tsx @@ -21,10 +21,7 @@ import { TraceAnalyticsMode } from '../../home'; import { serviceMapColorPalette } from './color_palette'; import { FilterType } from './filters/filters'; import { ServiceObject } from './plots/service_map'; - -const missingJaegerTracesConfigurationMessage = `The indices required for trace analytics (${JAEGER_INDEX_NAME} and ${JAEGER_SERVICE_INDEX_NAME}) do not exist or you do not have permission to access them.`; - -const missingDataPrepperTracesConfigurationMessage = `The indices required for trace analytics (${DATA_PREPPER_INDEX_NAME} and ${DATA_PREPPER_SERVICE_INDEX_NAME}) do not exist or you do not have permission to access them.`; +import { getTenantIndexName } from '../../../../../common/utils/tenant_index_name'; export function PanelTitle({ title, totalItems }: { title: string; totalItems?: number }) { return ( @@ -55,7 +52,23 @@ export function NoMatchMessage(props: { size: SpacerSize }) { ); } -export function MissingConfigurationMessage(props: { mode: TraceAnalyticsMode }) { +export function MissingConfigurationMessage(props: { mode: TraceAnalyticsMode; tenant?: string }) { + const missingJaegerTracesConfigurationMessage = `The indices required for trace analytics (${getTenantIndexName( + JAEGER_INDEX_NAME, + props.tenant + )} and ${getTenantIndexName( + JAEGER_SERVICE_INDEX_NAME, + props.tenant + )}) do not exist or you do not have permission to access them.`; + + const missingDataPrepperTracesConfigurationMessage = `The indices required for trace analytics (${getTenantIndexName( + DATA_PREPPER_INDEX_NAME, + props.tenant + )} and ${getTenantIndexName( + DATA_PREPPER_SERVICE_INDEX_NAME, + props.tenant + )}) do not exist or you do not have permission to access them.`; + const missingConfigurationBody = props.mode === 'jaeger' ? missingJaegerTracesConfigurationMessage diff --git a/public/components/trace_analytics/components/common/indices.ts b/public/components/trace_analytics/components/common/indices.ts new file mode 100644 index 000000000..5978cad1c --- /dev/null +++ b/public/components/trace_analytics/components/common/indices.ts @@ -0,0 +1,41 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export async function loadTenantInfo(multitenancyEnabled: boolean) { + if (!multitenancyEnabled) { + return; + } + + return await fetch(`../api/v1/multitenancy/tenant`, { + headers: { + 'Content-Type': 'application/json', + 'osd-xsrf': 'true', + accept: '*/*', + 'accept-language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6', + pragma: 'no-cache', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + }, + method: 'GET', + referrerPolicy: 'strict-origin-when-cross-origin', + mode: 'cors', + credentials: 'include', + }) + .then((response) => { + if (response.status === 404) { + // endpoint doesn't exist, security plugin is not enabled. + return undefined; + } else { + return response.text(); + } + }) + .then((tenant) => { + if (tenant === '' || tenant === '__user__') { + tenant = ''; + } + return tenant; + }); +} diff --git a/public/components/trace_analytics/components/dashboard/dashboard_content.tsx b/public/components/trace_analytics/components/dashboard/dashboard_content.tsx index 176643574..bf6d528d9 100644 --- a/public/components/trace_analytics/components/dashboard/dashboard_content.tsx +++ b/public/components/trace_analytics/components/dashboard/dashboard_content.tsx @@ -15,7 +15,6 @@ import { handleJaegerDashboardRequest, handleJaegerErrorDashboardRequest, } from '../../requests/dashboard_request_handler'; -import { handleServiceMapRequest } from '../../requests/services_request_handler'; import { FilterType } from '../common/filters/filters'; import { getValidFilterFields } from '../common/filters/filter_helpers'; import { @@ -27,9 +26,7 @@ import { processTimeStamp, } from '../common/helper_functions'; import { ErrorRatePlt } from '../common/plots/error_rate_plt'; -import { ServiceMap, ServiceObject } from '../common/plots/service_map'; import { ThroughputPlt } from '../common/plots/throughput_plt'; -import { SearchBar } from '../common/search_bar'; import { DashboardProps } from './dashboard'; import { DashboardTable } from './dashboard_table'; import { TopGroupsPage } from './top_groups_page'; @@ -49,12 +46,12 @@ export function DashboardContent(props: DashboardProps) { filters, setStartTime, setEndTime, - setQuery, setFilters, mode, dataPrepperIndicesExist, jaegerIndicesExist, toasts, + tenant, } = props; const [tableItems, setTableItems] = useState([]); const [jaegerTableItems, setJaegerTableItems] = useState([]); @@ -62,7 +59,6 @@ export function DashboardContent(props: DashboardProps) { const [throughputPltItems, setThroughputPltItems] = useState({ items: [], fixedInterval: '1h' }); const [errorRatePltItems, setErrorRatePltItems] = useState({ items: [], fixedInterval: '1h' }); const [percentileMap, setPercentileMap] = useState<{ [traceGroup: string]: number[] }>({}); - const [filteredService, setFilteredService] = useState(''); const [redirect, setRedirect] = useState(true); const [loading, setLoading] = useState(false); const [showTimeoutToast, setShowTimeoutToast] = useState(false); @@ -92,27 +88,12 @@ export function DashboardContent(props: DashboardProps) { }, []); useEffect(() => { - let newFilteredService = ''; - for (const filter of filters) { - if (mode === 'data_prepper') { - if (filter.field === 'serviceName') { - newFilteredService = filter.value; - break; - } - } else if (mode === 'jaeger') { - if (filter.field === 'process.serviceName') { - newFilteredService = filter.value; - break; - } - } - } - setFilteredService(newFilteredService); if ( !redirect && ((mode === 'data_prepper' && dataPrepperIndicesExist) || (mode === 'jaeger' && jaegerIndicesExist)) ) - refresh(newFilteredService); + refresh(); }, [ filters, startTime, @@ -124,7 +105,7 @@ export function DashboardContent(props: DashboardProps) { jaegerIndicesExist, ]); - const refresh = async (currService?: string) => { + const refresh = async () => { setLoading(true); const DSL = filtersToDsl( mode, @@ -201,7 +182,8 @@ export function DashboardContent(props: DashboardProps) { setTableItems, mode, () => setShowTimeoutToast(true), - setPercentileMap + setPercentileMap, + tenant ).then(() => setLoading(false)); // service map should not be filtered by service name (https://github.com/opensearch-project/observability/issues/442) const serviceMapDSL = _.cloneDeep(DSL); @@ -216,7 +198,8 @@ export function DashboardContent(props: DashboardProps) { fixedInterval, throughputPltItems, setThroughputPltItems, - mode + mode, + tenant ); handleDashboardErrorRatePltRequest( @@ -225,7 +208,8 @@ export function DashboardContent(props: DashboardProps) { fixedInterval, errorRatePltItems, setErrorRatePltItems, - mode + mode, + tenant ); }; @@ -344,7 +328,7 @@ export function DashboardContent(props: DashboardProps) { )} ) : ( - + )} ); diff --git a/public/components/trace_analytics/components/services/service_view.tsx b/public/components/trace_analytics/components/services/service_view.tsx index e81869d11..5c1b16d7f 100644 --- a/public/components/trace_analytics/components/services/service_view.tsx +++ b/public/components/trace_analytics/components/services/service_view.tsx @@ -20,7 +20,7 @@ import { } from '@elastic/eui'; import _ from 'lodash'; import React, { useEffect, useMemo, useState } from 'react'; -import { TraceAnalyticsComponentDeps, TraceAnalyticsMode } from '../../home'; +import { TraceAnalyticsComponentDeps } from '../../home'; import { handleServiceMapRequest, handleServiceViewRequest, @@ -38,7 +38,7 @@ interface ServiceViewProps extends TraceAnalyticsComponentDeps { } export function ServiceView(props: ServiceViewProps) { - const { mode } = props; + const { mode, tenant } = props; const [fields, setFields] = useState({}); const [serviceMap, setServiceMap] = useState({}); const [serviceMapIdSelected, setServiceMapIdSelected] = useState< @@ -54,9 +54,9 @@ export function ServiceView(props: ServiceViewProps) { processTimeStamp(props.startTime, mode), processTimeStamp(props.endTime, mode) ); - handleServiceViewRequest(props.serviceName, props.http, DSL, setFields, mode); + handleServiceViewRequest(props.serviceName, props.http, DSL, setFields, mode, tenant); if (mode === 'data_prepper') { - handleServiceMapRequest(props.http, DSL, mode, setServiceMap, props.serviceName); + handleServiceMapRequest(props.http, DSL, mode, setServiceMap, props.serviceName, tenant); } }; @@ -87,8 +87,7 @@ export function ServiceView(props: ServiceViewProps) { startTime: SearchBarProps['startTime'], setStartTime: SearchBarProps['setStartTime'], endTime: SearchBarProps['endTime'], - setEndTime: SearchBarProps['setEndTime'], - addFilter: (filter: FilterType) => void + setEndTime: SearchBarProps['setEndTime'] ) => { return ( <> diff --git a/public/components/trace_analytics/components/services/services_content.tsx b/public/components/trace_analytics/components/services/services_content.tsx index 0552c567e..cf50ff627 100644 --- a/public/components/trace_analytics/components/services/services_content.tsx +++ b/public/components/trace_analytics/components/services/services_content.tsx @@ -10,7 +10,6 @@ import React, { useEffect, useState } from 'react'; import { handleServiceMapRequest, handleServicesRequest, - handleTraceGroupsRequest, } from '../../requests/services_request_handler'; import { FilterType } from '../common/filters/filters'; import { getValidFilterFields } from '../common/filters/filter_helpers'; @@ -19,7 +18,6 @@ import { ServiceMap, ServiceObject } from '../common/plots/service_map'; import { SearchBar } from '../common/search_bar'; import { ServicesProps } from './services'; import { ServicesTable } from './services_table'; -import { OptionType } from '../../../../../common/types/application_analytics'; import { DashboardContent } from '../dashboard/dashboard_content'; export function ServicesContent(props: ServicesProps) { @@ -43,6 +41,7 @@ export function ServicesContent(props: ServicesProps) { mode, dataPrepperIndicesExist, jaegerIndicesExist, + tenant, } = props; const [tableItems, setTableItems] = useState([]); @@ -107,13 +106,14 @@ export function ServicesContent(props: ServicesProps) { (must: any) => must?.term?.serviceName == null ); await Promise.all([ - handleServicesRequest(http, DSL, setTableItems, mode), + handleServicesRequest(http, DSL, setTableItems, mode, undefined, tenant), handleServiceMapRequest( http, serviceMapDSL, mode, setServiceMap, - currService || filteredService + currService || filteredService, + tenant ), ]); setLoading(false); @@ -165,6 +165,7 @@ export function ServicesContent(props: ServicesProps) { traceColumnAction={traceColumnAction} jaegerIndicesExist={jaegerIndicesExist} dataPrepperIndicesExist={dataPrepperIndicesExist} + tenant={tenant} /> {mode === 'data_prepper' && dataPrepperIndicesExist ? ( diff --git a/public/components/trace_analytics/components/services/services_table.tsx b/public/components/trace_analytics/components/services/services_table.tsx index fb405dfe3..ed572ec88 100644 --- a/public/components/trace_analytics/components/services/services_table.tsx +++ b/public/components/trace_analytics/components/services/services_table.tsx @@ -36,6 +36,7 @@ interface ServicesTableProps { mode: TraceAnalyticsMode; jaegerIndicesExist: boolean; dataPrepperIndicesExist: boolean; + tenant?: string; } export function ServicesTable(props: ServicesTableProps) { @@ -49,6 +50,7 @@ export function ServicesTable(props: ServicesTableProps) { setRedirect, jaegerIndicesExist, dataPrepperIndicesExist, + tenant, } = props; const renderTitleBar = (totalItems?: number) => { return ( @@ -173,7 +175,7 @@ export function ServicesTable(props: ServicesTableProps) { (mode === 'data_prepper' && dataPrepperIndicesExist) || (mode === 'jaeger' && jaegerIndicesExist) ) ? ( - + ) : items?.length > 0 ? ( void; + tenant?: string; }) { - const { mode } = props; + const { mode, tenant } = props; const storedFilters = sessionStorage.getItem('TraceAnalyticsSpanFilters'); const fromApp = props.page === 'app'; const [spanFilters, setSpanFilters] = useState>( storedFilters ? JSON.parse(storedFilters) : [] ); + const [_data, _setData] = useState<{ gantt: any[]; table: any[]; ganttMaxX: number }>({ + gantt: [], + table: [], + ganttMaxX: 0, + }); const [DSL, setDSL] = useState({}); - let data: { gantt: any[]; table: any[]; ganttMaxX: number }, - setData: (data: { gantt: any[]; table: any[]; ganttMaxX: number }) => void; + let data: { gantt: any[]; table: any[]; ganttMaxX: number }; + let setData: (data: { gantt: any[]; table: any[]; ganttMaxX: number }) => void; if (props.data && props.setData) { [data, setData] = [props.data, props.setData]; } else { - [data, setData] = useState<{ gantt: any[]; table: any[]; ganttMaxX: number }>({ - gantt: [], - table: [], - ganttMaxX: 0, - }); + [data, setData] = [_data, _setData]; } const setSpanFiltersWithStorage = (newFilters: Array<{ field: string; value: any }>) => { @@ -81,41 +83,52 @@ export function SpanDetailPanel(props: { if (_.isEmpty(props.colorMap)) return; const refreshDSL = spanFiltersToDSL(); setDSL(refreshDSL); - handleSpansGanttRequest(props.traceId, props.http, setData, props.colorMap, refreshDSL, mode); + handleSpansGanttRequest( + props.traceId, + props.http, + setData, + props.colorMap, + refreshDSL, + mode, + tenant + ); }, 150); const spanFiltersToDSL = () => { - const spanDSL: any = mode === 'jaeger' ? { - query: { - bool: { - must: [ - { - term: { - traceID: props.traceId, + const spanDSL: any = + mode === 'jaeger' + ? { + query: { + bool: { + must: [ + { + term: { + traceID: props.traceId, + }, + }, + ], + filter: [], + should: [], + must_not: [], }, }, - ], - filter: [], - should: [], - must_not: [], - }, - }, - } : { - query: { - bool: { - must: [ - { - term: { - traceId: props.traceId, + } + : { + query: { + bool: { + must: [ + { + term: { + traceId: props.traceId, + }, + }, + ], + filter: [], + should: [], + must_not: [], }, }, - ], - filter: [], - should: [], - must_not: [], - }, - }, - }; + }; spanFilters.map(({ field, value }) => { if (value != null) { spanDSL.query.bool.must.push({ @@ -164,10 +177,10 @@ export function SpanDetailPanel(props: { }; }; - const layout = useMemo( - () => getSpanDetailLayout(data.gantt, data.ganttMaxX), - [data.gantt, data.ganttMaxX] - ); + const layout = useMemo(() => getSpanDetailLayout(data.gantt, data.ganttMaxX), [ + data.gantt, + data.ganttMaxX, + ]); const [currentSpan, setCurrentSpan] = useState(''); @@ -239,7 +252,7 @@ export function SpanDetailPanel(props: { return ( <> - + diff --git a/public/components/trace_analytics/components/traces/trace_view.tsx b/public/components/trace_analytics/components/traces/trace_view.tsx index c150a19ff..2cc87f3e9 100644 --- a/public/components/trace_analytics/components/traces/trace_view.tsx +++ b/public/components/trace_analytics/components/traces/trace_view.tsx @@ -35,10 +35,11 @@ import { SpanDetailPanel } from './span_detail_panel'; interface TraceViewProps extends TraceAnalyticsCoreDeps { traceId: string; mode: TraceAnalyticsMode; + tenant?: string; } export function TraceView(props: TraceViewProps) { - const { mode } = props; + const { mode, tenant } = props; const page = 'traceView'; const renderTitle = (traceId: string) => { return ( @@ -160,16 +161,18 @@ export function TraceView(props: TraceViewProps) { processTimeStamp('now', mode), page ); - handleTraceViewRequest(props.traceId, props.http, fields, setFields, mode); - handlePayloadRequest(props.traceId, props.http, payloadData, setPayloadData, mode); + console.log('tenant', tenant); + handleTraceViewRequest(props.traceId, props.http, fields, setFields, mode, tenant); + handlePayloadRequest(props.traceId, props.http, payloadData, setPayloadData, mode, tenant); handleServicesPieChartRequest( props.traceId, props.http, setServiceBreakdownData, setColorMap, - mode + mode, + tenant ); - handleServiceMapRequest(props.http, DSL, mode, setServiceMap); + handleServiceMapRequest(props.http, DSL, mode, setServiceMap, undefined, tenant); }; useEffect(() => { @@ -221,7 +224,7 @@ export function TraceView(props: TraceViewProps) { }, ]); refresh(); - }, [props.mode]); + }, [props.mode, props.tenant]); return ( <> @@ -246,6 +249,7 @@ export function TraceView(props: TraceViewProps) { mode={mode} data={ganttData} setData={setGanttData} + tenant={tenant} /> diff --git a/public/components/trace_analytics/components/traces/traces.tsx b/public/components/trace_analytics/components/traces/traces.tsx index b000a3954..82e893d65 100644 --- a/public/components/trace_analytics/components/traces/traces.tsx +++ b/public/components/trace_analytics/components/traces/traces.tsx @@ -13,6 +13,7 @@ export interface TracesProps extends TraceAnalyticsComponentDeps { page: 'traces' | 'app'; childBreadcrumbs: EuiBreadcrumb[]; traceIdColumnAction: any; + tenant?: string; } export function Traces(props: TracesProps) { diff --git a/public/components/trace_analytics/components/traces/traces_content.tsx b/public/components/trace_analytics/components/traces/traces_content.tsx index 2efc70ec7..28e69b5ec 100644 --- a/public/components/trace_analytics/components/traces/traces_content.tsx +++ b/public/components/trace_analytics/components/traces/traces_content.tsx @@ -33,6 +33,7 @@ export function TracesContent(props: TracesProps) { mode, dataPrepperIndicesExist, jaegerIndicesExist, + tenant, } = props; const [tableItems, setTableItems] = useState([]); const [redirect, setRedirect] = useState(true); @@ -78,7 +79,16 @@ export function TracesContent(props: TracesProps) { processTimeStamp(endTime, mode), page ); - await handleTracesRequest(http, DSL, timeFilterDSL, tableItems, setTableItems, mode, sort); + await handleTracesRequest( + http, + DSL, + timeFilterDSL, + tableItems, + setTableItems, + mode, + sort, + tenant + ); setLoading(false); }; @@ -107,6 +117,7 @@ export function TracesContent(props: TracesProps) { traceIdColumnAction={traceIdColumnAction} jaegerIndicesExist={jaegerIndicesExist} dataPrepperIndicesExist={dataPrepperIndicesExist} + tenant={tenant} /> ); diff --git a/public/components/trace_analytics/components/traces/traces_table.tsx b/public/components/trace_analytics/components/traces/traces_table.tsx index cd6699961..64d8133eb 100644 --- a/public/components/trace_analytics/components/traces/traces_table.tsx +++ b/public/components/trace_analytics/components/traces/traces_table.tsx @@ -36,10 +36,11 @@ interface TracesTableProps { traceIdColumnAction: any; jaegerIndicesExist: boolean; dataPrepperIndicesExist: boolean; + tenant?: string; } export function TracesTable(props: TracesTableProps) { - const { items, refresh, mode, loading, traceIdColumnAction } = props; + const { items, refresh, mode, loading, traceIdColumnAction, tenant } = props; const renderTitleBar = (totalItems?: number) => { return ( @@ -50,11 +51,9 @@ export function TracesTable(props: TracesTableProps) { ); }; - const columns = useMemo( - () => { - if (mode === 'data_prepper') { - return( - [ + const columns = useMemo(() => { + if (mode === 'data_prepper') { + return [ { field: 'trace_id', name: 'Trace ID', @@ -64,7 +63,7 @@ export function TracesTable(props: TracesTableProps) { render: (item) => ( - traceIdColumnAction(item)}> + traceIdColumnAction(item)}> {item.length < 24 ? ( item ) : ( @@ -151,79 +150,76 @@ export function TracesTable(props: TracesTableProps) { sortable: true, render: (item) => (item === 0 || item ? item : '-'), }, - ] as Array>) + ] as Array>; } else { - return ( - [ - { - field: 'trace_id', - name: 'Trace ID', - align: 'left', - sortable: true, - truncateText: true, - render: (item) => ( - - - traceIdColumnAction(item)}> - {item.length < 24 ? ( - item - ) : ( -
{_.truncate(item, { length: 24 })}
- )} -
-
- - - {(copy) => ( - - Click to copy - - )} - - - -
+ return [ + { + field: 'trace_id', + name: 'Trace ID', + align: 'left', + sortable: true, + truncateText: true, + render: (item) => ( + + + traceIdColumnAction(item)}> + {item.length < 24 ? ( + item + ) : ( +
{_.truncate(item, { length: 24 })}
+ )} +
+
+ + + {(copy) => ( + + Click to copy + + )} + + + +
+ ), + }, + { + field: 'latency', + name: 'Latency (ms)', + align: 'right', + sortable: true, + truncateText: true, + }, + { + field: 'error_count', + name: 'Errors', + align: 'right', + sortable: true, + render: (item) => + item == null ? ( + '-' + ) : item > 0 ? ( + + Yes + + ) : ( + 'No' ), - }, - { - field: 'latency', - name: 'Latency (ms)', - align: 'right', - sortable: true, - truncateText: true, - }, - { - field: 'error_count', - name: 'Errors', - align: 'right', - sortable: true, - render: (item) => - item == null ? ( - '-' - ) : item > 0 ? ( - - Yes - - ) : ( - 'No' - ), - }, - { - field: 'last_updated', - name: 'Last updated', - align: 'left', - sortable: true, - render: (item) => (item === 0 || item ? item : '-'), - }, - ] as Array>) + }, + { + field: 'last_updated', + name: 'Last updated', + align: 'left', + sortable: true, + render: (item) => (item === 0 || item ? item : '-'), + }, + ] as Array>; } - }, - [items] - ); + }, [items]); const titleBar = useMemo(() => renderTitleBar(items?.length), [items]); @@ -234,7 +230,7 @@ export function TracesTable(props: TracesTableProps) { }, }); - const onTableChange = async ({ currPage, sort }: { currPage: any; sort: any }) => { + const onTableChange = async ({ sort }: { currPage: any; sort: any }) => { if (typeof sort?.field !== 'string') return; // maps table column key to DSL aggregation name @@ -269,8 +265,11 @@ export function TracesTable(props: TracesTableProps) { {titleBar} - {!((mode === 'data_prepper' && props.dataPrepperIndicesExist) || (mode === 'jaeger' && props.jaegerIndicesExist)) ? ( - + {!( + (mode === 'data_prepper' && props.dataPrepperIndicesExist) || + (mode === 'jaeger' && props.jaegerIndicesExist) + ) ? ( + ) : items?.length > 0 ? ( void; jaegerIndicesExist: boolean; dataPrepperIndicesExist: boolean; + tenant?: string; } export const Home = (props: HomeProps) => { @@ -46,6 +50,8 @@ export const Home = (props: HomeProps) => { const [mode, setMode] = useState( (sessionStorage.getItem('TraceAnalyticsMode') as TraceAnalyticsMode) || 'jaeger' ); + const [tenantLoaded, setTenantLoaded] = useState(false); + const [tenantName, setTenantName] = useState(); const storedFilters = sessionStorage.getItem('TraceAnalyticsFilters'); const [query, setQuery] = useState(sessionStorage.getItem('TraceAnalyticsQuery') || ''); const [filters, setFilters] = useState( @@ -76,15 +82,15 @@ export const Home = (props: HomeProps) => { }; const [toasts, setToasts] = useState([]); - const setToast = (title: string, color = 'success', text?: ReactChild, side?: string) => { - if (!text) text = ''; - setToasts([...toasts, { id: new Date().toISOString(), title, text, color } as Toast]); - }; - useEffect(() => { - handleDataPrepperIndicesExistRequest(props.http, setDataPrepperIndicesExist); - handleJaegerIndicesExistRequest(props.http, setJaegerIndicesExist); - }, []); + if (!tenantLoaded) + loadTenantInfo(props.config.multitenancy.enabled).then((tenant) => { + setTenantLoaded(true); + setTenantName(tenant); + handleDataPrepperIndicesExistRequest(props.http, setDataPrepperIndicesExist, tenant); + handleJaegerIndicesExistRequest(props.http, setJaegerIndicesExist, tenant); + }); + }, [props.config.multitenancy.enabled, tenantLoaded, props.http]); const modes = [ { id: 'jaeger', title: 'Jaeger', 'data-test-subj': 'jaeger-mode' }, @@ -152,6 +158,7 @@ export const Home = (props: HomeProps) => { }, jaegerIndicesExist, dataPrepperIndicesExist, + tenant: tenantName, }; return ( @@ -167,7 +174,7 @@ export const Home = (props: HomeProps) => { ( + render={() => ( { /> ( - - )} + render={(routerProps) => + tenantLoaded && ( + + ) + } /> ( + render={() => ( - + {tenantLoaded && ( + + )} )} /> diff --git a/public/components/trace_analytics/requests/dashboard_request_handler.ts b/public/components/trace_analytics/requests/dashboard_request_handler.ts index d9316bca0..38186daaa 100644 --- a/public/components/trace_analytics/requests/dashboard_request_handler.ts +++ b/public/components/trace_analytics/requests/dashboard_request_handler.ts @@ -6,7 +6,11 @@ import _ from 'lodash'; import moment from 'moment'; import { TRACE_ANALYTICS_PLOTS_DATE_FORMAT } from '../../../../common/constants/trace_analytics'; -import { fixedIntervalToMilli, microToMilliSec, nanoToMilliSec } from '../components/common/helper_functions'; +import { + fixedIntervalToMilli, + microToMilliSec, + nanoToMilliSec, +} from '../components/common/helper_functions'; import { getDashboardQuery, getDashboardThroughputPltQuery, @@ -29,14 +33,17 @@ export const handleDashboardRequest = async ( setItems, mode, setShowTimeoutToast, - setPercentileMap? + setPercentileMap?, + tenant?: string ) => { // latency_variance should only be affected by timefilter const latencyVariances = await handleDslRequest( http, timeFilterDSL, getDashboardTraceGroupPercentiles(mode), - mode + mode, + undefined, + tenant ) .then((response) => { const map: any = {}; @@ -50,16 +57,26 @@ export const handleDashboardRequest = async ( .catch((error) => console.error(error)); if (setPercentileMap) setPercentileMap(latencyVariances); - const latencyTrends = await handleDslRequest(http, latencyTrendDSL, getLatencyTrendQuery(), mode, setShowTimeoutToast) + const latencyTrends = await handleDslRequest( + http, + latencyTrendDSL, + getLatencyTrendQuery(), + mode, + setShowTimeoutToast, + tenant + ) .then((response) => { const map: any = {}; response.aggregations.trace_group_name.buckets.map((bucket) => { const latencyTrend = bucket.group_by_hour.buckets .slice(-24) - .filter((bucket) => bucket.average_latency?.value || bucket.average_latency?.value === 0); + .filter( + (latencyBucket) => + latencyBucket.average_latency?.value || latencyBucket.average_latency?.value === 0 + ); const values = { - x: latencyTrend.map((bucket) => bucket.key), - y: latencyTrend.map((bucket) => bucket.average_latency?.value || 0), + x: latencyTrend.map((latencyXBucket) => latencyXBucket.key), + y: latencyTrend.map((latencyYBucket) => latencyYBucket.average_latency?.value || 0), }; const latencyTrendData = values.x?.length > 0 @@ -105,7 +122,7 @@ export const handleDashboardRequest = async ( }) .catch((error) => console.error(error)); - await handleDslRequest(http, DSL, getDashboardQuery(), mode, setShowTimeoutToast) + await handleDslRequest(http, DSL, getDashboardQuery(), mode, setShowTimeoutToast, tenant) .then((response) => { return Promise.all( response.aggregations.trace_group_name.buckets.map((bucket) => { @@ -135,19 +152,27 @@ export const handleJaegerDashboardRequest = async ( items, setItems, mode, - setShowTimeoutToast, - setPercentileMap? + setShowTimeoutToast ) => { - const latencyTrends = await handleDslRequest(http, latencyTrendDSL, getJaegerLatencyTrendQuery(), mode, setShowTimeoutToast) + const latencyTrends = await handleDslRequest( + http, + latencyTrendDSL, + getJaegerLatencyTrendQuery(), + mode, + setShowTimeoutToast + ) .then((response) => { const map: any = {}; response.aggregations.trace_group_name.buckets.map((bucket) => { const latencyTrend = bucket.group_by_hour.buckets .slice(-24) - .filter((bucket) => bucket.average_latency?.value || bucket.average_latency?.value === 0); + .filter( + (latencyBucket) => + latencyBucket.average_latency?.value || latencyBucket.average_latency?.value === 0 + ); const values = { - x: latencyTrend.map((bucket) => bucket.key), - y: latencyTrend.map((bucket) => bucket.average_latency?.value || 0), + x: latencyTrend.map((latencyXBucket) => latencyXBucket.key), + y: latencyTrend.map((latencyYBucket) => latencyYBucket.average_latency?.value || 0), }; const latencyTrendData = values.x?.length > 0 @@ -215,10 +240,13 @@ export const handleJaegerDashboardRequest = async ( const latencies = await handleDslRequest( http, timeFilterDSL, - getDashboardTraceGroupPercentiles(mode, newItems.map(a => a.dashboard_trace_group_name)), + getDashboardTraceGroupPercentiles( + mode, + newItems.map((a) => a.dashboard_trace_group_name) + ), mode, true, - setShowTimeoutToast, + setShowTimeoutToast ) .then((response) => { const map: any = {}; @@ -230,10 +258,10 @@ export const handleJaegerDashboardRequest = async ( return map; }) .catch((error) => console.error(error)); - newItems.forEach((item) => { - item.dashboard_latency_variance = latencies[item.dashboard_key_as_string] - }) - setItems(newItems); + newItems.forEach((item) => { + item.dashboard_latency_variance = latencies[item.dashboard_key_as_string]; + }); + setItems(newItems); }) .catch((error) => console.error(error)); }; @@ -246,19 +274,27 @@ export const handleJaegerErrorDashboardRequest = async ( items, setItems, mode, - setShowTimeoutToast, - setPercentileMap? + setShowTimeoutToast ) => { - const errorTrends = await handleDslRequest(http, latencyTrendDSL, getJaegerErrorTrendQuery(), mode, setShowTimeoutToast) + const errorTrends = await handleDslRequest( + http, + latencyTrendDSL, + getJaegerErrorTrendQuery(), + mode, + setShowTimeoutToast + ) .then((response) => { const map: any = {}; response.aggregations.trace_group_name.buckets.map((bucket) => { const errorTrend = bucket.group_by_hour.buckets .slice(-24) - .filter((bucket) => bucket.error_rate?.value || bucket.error_rate?.value === 0); + .filter( + (latencyBucket) => + latencyBucket.error_rate?.value || latencyBucket.error_rate?.value === 0 + ); const values = { - x: errorTrend.map((bucket) => bucket.key), - y: errorTrend.map((bucket) => bucket.error_rate?.value || 0), + x: errorTrend.map((latencyXBucket) => latencyXBucket.key), + y: errorTrend.map((latencyYBucket) => latencyYBucket.error_rate?.value || 0), }; const errorTrendData = values.x?.length > 0 @@ -325,8 +361,23 @@ export const handleJaegerErrorDashboardRequest = async ( .catch((error) => console.error(error)); }; -export const handleDashboardThroughputPltRequest = (http, DSL, fixedInterval, items, setItems, mode) => { - return handleDslRequest(http, DSL, getDashboardThroughputPltQuery(mode, fixedInterval), mode) +export const handleDashboardThroughputPltRequest = ( + http, + DSL, + fixedInterval, + items, + setItems, + mode, + tenant?: string +) => { + return handleDslRequest( + http, + DSL, + getDashboardThroughputPltQuery(mode, fixedInterval), + mode, + undefined, + tenant + ) .then((response) => { const buckets = response.aggregations.throughput.buckets; const texts = buckets.map( @@ -353,13 +404,28 @@ export const handleDashboardThroughputPltRequest = (http, DSL, fixedInterval, it }, ] : []; - setItems({ items: newItems, fixedInterval: fixedInterval }); + setItems({ items: newItems, fixedInterval }); }) .catch((error) => console.error(error)); }; -export const handleDashboardErrorRatePltRequest = (http, DSL, fixedInterval, items, setItems, mode) => { - return handleDslRequest(http, DSL, getErrorRatePltQuery(mode, fixedInterval), mode) +export const handleDashboardErrorRatePltRequest = ( + http, + DSL, + fixedInterval, + items, + setItems, + mode, + tenant?: string +) => { + return handleDslRequest( + http, + DSL, + getErrorRatePltQuery(mode, fixedInterval), + mode, + undefined, + tenant + ) .then((response) => { const buckets = response.aggregations.error_rate.buckets; const texts = buckets.map( @@ -386,7 +452,7 @@ export const handleDashboardErrorRatePltRequest = (http, DSL, fixedInterval, ite }, ] : []; - setItems({ items: newItems, fixedInterval: fixedInterval }); + setItems({ items: newItems, fixedInterval }); }) .catch((error) => console.error(error)); -}; \ No newline at end of file +}; diff --git a/public/components/trace_analytics/requests/queries/dashboard_queries.ts b/public/components/trace_analytics/requests/queries/dashboard_queries.ts index b73d1203e..7b70d9779 100644 --- a/public/components/trace_analytics/requests/queries/dashboard_queries.ts +++ b/public/components/trace_analytics/requests/queries/dashboard_queries.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { TraceAnalyticsMode } from "../../home"; +import { TraceAnalyticsMode } from '../../home'; export const getDashboardQuery = () => { return { @@ -111,27 +111,27 @@ export const getJaegerDashboardQuery = () => { multi_terms: { terms: [ { - field: "process.serviceName" + field: 'process.serviceName', }, { - field: "operationName" + field: 'operationName', }, ], order: { - 'latency': 'desc' + latency: 'desc', }, - size: 5 + size: 5, }, aggs: { latency: { avg: { - field: 'duration' - } + field: 'duration', + }, }, average_latency: { - scripted_metric: { - init_script: 'state.traceIDToLatencyMap = [:];', - map_script: ` + scripted_metric: { + init_script: 'state.traceIDToLatencyMap = [:];', + map_script: ` if (doc.containsKey('duration') && !doc['duration'].empty) { def traceID = doc['traceID'].value; if (!state.traceIDToLatencyMap.containsKey(traceID)) { @@ -139,8 +139,8 @@ export const getJaegerDashboardQuery = () => { } } `, - combine_script: 'return state.traceIDToLatencyMap', - reduce_script: ` + combine_script: 'return state.traceIDToLatencyMap', + reduce_script: ` def seenTraceIdsMap = [:]; def totalLatency = 0.0; def traceCount = 0.0; @@ -164,9 +164,9 @@ export const getJaegerDashboardQuery = () => { def average_latency_nanos = totalLatency / traceCount; return Math.round(average_latency_nanos / 10) / 100.0; `, + }, }, - }, - + trace_count: { cardinality: { field: 'traceID', @@ -197,8 +197,8 @@ export const getJaegerDashboardQuery = () => { }, }, }, - }, -} + }, + }; }; export const getJaegerErrorDashboardQuery = () => { @@ -217,22 +217,22 @@ export const getJaegerErrorDashboardQuery = () => { multi_terms: { terms: [ { - field: "process.serviceName" + field: 'process.serviceName', }, { - field: "operationName" + field: 'operationName', }, ], order: { - 'error_count': 'desc' + error_count: 'desc', }, - size: 5 + size: 5, }, aggs: { average_latency: { - scripted_metric: { - init_script: 'state.traceIDToLatencyMap = [:];', - map_script: ` + scripted_metric: { + init_script: 'state.traceIDToLatencyMap = [:];', + map_script: ` if (doc.containsKey('duration') && !doc['duration'].empty) { def traceID = doc['traceID'].value; if (!state.traceIDToLatencyMap.containsKey(traceID)) { @@ -240,8 +240,8 @@ export const getJaegerErrorDashboardQuery = () => { } } `, - combine_script: 'return state.traceIDToLatencyMap', - reduce_script: ` + combine_script: 'return state.traceIDToLatencyMap', + reduce_script: ` def seenTraceIdsMap = [:]; def totalLatency = 0.0; def traceCount = 0.0; @@ -265,9 +265,9 @@ export const getJaegerErrorDashboardQuery = () => { def average_latency_nanos = totalLatency / traceCount; return Math.round(average_latency_nanos / 10) / 100.0; `, + }, }, - }, - + trace_count: { cardinality: { field: 'traceID', @@ -295,11 +295,11 @@ export const getJaegerErrorDashboardQuery = () => { }, script: 'params.errors / params.total * 100', }, - } + }, }, }, - }, -} + }, + }; }; export const getLatencyTrendQuery = () => { @@ -388,10 +388,10 @@ export const getJaegerLatencyTrendQuery = () => { multi_terms: { terms: [ { - field: "process.serviceName" + field: 'process.serviceName', }, { - field: "operationName" + field: 'operationName', }, ], }, @@ -464,10 +464,10 @@ export const getJaegerErrorTrendQuery = () => { multi_terms: { terms: [ { - field: "process.serviceName" + field: 'process.serviceName', }, { - field: "operationName" + field: 'operationName', }, ], }, @@ -507,7 +507,6 @@ export const getJaegerErrorTrendQuery = () => { }, }, }, - }, }, }, @@ -515,9 +514,8 @@ export const getJaegerErrorTrendQuery = () => { }; }; - export const getDashboardTraceGroupPercentiles = (mode: TraceAnalyticsMode, buckets?: any[]) => { - if (mode === 'data_prepper') { + if (mode === 'data_prepper') { return { size: 0, query: { @@ -552,21 +550,23 @@ export const getDashboardTraceGroupPercentiles = (mode: TraceAnalyticsMode, buck }, }, }; - } else if (mode === 'jaeger') { + } else if (mode === 'jaeger') { const query = { size: 0, query: { bool: { must: [], - filter: [{ - bool: { - must_not: { - exists: { - field: "references" - } + filter: [ + { + bool: { + must_not: { + exists: { + field: 'references', + }, + }, }, }, - }], + ], should: [], must_not: [], minimum_should_match: 1, @@ -574,45 +574,49 @@ export const getDashboardTraceGroupPercentiles = (mode: TraceAnalyticsMode, buck }, aggs: { trace_group: { - multi_terms: { - terms: [ - { - field: "process.serviceName" - }, - { - field: "operationName" - }, - ], - }, - aggs: { - latency_variance_micros: { - percentiles: { - field: 'duration', - percents: [0, 95, 100], + multi_terms: { + terms: [ + { + field: 'process.serviceName', + }, + { + field: 'operationName', + }, + ], + }, + aggs: { + latency_variance_micros: { + percentiles: { + field: 'duration', + percents: [0, 95, 100], + }, }, + }, }, }, - } - }, - } + }; if (buckets) { buckets.forEach((item) => { query.query.bool.should.push({ - bool:{ - must: [ - { - term: { - 'process.serviceName': item[0] - }},{ - term: { - 'operationName': item[1] - }, - }] - }}) - }) + bool: { + must: [ + { + term: { + 'process.serviceName': item[0], + }, + }, + { + term: { + operationName: item[1], + }, + }, + ], + }, + }); + }); } - return query - }; + return query; + } }; export const getErrorRatePltQuery = (mode: TraceAnalyticsMode, fixedInterval) => { @@ -792,7 +796,7 @@ export const getDashboardThroughputPltQuery = (mode: TraceAnalyticsMode, fixedIn aggs: { trace_count: { cardinality: { - field: mode === 'jaeger' ? 'traceID': 'traceId', + field: mode === 'jaeger' ? 'traceID' : 'traceId', }, }, }, @@ -801,7 +805,7 @@ export const getDashboardThroughputPltQuery = (mode: TraceAnalyticsMode, fixedIn }; }; -export const getDashboardErrorTopGroupsQuery = (mode: TraceAnalyticsMode) => { +export const getDashboardErrorTopGroupsQuery = () => { return { size: 0, query: { @@ -817,16 +821,16 @@ export const getDashboardErrorTopGroupsQuery = (mode: TraceAnalyticsMode) => { multi_terms: { terms: [ { - "field": "process.serviceName" + field: 'process.serviceName', }, { - "field": "operationName" - } + field: 'operationName', + }, ], order: { - 'error_count': 'desc' - }, - size: 5 + error_count: 'desc', + }, + size: 5, }, aggs: { error_count: { @@ -856,7 +860,7 @@ export const getDashboardErrorTopGroupsQuery = (mode: TraceAnalyticsMode) => { }, script: 'params.errors / params.total * 100', }, - } + }, }, }, }, @@ -879,26 +883,26 @@ export const getDashboardThroughputTopGroupsQuery = (mode: TraceAnalyticsMode) = multi_terms: { terms: [ { - "field": "process.serviceName" + field: 'process.serviceName', }, { - "field": "operationName" - } + field: 'operationName', + }, ], order: { - 'latency': 'desc' + latency: 'desc', }, - size: 5 + size: 5, }, aggs: { latencies: { avg: { - field: 'duration' - } + field: 'duration', + }, }, trace_count: { cardinality: { - field: mode === 'jaeger' ? 'traceID': 'traceId', + field: mode === 'jaeger' ? 'traceID' : 'traceId', }, }, average_latency: { @@ -938,7 +942,7 @@ export const getDashboardThroughputTopGroupsQuery = (mode: TraceAnalyticsMode) = return Math.round(average_latency_nanos / 10) / 100.0; `, }, - } + }, }, }, }, diff --git a/public/components/trace_analytics/requests/queries/services_queries.ts b/public/components/trace_analytics/requests/queries/services_queries.ts index 46ee1e30d..d5496cd1e 100644 --- a/public/components/trace_analytics/requests/queries/services_queries.ts +++ b/public/components/trace_analytics/requests/queries/services_queries.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { getTenantIndexName } from '../../../../../common/utils/tenant_index_name'; import { DATA_PREPPER_SERVICE_INDEX_NAME, JAEGER_SERVICE_INDEX_NAME, @@ -13,8 +14,13 @@ import { getServiceMapTargetResources } from '../../components/common/helper_fun import { ServiceObject } from '../../components/common/plots/service_map'; import { TraceAnalyticsMode } from '../../home'; -export const getServicesQuery = (mode: TraceAnalyticsMode, serviceName: string | undefined, DSL?: any) => { +export const getServicesQuery = ( + mode: TraceAnalyticsMode, + serviceName: string | undefined, + DSL?: any +) => { const query = { + tenant, size: 0, query: { bool: { @@ -33,7 +39,7 @@ export const getServicesQuery = (mode: TraceAnalyticsMode, serviceName: string | aggs: { trace_count: { cardinality: { - field: mode === 'jaeger'? 'traceID': 'traceId', + field: mode === 'jaeger' ? 'traceID' : 'traceId', }, }, }, @@ -44,21 +50,21 @@ export const getServicesQuery = (mode: TraceAnalyticsMode, serviceName: string | if (serviceName) { query.query.bool.must.push({ term: { - "process.serviceName": serviceName, + 'process.serviceName': serviceName, }, }); } DSL?.custom?.serviceNames?.map((service: string) => { query.query.bool.must.push({ term: { - "process.serviceName": service, + 'process.serviceName': service, }, }); }); DSL?.custom?.serviceNamesExclude?.map((service: string) => { query.query.bool.must_not.push({ term: { - "process.serviceName": service, + 'process.serviceName': service, }, }); }); @@ -66,21 +72,21 @@ export const getServicesQuery = (mode: TraceAnalyticsMode, serviceName: string | if (serviceName) { query.query.bool.must.push({ term: { - "serviceName": serviceName, + serviceName, }, }); } DSL?.custom?.serviceNames?.map((service: string) => { query.query.bool.must.push({ term: { - "serviceName": service, + serviceName: service, }, }); }); DSL?.custom?.serviceNamesExclude?.map((service: string) => { query.query.bool.must_not.push({ term: { - "serviceName": service, + serviceName: service, }, }); }); @@ -88,8 +94,9 @@ export const getServicesQuery = (mode: TraceAnalyticsMode, serviceName: string | return query; }; -export const getRelatedServicesQuery = (serviceName: string) => { +export const getRelatedServicesQuery = (serviceName: string, tenant?: string) => { const query = { + tenant, size: 0, query: { bool: { @@ -118,7 +125,7 @@ export const getRelatedServicesQuery = (serviceName: string) => { must: [ { term: { - "serviceName": serviceName, + serviceName, }, }, ], @@ -133,9 +140,12 @@ export const getRelatedServicesQuery = (serviceName: string) => { return query; }; -export const getServiceNodesQuery = (mode: TraceAnalyticsMode) => { +export const getServiceNodesQuery = (mode: TraceAnalyticsMode, tenant?: string) => { return { - index: mode === 'jaeger' ? JAEGER_SERVICE_INDEX_NAME : DATA_PREPPER_SERVICE_INDEX_NAME, + index: getTenantIndexName( + mode === 'jaeger' ? JAEGER_SERVICE_INDEX_NAME : DATA_PREPPER_SERVICE_INDEX_NAME, + tenant + ), size: 0, query: { bool: { @@ -172,9 +182,16 @@ export const getServiceNodesQuery = (mode: TraceAnalyticsMode) => { }; }; -export const getServiceEdgesQuery = (source: 'destination' | 'target', mode: TraceAnalyticsMode) => { +export const getServiceEdgesQuery = ( + source: 'destination' | 'target', + mode: TraceAnalyticsMode, + tenant?: string +) => { return { - index: mode === 'jaeger' ? JAEGER_SERVICE_INDEX_NAME : DATA_PREPPER_SERVICE_INDEX_NAME, + index: getTenantIndexName( + mode === 'jaeger' ? JAEGER_SERVICE_INDEX_NAME : DATA_PREPPER_SERVICE_INDEX_NAME, + tenant + ), size: 0, query: { bool: { @@ -211,7 +228,12 @@ export const getServiceEdgesQuery = (source: 'destination' | 'target', mode: Tra }; }; -export const getServiceMetricsQuery = (DSL: any, serviceNames: string[], map: ServiceObject, mode: TraceAnalyticsMode) => { +export const getServiceMetricsQuery = ( + DSL: any, + serviceNames: string[], + map: ServiceObject, + mode: TraceAnalyticsMode +) => { const traceGroupFilter = new Set( DSL?.query?.bool.must .filter((must: any) => must.term?.['traceGroup']) @@ -240,7 +262,7 @@ export const getServiceMetricsQuery = (DSL: any, serviceNames: string[], map: Se filter: [ { terms: { - "process.serviceName": serviceNames, + 'process.serviceName': serviceNames, }, }, { diff --git a/public/components/trace_analytics/requests/queries/traces_queries.ts b/public/components/trace_analytics/requests/queries/traces_queries.ts index fbff7cf69..db959b747 100644 --- a/public/components/trace_analytics/requests/queries/traces_queries.ts +++ b/public/components/trace_analytics/requests/queries/traces_queries.ts @@ -8,8 +8,9 @@ import { TRACES_MAX_NUM } from '../../../../../common/constants/trace_analytics' import { SpanSearchParams } from '../../components/traces/span_detail_table'; import { TraceAnalyticsMode } from '../../home'; -export const getTraceGroupPercentilesQuery = () => { +export const getTraceGroupPercentilesQuery = (tenant?: string) => { const query: any = { + tenant, size: 0, query: { bool: { @@ -47,7 +48,11 @@ export const getTraceGroupPercentilesQuery = () => { return query; }; -export const getTracesQuery = (mode: TraceAnalyticsMode, traceId: string = '', sort?: PropertySort) => { +export const getTracesQuery = ( + mode: TraceAnalyticsMode, + traceId: string = '', + sort?: PropertySort +) => { const field = sort?.field || '_key'; const direction = sort?.direction || 'asc'; const jaegerQuery: any = { @@ -173,7 +178,7 @@ export const getTracesQuery = (mode: TraceAnalyticsMode, traceId: string = '', s if (traceId) { jaegerQuery.query.bool.must.push({ term: { - "traceID": traceId, + traceID: traceId, }, }); dataPrepperQuery.query.bool.must.push({ @@ -193,7 +198,7 @@ export const getServiceBreakdownQuery = (traceId: string, mode: TraceAnalyticsMo must: [ { term: { - "traceID": traceId, + traceID: traceId, }, }, ], @@ -276,7 +281,7 @@ export const getServiceBreakdownQuery = (traceId: string, mode: TraceAnalyticsMo }, }, }; - return mode === 'jaeger'? jaegerQuery : dataPrepperQuery; + return mode === 'jaeger' ? jaegerQuery : dataPrepperQuery; }; export const getSpanDetailQuery = (mode: TraceAnalyticsMode, traceId: string, size = 3000) => { @@ -288,7 +293,7 @@ export const getSpanDetailQuery = (mode: TraceAnalyticsMode, traceId: string, si must: [ { term: { - "traceID": traceId, + traceID: traceId, }, }, { @@ -318,11 +323,11 @@ export const getSpanDetailQuery = (mode: TraceAnalyticsMode, traceId: string, si 'spanID', 'tag', 'duration', - 'references' - ] + 'references', + ], }, }; - } + } return { size, query: { @@ -374,7 +379,7 @@ export const getPayloadQuery = (mode: TraceAnalyticsMode, traceId: string, size must: [ { term: { - "traceID": traceId, + traceID: traceId, }, }, ], @@ -413,7 +418,7 @@ export const getSpanFlyoutQuery = (mode: TraceAnalyticsMode, spanId?: string, si must: [ { term: { - "spanID": spanId, + spanID: spanId, }, }, ], @@ -425,6 +430,7 @@ export const getSpanFlyoutQuery = (mode: TraceAnalyticsMode, spanId?: string, si }; } return { + tenant, size, query: { bool: { @@ -443,8 +449,9 @@ export const getSpanFlyoutQuery = (mode: TraceAnalyticsMode, spanId?: string, si }; }; -export const getSpansQuery = (spanSearchParams: SpanSearchParams) => { +export const getSpansQuery = (spanSearchParams: SpanSearchParams, tenant?: string) => { const query: any = { + tenant, size: spanSearchParams.size, from: spanSearchParams.from, query: { @@ -460,8 +467,9 @@ export const getSpansQuery = (spanSearchParams: SpanSearchParams) => { return query; }; -export const getValidTraceIdsQuery = (DSL) => { +export const getValidTraceIdsQuery = (DSL, tenant?: string) => { const query: any = { + tenant, size: 0, query: { bool: { @@ -500,4 +508,4 @@ export const getValidTraceIdsQuery = (DSL) => { }); } return query; -}; \ No newline at end of file +}; diff --git a/public/components/trace_analytics/requests/request_handler.ts b/public/components/trace_analytics/requests/request_handler.ts index bb687183d..54b28439c 100644 --- a/public/components/trace_analytics/requests/request_handler.ts +++ b/public/components/trace_analytics/requests/request_handler.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { getTenantIndexName } from '../../../../common/utils/tenant_index_name'; import { CoreStart } from '../../../../../../src/core/public'; import { TRACE_ANALYTICS_DSL_ROUTE, @@ -18,7 +19,8 @@ export async function handleDslRequest( DSL: any, bodyQuery: any, mode: TraceAnalyticsMode, - setShowTimeoutToast?: () => void + setShowTimeoutToast?: () => void, + tenant?: string ) { if (DSL?.query) { bodyQuery.query.bool.must.push(...DSL.query.bool.must); @@ -30,7 +32,13 @@ export async function handleDslRequest( } let body = bodyQuery; if (!bodyQuery.index) { - body = { ...bodyQuery, index: mode === 'jaeger' ? JAEGER_INDEX_NAME : DATA_PREPPER_INDEX_NAME }; + body = { + ...bodyQuery, + index: getTenantIndexName( + mode === 'jaeger' ? JAEGER_INDEX_NAME : DATA_PREPPER_INDEX_NAME, + tenant + ), + }; } if (setShowTimeoutToast) { const id = setTimeout(() => setShowTimeoutToast(), 25000); // 25 seconds @@ -45,7 +53,6 @@ export async function handleDslRequest( clearTimeout(id); } } else { - try { return await http.post(TRACE_ANALYTICS_DSL_ROUTE, { body: JSON.stringify(body), @@ -58,20 +65,30 @@ export async function handleDslRequest( export async function handleJaegerIndicesExistRequest( http: CoreStart['http'], - setJaegerIndicesExist + setJaegerIndicesExist, + tenant?: string ) { http - .post(TRACE_ANALYTICS_JAEGER_INDICES_ROUTE) + .post(TRACE_ANALYTICS_JAEGER_INDICES_ROUTE, { + body: JSON.stringify({ + tenant, + }), + }) .then((exists) => setJaegerIndicesExist(exists)) .catch(() => setJaegerIndicesExist(false)); } export async function handleDataPrepperIndicesExistRequest( http: CoreStart['http'], - setDataPrepperIndicesExist + setDataPrepperIndicesExist, + tenant?: string ) { http - .post(TRACE_ANALYTICS_DATA_PREPPER_INDICES_ROUTE) + .post(TRACE_ANALYTICS_DATA_PREPPER_INDICES_ROUTE, { + body: JSON.stringify({ + tenant, + }), + }) .then((exists) => setDataPrepperIndicesExist(exists)) .catch(() => setDataPrepperIndicesExist(false)); } diff --git a/public/components/trace_analytics/requests/services_request_handler.ts b/public/components/trace_analytics/requests/services_request_handler.ts index 2c0152dff..587de2d61 100644 --- a/public/components/trace_analytics/requests/services_request_handler.ts +++ b/public/components/trace_analytics/requests/services_request_handler.ts @@ -2,7 +2,6 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ -/* eslint-disable no-console */ import _ from 'lodash'; import dateMath from '@elastic/datemath'; @@ -26,10 +25,18 @@ export const handleServicesRequest = async ( mode: TraceAnalyticsMode, setServiceMap?: any, serviceNameFilter?: string, + tenant?: string ) => { return handleDslRequest(http, DSL, getServicesQuery(mode, serviceNameFilter, DSL), mode) .then(async (response) => { - const serviceObject: ServiceObject = await handleServiceMapRequest(http, DSL, mode, setServiceMap); + const serviceObject: ServiceObject = await handleServiceMapRequest( + http, + DSL, + mode, + setServiceMap, + undefined, + tenant + ); return Promise.all( response.aggregations.service.buckets .filter((bucket: any) => serviceObject[bucket.key]) @@ -62,6 +69,7 @@ export const handleServiceMapRequest = async ( mode: TraceAnalyticsMode, setItems?: any, currService?: string, + tenant?: string ) => { let minutesInDateRange: number; const startTime = DSL.custom?.timeFilter?.[0]?.range?.startTime; @@ -72,7 +80,7 @@ export const handleServiceMapRequest = async ( } const map: ServiceObject = {}; let id = 1; - await handleDslRequest(http, null, getServiceNodesQuery(mode), mode) + await handleDslRequest(http, null, getServiceNodesQuery(mode, tenant), mode) .then((response) => response.aggregations.service_name.buckets.map( (bucket: any) => @@ -91,7 +99,7 @@ export const handleServiceMapRequest = async ( .catch((error) => console.error(error)); const targets = {}; - await handleDslRequest(http, null, getServiceEdgesQuery('target', mode), mode) + await handleDslRequest(http, null, getServiceEdgesQuery('target', mode, tenant), mode) .then((response) => response.aggregations.service_name.buckets.map((bucket: any) => { bucket.resource.buckets.map((resource: any) => { @@ -102,7 +110,7 @@ export const handleServiceMapRequest = async ( }) ) .catch((error) => console.error(error)); - await handleDslRequest(http, null, getServiceEdgesQuery('destination', mode), mode) + await handleDslRequest(http, null, getServiceEdgesQuery('destination', mode, tenant), mode) .then((response) => Promise.all( response.aggregations.service_name.buckets.map((bucket: any) => { @@ -126,8 +134,10 @@ export const handleServiceMapRequest = async ( const latencies = await handleDslRequest( http, DSL, - getServiceMetricsQuery(DSL, Object.keys(map), map, mode), + getServiceMetricsQuery(DSL, Object.keys(map), map, mode), mode, + undefined, + tenant ); latencies.aggregations.service_name.buckets.map((bucket: any) => { map[bucket.key].latency = bucket.average_latency.value; @@ -138,7 +148,7 @@ export const handleServiceMapRequest = async ( }); if (currService) { - await handleDslRequest(http, DSL, getRelatedServicesQuery(currService), mode) + await handleDslRequest(http, DSL, getRelatedServicesQuery(currService), mode, undefined, tenant) .then((response) => response.aggregations.traces.buckets.filter((bucket: any) => bucket.service.doc_count > 0) ) @@ -164,12 +174,20 @@ export const handleServiceViewRequest = ( DSL: any, setFields: any, mode: TraceAnalyticsMode, + tenant?: string ) => { - handleDslRequest(http, DSL, getServicesQuery(mode, serviceName), mode) + handleDslRequest(http, DSL, getServicesQuery(mode, serviceName), mode, undefined, tenant) .then(async (response) => { const bucket = response.aggregations.service.buckets[0]; if (!bucket) return {}; - const serviceObject: ServiceObject = await handleServiceMapRequest(http, DSL, mode); + const serviceObject: ServiceObject = await handleServiceMapRequest( + http, + DSL, + mode, + undefined, + undefined, + tenant + ); const connectedServices = [ ...serviceObject[bucket.key].targetServices, ...serviceObject[bucket.key].destServices, diff --git a/public/components/trace_analytics/requests/traces_request_handler.ts b/public/components/trace_analytics/requests/traces_request_handler.ts index 0ed7a0205..78dcf057a 100644 --- a/public/components/trace_analytics/requests/traces_request_handler.ts +++ b/public/components/trace_analytics/requests/traces_request_handler.ts @@ -2,12 +2,11 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ -/* eslint-disable no-console */ -import { BarOrientation } from '../../../../common/constants/shared'; import _ from 'lodash'; import moment from 'moment'; import { v1 as uuid } from 'uuid'; +import { BarOrientation } from '../../../../common/constants/shared'; import { HttpSetup } from '../../../../../../src/core/public'; import { TRACE_ANALYTICS_DATE_FORMAT } from '../../../../common/constants/trace_analytics'; import { microToMilliSec, nanoToMilliSec } from '../components/common/helper_functions'; @@ -39,6 +38,7 @@ export const handleTracesRequest = async ( setItems: (items: any) => void, mode: TraceAnalyticsMode, sort?: any, + tenant?: string ) => { const binarySearch = (arr: number[], target: number) => { if (!arr) return Number.NaN; @@ -58,7 +58,9 @@ export const handleTracesRequest = async ( http, timeFilterDSL, getTraceGroupPercentilesQuery(), - mode + mode, + undefined, + tenant ).then((response) => { const map: any = {}; response.aggregations.trace_group_name.buckets.forEach((traceGroup: any) => { @@ -69,11 +71,11 @@ export const handleTracesRequest = async ( return map; }); - return handleDslRequest(http, DSL, getTracesQuery(mode, undefined, sort), mode) + return handleDslRequest(http, DSL, getTracesQuery(mode, undefined, sort), mode, undefined, tenant) .then((response) => { return Promise.all( response.aggregations.traces.buckets.map((bucket: any) => { - if (mode === 'data_prepper') { + if (mode === 'data_prepper') { return { trace_id: bucket.key, trace_group: bucket.trace_group.buckets[0]?.key, @@ -86,15 +88,14 @@ export const handleTracesRequest = async ( ), actions: '#', }; - } - return { - trace_id: bucket.key, - latency: bucket.latency.value, - last_updated: moment(bucket.last_updated.value).format(TRACE_ANALYTICS_DATE_FORMAT), - error_count: bucket.error_count.doc_count, - actions: '#', - }; - + } + return { + trace_id: bucket.key, + latency: bucket.latency.value, + last_updated: moment(bucket.last_updated.value).format(TRACE_ANALYTICS_DATE_FORMAT), + error_count: bucket.error_count.doc_count, + actions: '#', + }; }) ); }) @@ -110,8 +111,9 @@ export const handleTraceViewRequest = ( fields: {}, setFields: (fields: any) => void, mode: TraceAnalyticsMode, + tenant?: string ) => { - handleDslRequest(http, null, getTracesQuery(mode, traceId), mode) + handleDslRequest(http, null, getTracesQuery(mode, traceId), mode, undefined, tenant) .then(async (response) => { const bucket = response.aggregations.traces.buckets[0]; return { @@ -139,6 +141,7 @@ export const handleServicesPieChartRequest = async ( setServiceBreakdownData: (serviceBreakdownData: any) => void, setColorMap: (colorMap: any) => void, mode: TraceAnalyticsMode, + tenant?: string ) => { const colors = [ '#7492e7', @@ -156,7 +159,14 @@ export const handleServicesPieChartRequest = async ( ]; const colorMap: any = {}; let index = 0; - await handleDslRequest(http, null, getServiceBreakdownQuery(traceId, mode), mode) + await handleDslRequest( + http, + null, + getServiceBreakdownQuery(traceId, mode), + mode, + undefined, + tenant + ) .then((response) => Promise.all( response.aggregations.service_type.buckets.map((bucket: any) => { @@ -202,8 +212,9 @@ export const handleSpansGanttRequest = ( colorMap: any, spanFiltersDSL: any, mode: TraceAnalyticsMode, + tenant?: string ) => { - handleDslRequest(http, spanFiltersDSL, getSpanDetailQuery(mode, traceId), mode) + handleDslRequest(http, spanFiltersDSL, getSpanDetailQuery(mode, traceId), mode, undefined, tenant) .then((response) => hitsToSpanDetailData(response.hits.hits, colorMap, mode)) .then((newItems) => setSpanDetailData(newItems)) .catch((error) => console.error(error)); @@ -213,7 +224,7 @@ export const handleSpansFlyoutRequest = ( http: HttpSetup, spanId: string, setItems: (items: any) => void, - mode: TraceAnalyticsMode, + mode: TraceAnalyticsMode ) => { handleDslRequest(http, null, getSpanFlyoutQuery(mode, spanId), mode) .then((response) => { @@ -230,15 +241,35 @@ const hitsToSpanDetailData = async (hits: any, colorMap: any, mode: TraceAnalyti }; if (hits.length === 0) return data; - const minStartTime = mode === 'jaeger' ? microToMilliSec(hits[hits.length - 1].sort[0]) : nanoToMilliSec(hits[hits.length - 1].sort[0]); + const minStartTime = + mode === 'jaeger' + ? microToMilliSec(hits[hits.length - 1].sort[0]) + : nanoToMilliSec(hits[hits.length - 1].sort[0]); let maxEndTime = 0; hits.forEach((hit: any) => { - const startTime = mode === 'jaeger' ? microToMilliSec(hit.sort[0]) - minStartTime : nanoToMilliSec(hit.sort[0]) - minStartTime; - const duration = mode === 'jaeger' ? _.round(microToMilliSec(hit._source.duration), 2) : _.round(nanoToMilliSec(hit._source.durationInNanos), 2);; - const serviceName = mode === 'jaeger'? _.get(hit, ['_source', 'process'])['serviceName'] : _.get(hit, ['_source', 'serviceName']); - const name = mode === 'jaeger' ? _.get(hit, '_source.operationName') : _.get(hit, '_source.name'); - const error = mode === 'jaeger' ? (hit._source['tag']['error'] === true ? ' \u26a0 Error' : '') : (hit._source['status.code'] === 2 ? ' \u26a0 Error' : ''); + const startTime = + mode === 'jaeger' + ? microToMilliSec(hit.sort[0]) - minStartTime + : nanoToMilliSec(hit.sort[0]) - minStartTime; + const duration = + mode === 'jaeger' + ? _.round(microToMilliSec(hit._source.duration), 2) + : _.round(nanoToMilliSec(hit._source.durationInNanos), 2); + const serviceName = + mode === 'jaeger' + ? _.get(hit, ['_source', 'process']).serviceName + : _.get(hit, ['_source', 'serviceName']); + const name = + mode === 'jaeger' ? _.get(hit, '_source.operationName') : _.get(hit, '_source.name'); + const error = + mode === 'jaeger' + ? hit._source.tag.error === true + ? ' \u26a0 Error' + : '' + : hit._source['status.code'] === 2 + ? ' \u26a0 Error' + : ''; const uniqueLabel = `${serviceName}
${name} ` + uuid(); maxEndTime = Math.max(maxEndTime, startTime + duration); @@ -293,8 +324,9 @@ export const handlePayloadRequest = ( payloadData: any, setPayloadData: (payloadData: any) => void, mode: TraceAnalyticsMode, + tenant?: string ) => { - handleDslRequest(http, null, getPayloadQuery(mode, traceId), mode) + handleDslRequest(http, null, getPayloadQuery(mode, traceId), mode, undefined, tenant) .then((response) => setPayloadData(JSON.stringify(response.hits.hits, null, 2))) .catch((error) => console.error(error)); }; @@ -305,7 +337,7 @@ export const handleSpansRequest = ( setTotal: (total: number) => void, spanSearchParams: SpanSearchParams, DSL: any, - mode: TraceAnalyticsMode, + mode: TraceAnalyticsMode ) => { handleDslRequest(http, DSL, getSpansQuery(spanSearchParams), mode) .then((response) => { diff --git a/public/plugin.ts b/public/plugin.ts index aef5db217..afebc61d3 100644 --- a/public/plugin.ts +++ b/public/plugin.ts @@ -80,13 +80,16 @@ import { SetupDependencies, } from './types'; -interface PublicConfig { +export interface PublicConfig { query_assist: { enabled: boolean; }; summarize: { enabled: boolean; }; + multitenancy: { + enabled: boolean; + }; } export class ObservabilityPlugin @@ -209,7 +212,8 @@ export class ObservabilityPlugin timestampUtils, qm, startPage, - dataSourcePluggables // just pass down for now due to time constraint, later may better expose this as context + dataSourcePluggables, // just pass down for now due to time constraint, later may better expose this as context + this.config ); }; From a53308e6ab9332734e8fdcd3a9b0670b3c1052d2 Mon Sep 17 00:00:00 2001 From: Julian Quispel Date: Wed, 7 Feb 2024 11:24:25 +0100 Subject: [PATCH 04/12] Fix undefined tenant Signed-off-by: Julian Quispel --- .../trace_analytics/requests/queries/services_queries.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/public/components/trace_analytics/requests/queries/services_queries.ts b/public/components/trace_analytics/requests/queries/services_queries.ts index d5496cd1e..4de48cc05 100644 --- a/public/components/trace_analytics/requests/queries/services_queries.ts +++ b/public/components/trace_analytics/requests/queries/services_queries.ts @@ -20,7 +20,6 @@ export const getServicesQuery = ( DSL?: any ) => { const query = { - tenant, size: 0, query: { bool: { From a55978cf8f41b55494187425d39029930a0757fd Mon Sep 17 00:00:00 2001 From: Julian Quispel Date: Thu, 8 Feb 2024 09:25:11 +0100 Subject: [PATCH 05/12] Remove tenant from queries Signed-off-by: Julian Quispel --- .../requests/queries/services_queries.ts | 3 +-- .../trace_analytics/requests/queries/traces_queries.ts | 10 +++------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/public/components/trace_analytics/requests/queries/services_queries.ts b/public/components/trace_analytics/requests/queries/services_queries.ts index 4de48cc05..f04a7a16c 100644 --- a/public/components/trace_analytics/requests/queries/services_queries.ts +++ b/public/components/trace_analytics/requests/queries/services_queries.ts @@ -93,9 +93,8 @@ export const getServicesQuery = ( return query; }; -export const getRelatedServicesQuery = (serviceName: string, tenant?: string) => { +export const getRelatedServicesQuery = (serviceName: string) => { const query = { - tenant, size: 0, query: { bool: { diff --git a/public/components/trace_analytics/requests/queries/traces_queries.ts b/public/components/trace_analytics/requests/queries/traces_queries.ts index db959b747..dbaf4fe10 100644 --- a/public/components/trace_analytics/requests/queries/traces_queries.ts +++ b/public/components/trace_analytics/requests/queries/traces_queries.ts @@ -8,9 +8,8 @@ import { TRACES_MAX_NUM } from '../../../../../common/constants/trace_analytics' import { SpanSearchParams } from '../../components/traces/span_detail_table'; import { TraceAnalyticsMode } from '../../home'; -export const getTraceGroupPercentilesQuery = (tenant?: string) => { +export const getTraceGroupPercentilesQuery = () => { const query: any = { - tenant, size: 0, query: { bool: { @@ -430,7 +429,6 @@ export const getSpanFlyoutQuery = (mode: TraceAnalyticsMode, spanId?: string, si }; } return { - tenant, size, query: { bool: { @@ -449,9 +447,8 @@ export const getSpanFlyoutQuery = (mode: TraceAnalyticsMode, spanId?: string, si }; }; -export const getSpansQuery = (spanSearchParams: SpanSearchParams, tenant?: string) => { +export const getSpansQuery = (spanSearchParams: SpanSearchParams) => { const query: any = { - tenant, size: spanSearchParams.size, from: spanSearchParams.from, query: { @@ -467,9 +464,8 @@ export const getSpansQuery = (spanSearchParams: SpanSearchParams, tenant?: strin return query; }; -export const getValidTraceIdsQuery = (DSL, tenant?: string) => { +export const getValidTraceIdsQuery = (DSL) => { const query: any = { - tenant, size: 0, query: { bool: { From 20c27490ee19cb8f494bc511a522b0340e713ff6 Mon Sep 17 00:00:00 2001 From: Julian Quispel Date: Thu, 2 May 2024 20:38:54 +0200 Subject: [PATCH 06/12] Remove unused imports and logs --- .../components/config_components/service_config.tsx | 4 ++-- .../components/flyout_components/service_detail_flyout.tsx | 4 ++-- .../trace_analytics/components/traces/trace_view.tsx | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/public/components/application_analytics/components/config_components/service_config.tsx b/public/components/application_analytics/components/config_components/service_config.tsx index 09222fb0d..af9da91d3 100644 --- a/public/components/application_analytics/components/config_components/service_config.tsx +++ b/public/components/application_analytics/components/config_components/service_config.tsx @@ -24,7 +24,6 @@ import { handleServiceMapRequest } from '../../../trace_analytics/requests/servi import { AppAnalyticsComponentDeps } from '../../home'; import { OptionType } from '../../../../../common/types/application_analytics'; import { getClearModal } from '../../helpers/modal_containers'; -import { tenantName } from '../../../../components/trace_analytics/components/common/indices'; interface ServiceConfigProps extends AppAnalyticsComponentDeps { dslService: DSLService; @@ -40,6 +39,7 @@ export const ServiceConfig = (props: ServiceConfigProps) => { http, selectedServices, setSelectedServices, + tenant, } = props; const { mode } = props; const [servicesOpen, setServicesOpen] = useState(false); @@ -51,7 +51,7 @@ export const ServiceConfig = (props: ServiceConfigProps) => { const [modalLayout, setModalLayout] = useState(); useEffect(() => { - handleServiceMapRequest(http, dslService, mode, setServiceMap, undefined, tenantName); + handleServiceMapRequest(http, dslService, mode, setServiceMap, undefined, tenant); }, []); useEffect(() => { diff --git a/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx b/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx index 455643123..c1f01dd27 100644 --- a/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx +++ b/public/components/application_analytics/components/flyout_components/service_detail_flyout.tsx @@ -28,7 +28,6 @@ import { ServiceObject } from '../../../../../public/components/trace_analytics/ import { SpanDetailTable } from '../../../../../public/components/trace_analytics/components/traces/span_detail_table'; import { TraceAnalyticsComponentDeps } from '../../../../../public/components/trace_analytics/home'; import { getListItem } from '../../helpers/utils'; -import { tenantName } from '../../../../components/trace_analytics/components/common/indices'; interface ServiceFlyoutProps extends TraceAnalyticsComponentDeps { serviceName: string; @@ -49,6 +48,7 @@ export function ServiceDetailFlyout(props: ServiceFlyoutProps) { closeServiceFlyout, openSpanFlyout, mode, + tenant, } = props; const [fields, setFields] = useState({}); const [serviceMap, setServiceMap] = useState({}); @@ -132,7 +132,7 @@ export function ServiceDetailFlyout(props: ServiceFlyoutProps) { appConfigs ); handleServiceViewRequest(serviceName, http, serviceDSL, setFields, mode); - handleServiceMapRequest(http, serviceDSL, mode, setServiceMap, serviceName, tenantName); + handleServiceMapRequest(http, serviceDSL, mode, setServiceMap, serviceName, tenant); const spanDSL = filtersToDsl(mode, filters, query, startTime, endTime, 'app', appConfigs); spanDSL.query.bool.must.push({ term: { diff --git a/public/components/trace_analytics/components/traces/trace_view.tsx b/public/components/trace_analytics/components/traces/trace_view.tsx index 2cc87f3e9..ccc4f5a81 100644 --- a/public/components/trace_analytics/components/traces/trace_view.tsx +++ b/public/components/trace_analytics/components/traces/trace_view.tsx @@ -161,7 +161,6 @@ export function TraceView(props: TraceViewProps) { processTimeStamp('now', mode), page ); - console.log('tenant', tenant); handleTraceViewRequest(props.traceId, props.http, fields, setFields, mode, tenant); handlePayloadRequest(props.traceId, props.http, payloadData, setPayloadData, mode, tenant); handleServicesPieChartRequest( From b6b8117d29ac3d2846dccb79f0b2f5ffe9df0a14 Mon Sep 17 00:00:00 2001 From: Julian Quispel Date: Thu, 2 May 2024 21:54:35 +0200 Subject: [PATCH 07/12] Replace fetch with http Signed-off-by: Julian Quispel --- .../components/common/indices.ts | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/public/components/trace_analytics/components/common/indices.ts b/public/components/trace_analytics/components/common/indices.ts index 5978cad1c..c98d7cd10 100644 --- a/public/components/trace_analytics/components/common/indices.ts +++ b/public/components/trace_analytics/components/common/indices.ts @@ -3,27 +3,29 @@ * SPDX-License-Identifier: Apache-2.0 */ -export async function loadTenantInfo(multitenancyEnabled: boolean) { +import { CoreStart } from '../../../../../../../src/core/public'; + +export async function loadTenantInfo(http: CoreStart['http'], multitenancyEnabled: boolean) { if (!multitenancyEnabled) { return; } - return await fetch(`../api/v1/multitenancy/tenant`, { - headers: { - 'Content-Type': 'application/json', - 'osd-xsrf': 'true', - accept: '*/*', - 'accept-language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6', - pragma: 'no-cache', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - }, - method: 'GET', - referrerPolicy: 'strict-origin-when-cross-origin', - mode: 'cors', - credentials: 'include', - }) + return await http + .get(`../api/v1/multitenancy/tenant`, { + headers: { + 'Content-Type': 'application/json', + 'osd-xsrf': 'true', + accept: '*/*', + 'accept-language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6', + pragma: 'no-cache', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + }, + referrerPolicy: 'strict-origin-when-cross-origin', + mode: 'cors', + credentials: 'include', + }) .then((response) => { if (response.status === 404) { // endpoint doesn't exist, security plugin is not enabled. From 21c61ccaa32dce04a8424fbb37ea6b192e639c84 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Thu, 2 May 2024 20:34:32 +0000 Subject: [PATCH 08/12] fix runtime errors Signed-off-by: Joshua Li --- .../components/common/indices.ts | 31 +++++-------------- public/components/trace_analytics/home.tsx | 4 +-- public/plugin.tsx | 3 +- server/routes/trace_analytics_dsl_router.ts | 2 +- 4 files changed, 13 insertions(+), 27 deletions(-) diff --git a/public/components/trace_analytics/components/common/indices.ts b/public/components/trace_analytics/components/common/indices.ts index c98d7cd10..a850a3087 100644 --- a/public/components/trace_analytics/components/common/indices.ts +++ b/public/components/trace_analytics/components/common/indices.ts @@ -11,33 +11,18 @@ export async function loadTenantInfo(http: CoreStart['http'], multitenancyEnable } return await http - .get(`../api/v1/multitenancy/tenant`, { - headers: { - 'Content-Type': 'application/json', - 'osd-xsrf': 'true', - accept: '*/*', - 'accept-language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6', - pragma: 'no-cache', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - }, - referrerPolicy: 'strict-origin-when-cross-origin', - mode: 'cors', - credentials: 'include', - }) - .then((response) => { - if (response.status === 404) { - // endpoint doesn't exist, security plugin is not enabled. - return undefined; - } else { - return response.text(); - } - }) + .get('/api/v1/multitenancy/tenant') .then((tenant) => { if (tenant === '' || tenant === '__user__') { tenant = ''; } return tenant; + }) + .catch((error) => { + if (error.body.statusCode === 404) { + // endpoint doesn't exist, security plugin is not enabled. + return undefined; + } + console.error(`failed to request tenant: ${String(error)}`); }); } diff --git a/public/components/trace_analytics/home.tsx b/public/components/trace_analytics/home.tsx index b57fc28fd..1d17a6e0a 100644 --- a/public/components/trace_analytics/home.tsx +++ b/public/components/trace_analytics/home.tsx @@ -108,7 +108,7 @@ export const Home = (props: HomeProps) => { useEffect(() => { if (!tenantLoaded) - loadTenantInfo(props.config.multitenancy.enabled).then((tenant) => { + loadTenantInfo(props.http, props.config.multitenancy.enabled).then((tenant) => { setTenantLoaded(true); setTenantName(tenant); handleDataPrepperIndicesExistRequest( @@ -118,7 +118,7 @@ export const Home = (props: HomeProps) => { dataSourceMDSId[0].id ); handleJaegerIndicesExistRequest(props.http, setJaegerIndicesExist, tenant); - }, dataSourceMDSId[0].id); + }); }, [props.config.multitenancy.enabled, tenantLoaded, dataSourceMDSId]); const modes = [ diff --git a/public/plugin.tsx b/public/plugin.tsx index d8a1487e8..c7a46dd08 100644 --- a/public/plugin.tsx +++ b/public/plugin.tsx @@ -269,7 +269,8 @@ export class ObservabilityPlugin startPage, dataSourcePluggables, // just pass down for now due to time constraint, later may better expose this as context dataSourceManagement, - coreStart.savedObjects + coreStart.savedObjects, + this.config ); }; diff --git a/server/routes/trace_analytics_dsl_router.ts b/server/routes/trace_analytics_dsl_router.ts index 732857316..df7f18c43 100644 --- a/server/routes/trace_analytics_dsl_router.ts +++ b/server/routes/trace_analytics_dsl_router.ts @@ -68,7 +68,7 @@ export function registerTraceAnalyticsDslRouter(router: IRouter, dataSourceEnabl { path: TRACE_ANALYTICS_JAEGER_INDICES_ROUTE, validate: { - body: chema.object({ + body: schema.object({ tenant: schema.maybe(schema.string()), }), query: schema.object({ From f519b790199f477f8f484d0d756f42544ba8518d Mon Sep 17 00:00:00 2001 From: Julian Quispel Date: Mon, 27 May 2024 20:47:17 +0200 Subject: [PATCH 09/12] Update public/components/trace_analytics/home.tsx Co-authored-by: Joshua Li Signed-off-by: Julian Quispel --- public/components/trace_analytics/home.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/components/trace_analytics/home.tsx b/public/components/trace_analytics/home.tsx index 1d17a6e0a..b5bcba77c 100644 --- a/public/components/trace_analytics/home.tsx +++ b/public/components/trace_analytics/home.tsx @@ -117,7 +117,7 @@ export const Home = (props: HomeProps) => { tenant, dataSourceMDSId[0].id ); - handleJaegerIndicesExistRequest(props.http, setJaegerIndicesExist, tenant); + handleJaegerIndicesExistRequest(props.http, setJaegerIndicesExist, dataSourceMDSId[0].id, tenant); }); }, [props.config.multitenancy.enabled, tenantLoaded, dataSourceMDSId]); From 290203a39abaab3a9050d3dbbf5f7135c4a3d858 Mon Sep 17 00:00:00 2001 From: Julian Quispel Date: Mon, 27 May 2024 20:48:17 +0200 Subject: [PATCH 10/12] Swap lines in trace analytics home --- public/components/trace_analytics/home.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/components/trace_analytics/home.tsx b/public/components/trace_analytics/home.tsx index 1d17a6e0a..290298e49 100644 --- a/public/components/trace_analytics/home.tsx +++ b/public/components/trace_analytics/home.tsx @@ -114,8 +114,8 @@ export const Home = (props: HomeProps) => { handleDataPrepperIndicesExistRequest( props.http, setDataPrepperIndicesExist, - tenant, - dataSourceMDSId[0].id + dataSourceMDSId[0].id, + tenant ); handleJaegerIndicesExistRequest(props.http, setJaegerIndicesExist, tenant); }); From b8e94d74dd66d91080bf23f9aa78d06f7041a11f Mon Sep 17 00:00:00 2001 From: Julian Quispel Date: Mon, 27 May 2024 20:56:49 +0200 Subject: [PATCH 11/12] Add dataSourceMDSId --- public/components/trace_analytics/home.tsx | 7 ++++++- .../requests/dashboard_request_handler.ts | 11 +++++++++-- server/routes/trace_analytics_dsl_router.ts | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/public/components/trace_analytics/home.tsx b/public/components/trace_analytics/home.tsx index 9f6942095..3dcea94de 100644 --- a/public/components/trace_analytics/home.tsx +++ b/public/components/trace_analytics/home.tsx @@ -117,7 +117,12 @@ export const Home = (props: HomeProps) => { dataSourceMDSId[0].id, tenant ); - handleJaegerIndicesExistRequest(props.http, setJaegerIndicesExist, dataSourceMDSId[0].id, tenant); + handleJaegerIndicesExistRequest( + props.http, + setJaegerIndicesExist, + dataSourceMDSId[0].id, + tenant + ); }); }, [props.config.multitenancy.enabled, tenantLoaded, dataSourceMDSId]); diff --git a/public/components/trace_analytics/requests/dashboard_request_handler.ts b/public/components/trace_analytics/requests/dashboard_request_handler.ts index 24af2faa1..71bae4667 100644 --- a/public/components/trace_analytics/requests/dashboard_request_handler.ts +++ b/public/components/trace_analytics/requests/dashboard_request_handler.ts @@ -394,9 +394,16 @@ export const handleDashboardThroughputPltRequest = ( fixedInterval, items, setItems, - mode + mode, + dataSourceMDSId? ) => { - return handleDslRequest(http, DSL, getDashboardThroughputPltQuery(mode, fixedInterval), mode) + return handleDslRequest( + http, + DSL, + getDashboardThroughputPltQuery(mode, fixedInterval), + mode, + dataSourceMDSId + ) .then((response) => { const buckets = response.aggregations.throughput.buckets; const texts = buckets.map( diff --git a/server/routes/trace_analytics_dsl_router.ts b/server/routes/trace_analytics_dsl_router.ts index df7f18c43..5d4725d98 100644 --- a/server/routes/trace_analytics_dsl_router.ts +++ b/server/routes/trace_analytics_dsl_router.ts @@ -148,7 +148,7 @@ export function registerTraceAnalyticsDslRouter(router: IRouter, dataSourceEnabl }, async (context, request, response) => { addRequestToMetric('trace_analytics', 'get', 'count'); - const { index, size, ...rest } = request.body; + const { index, size, tenant, ...rest } = request.body; const { dataSourceMDSId } = request.query; const params: RequestParams.Search = { index: index || getTenantIndexName(DATA_PREPPER_INDEX_NAME, tenant), From 9210dac004e2a91bea0c10d0e3b411878f32b4c9 Mon Sep 17 00:00:00 2001 From: Julian Quispel Date: Mon, 27 May 2024 20:58:38 +0200 Subject: [PATCH 12/12] Add dataSourceMDSId to handleDashboardErrorRatePltRequest --- .../requests/dashboard_request_handler.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/public/components/trace_analytics/requests/dashboard_request_handler.ts b/public/components/trace_analytics/requests/dashboard_request_handler.ts index 71bae4667..5d53acbd6 100644 --- a/public/components/trace_analytics/requests/dashboard_request_handler.ts +++ b/public/components/trace_analytics/requests/dashboard_request_handler.ts @@ -441,9 +441,16 @@ export const handleDashboardErrorRatePltRequest = ( fixedInterval, items, setItems, - mode + mode, + dataSourceMDSId? ) => { - return handleDslRequest(http, DSL, getErrorRatePltQuery(mode, fixedInterval), mode) + return handleDslRequest( + http, + DSL, + getErrorRatePltQuery(mode, fixedInterval), + mode, + dataSourceMDSId + ) .then((response) => { const buckets = response.aggregations.error_rate.buckets; const texts = buckets.map(