diff --git a/src/plugins/apm_oss/server/index.ts b/src/plugins/apm_oss/server/index.ts index ae7b70339cabc..bea9965748f27 100644 --- a/src/plugins/apm_oss/server/index.ts +++ b/src/plugins/apm_oss/server/index.ts @@ -21,6 +21,7 @@ export const config = { sourcemapIndices: schema.string({ defaultValue: 'apm-*' }), onboardingIndices: schema.string({ defaultValue: 'apm-*' }), indexPattern: schema.string({ defaultValue: 'apm-*' }), + fleetMode: schema.boolean({ defaultValue: true }), }), }; diff --git a/x-pack/plugins/apm/common/processor_event.ts b/x-pack/plugins/apm/common/processor_event.ts index 63cbb18cacc97..9eb9ee60c1998 100644 --- a/x-pack/plugins/apm/common/processor_event.ts +++ b/x-pack/plugins/apm/common/processor_event.ts @@ -10,8 +10,6 @@ export enum ProcessorEvent { error = 'error', metric = 'metric', span = 'span', - onboarding = 'onboarding', - sourcemap = 'sourcemap', } /** * Processor events that are searchable in the UI via the query bar. diff --git a/x-pack/plugins/apm/public/components/shared/KueryBar/index.tsx b/x-pack/plugins/apm/public/components/shared/KueryBar/index.tsx index efa4f26d9a23f..ff34359d83c76 100644 --- a/x-pack/plugins/apm/public/components/shared/KueryBar/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/KueryBar/index.tsx @@ -66,7 +66,7 @@ export function KueryBar(props: { prepend?: React.ReactNode | string }) { const example = examples[processorEvent || 'defaults']; - const { indexPattern } = useDynamicIndexPatternFetcher(processorEvent); + const { indexPattern } = useDynamicIndexPatternFetcher(); const placeholder = i18n.translate('xpack.apm.kueryBar.placeholder', { defaultMessage: `Search {event, select, diff --git a/x-pack/plugins/apm/public/hooks/use_dynamic_index_pattern.ts b/x-pack/plugins/apm/public/hooks/use_dynamic_index_pattern.ts index 8d0af2385df29..9c637dc1336ad 100644 --- a/x-pack/plugins/apm/public/hooks/use_dynamic_index_pattern.ts +++ b/x-pack/plugins/apm/public/hooks/use_dynamic_index_pattern.ts @@ -6,25 +6,14 @@ */ import { useFetcher } from './use_fetcher'; -import { UIProcessorEvent } from '../../common/processor_event'; -export function useDynamicIndexPatternFetcher( - processorEvent: UIProcessorEvent | undefined -) { - const { data, status } = useFetcher( - (callApmApi) => { - return callApmApi({ - endpoint: 'GET /api/apm/index_pattern/dynamic', - isCachable: true, - params: { - query: { - processorEvent, - }, - }, - }); - }, - [processorEvent] - ); +export function useDynamicIndexPatternFetcher() { + const { data, status } = useFetcher((callApmApi) => { + return callApmApi({ + endpoint: 'GET /api/apm/index_pattern/dynamic', + isCachable: true, + }); + }, []); return { indexPattern: data?.dynamicIndexPattern, diff --git a/x-pack/plugins/apm/server/index.test.ts b/x-pack/plugins/apm/server/index.test.ts new file mode 100644 index 0000000000000..006a21b597458 --- /dev/null +++ b/x-pack/plugins/apm/server/index.test.ts @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* eslint-disable @typescript-eslint/naming-convention */ + +import { APMOSSConfig } from 'src/plugins/apm_oss/server'; +import { APMXPackConfig } from '.'; +import { mergeConfigs } from './index'; + +describe('mergeConfigs', () => { + it('merges the configs', () => { + const apmOssConfig = { + transactionIndices: 'apm-*-transaction-*', + spanIndices: 'apm-*-span-*', + errorIndices: 'apm-*-error-*', + metricsIndices: 'apm-*-metric-*', + indexPattern: 'apm-*', + } as APMOSSConfig; + + const apmConfig = { + ui: { enabled: false }, + enabled: true, + metricsInterval: 2000, + } as APMXPackConfig; + + expect(mergeConfigs(apmOssConfig, apmConfig)).toEqual({ + 'apm_oss.errorIndices': 'apm-*-error-*', + 'apm_oss.indexPattern': 'apm-*', + 'apm_oss.metricsIndices': 'apm-*-metric-*', + 'apm_oss.spanIndices': 'apm-*-span-*', + 'apm_oss.transactionIndices': 'apm-*-transaction-*', + 'xpack.apm.metricsInterval': 2000, + 'xpack.apm.ui.enabled': false, + }); + }); + + it('adds fleet indices', () => { + const apmOssConfig = { + transactionIndices: 'apm-*-transaction-*', + spanIndices: 'apm-*-span-*', + errorIndices: 'apm-*-error-*', + metricsIndices: 'apm-*-metric-*', + fleetMode: true, + } as APMOSSConfig; + + const apmConfig = { ui: {} } as APMXPackConfig; + + expect(mergeConfigs(apmOssConfig, apmConfig)).toEqual({ + 'apm_oss.errorIndices': 'logs-apm*,apm-*-error-*', + 'apm_oss.metricsIndices': 'metrics-apm*,apm-*-metric-*', + 'apm_oss.spanIndices': 'traces-apm*,apm-*-span-*', + 'apm_oss.transactionIndices': 'traces-apm*,apm-*-transaction-*', + }); + }); + + it('does not add fleet indices', () => { + const apmOssConfig = { + transactionIndices: 'apm-*-transaction-*', + spanIndices: 'apm-*-span-*', + errorIndices: 'apm-*-error-*', + metricsIndices: 'apm-*-metric-*', + fleetMode: false, + } as APMOSSConfig; + + const apmConfig = { ui: {} } as APMXPackConfig; + + expect(mergeConfigs(apmOssConfig, apmConfig)).toEqual({ + 'apm_oss.errorIndices': 'apm-*-error-*', + 'apm_oss.metricsIndices': 'apm-*-metric-*', + 'apm_oss.spanIndices': 'apm-*-span-*', + 'apm_oss.transactionIndices': 'apm-*-transaction-*', + }); + }); +}); diff --git a/x-pack/plugins/apm/server/index.ts b/x-pack/plugins/apm/server/index.ts index da3afd03513f0..52b5765a984d5 100644 --- a/x-pack/plugins/apm/server/index.ts +++ b/x-pack/plugins/apm/server/index.ts @@ -11,6 +11,7 @@ import { APMOSSConfig } from 'src/plugins/apm_oss/server'; import { APMPlugin } from './plugin'; import { SearchAggregatedTransactionSetting } from '../common/aggregated_transactions'; +// plugin config export const config = { exposeToBrowser: { serviceMapEnabled: true, @@ -50,20 +51,23 @@ export const config = { }; export type APMXPackConfig = TypeOf; +export type APMConfig = ReturnType; +// plugin config and ui indices settings export function mergeConfigs( apmOssConfig: APMOSSConfig, apmConfig: APMXPackConfig ) { - return { + const mergedConfig = { /* eslint-disable @typescript-eslint/naming-convention */ + // TODO: Remove all apm_oss options by 8.0 'apm_oss.transactionIndices': apmOssConfig.transactionIndices, 'apm_oss.spanIndices': apmOssConfig.spanIndices, 'apm_oss.errorIndices': apmOssConfig.errorIndices, 'apm_oss.metricsIndices': apmOssConfig.metricsIndices, 'apm_oss.sourcemapIndices': apmOssConfig.sourcemapIndices, 'apm_oss.onboardingIndices': apmOssConfig.onboardingIndices, - 'apm_oss.indexPattern': apmOssConfig.indexPattern, + 'apm_oss.indexPattern': apmOssConfig.indexPattern, // TODO: add data stream indices: traces-apm*,logs-apm*,metrics-apm*. Blocked by https://github.com/elastic/kibana/issues/87851 /* eslint-enable @typescript-eslint/naming-convention */ 'xpack.apm.serviceMapEnabled': apmConfig.serviceMapEnabled, 'xpack.apm.serviceMapFingerprintBucketSize': @@ -89,9 +93,27 @@ export function mergeConfigs( apmConfig.searchAggregatedTransactions, 'xpack.apm.metricsInterval': apmConfig.metricsInterval, }; -} -export type APMConfig = ReturnType; + if (apmOssConfig.fleetMode) { + mergedConfig[ + 'apm_oss.transactionIndices' + ] = `traces-apm*,${mergedConfig['apm_oss.transactionIndices']}`; + + mergedConfig[ + 'apm_oss.spanIndices' + ] = `traces-apm*,${mergedConfig['apm_oss.spanIndices']}`; + + mergedConfig[ + 'apm_oss.errorIndices' + ] = `logs-apm*,${mergedConfig['apm_oss.errorIndices']}`; + + mergedConfig[ + 'apm_oss.metricsIndices' + ] = `metrics-apm*,${mergedConfig['apm_oss.metricsIndices']}`; + } + + return mergedConfig; +} export const plugin = (initContext: PluginInitializerContext) => new APMPlugin(initContext); diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts index 8b2c83804b526..b93513646fb9f 100644 --- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts +++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts @@ -41,8 +41,6 @@ type TypeOfProcessorEvent = { [ProcessorEvent.transaction]: Transaction; [ProcessorEvent.span]: Span; [ProcessorEvent.metric]: Metric; - [ProcessorEvent.onboarding]: unknown; - [ProcessorEvent.sourcemap]: unknown; }[T]; type ESSearchRequestOf = Omit< diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.test.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.test.ts new file mode 100644 index 0000000000000..4983d6d515944 --- /dev/null +++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.test.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* eslint-disable @typescript-eslint/naming-convention */ +import { APMEventESSearchRequest } from '.'; +import { ApmIndicesConfig } from '../../../settings/apm_indices/get_apm_indices'; +import { unpackProcessorEvents } from './unpack_processor_events'; + +describe('unpackProcessorEvents', () => { + let res: ReturnType; + beforeEach(() => { + const request = { + apm: { events: ['transaction', 'error'] }, + body: { query: { bool: { filter: [{ terms: { foo: 'bar' } }] } } }, + } as APMEventESSearchRequest; + + const indices = { + 'apm_oss.transactionIndices': 'my-apm-*-transaction-*', + 'apm_oss.metricsIndices': 'my-apm-*-metric-*', + 'apm_oss.errorIndices': 'my-apm-*-error-*', + 'apm_oss.spanIndices': 'my-apm-*-span-*', + 'apm_oss.onboardingIndices': 'my-apm-*-onboarding-', + 'apm_oss.sourcemapIndices': 'my-apm-*-sourcemap-*', + } as ApmIndicesConfig; + + res = unpackProcessorEvents(request, indices); + }); + + it('adds terms filter for apm events', () => { + expect(res.body.query.bool.filter).toContainEqual({ + terms: { 'processor.event': ['transaction', 'error'] }, + }); + }); + + it('merges queries', () => { + expect(res.body.query.bool.filter).toEqual([ + { terms: { foo: 'bar' } }, + { terms: { 'processor.event': ['transaction', 'error'] } }, + ]); + }); + + it('searches the specified indices', () => { + expect(res.index).toEqual(['my-apm-*-transaction-*', 'my-apm-*-error-*']); + }); +}); diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.ts index e5e766069fa61..eef9aff946ea7 100644 --- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.ts +++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/unpack_processor_events.ts @@ -18,13 +18,11 @@ import { ApmIndicesName, } from '../../../settings/apm_indices/get_apm_indices'; -export const processorEventIndexMap: Record = { +const processorEventIndexMap: Record = { [ProcessorEvent.transaction]: 'apm_oss.transactionIndices', [ProcessorEvent.span]: 'apm_oss.spanIndices', [ProcessorEvent.metric]: 'apm_oss.metricsIndices', [ProcessorEvent.error]: 'apm_oss.errorIndices', - [ProcessorEvent.sourcemap]: 'apm_oss.sourcemapIndices', - [ProcessorEvent.onboarding]: 'apm_oss.onboardingIndices', }; export function unpackProcessorEvents( @@ -32,9 +30,7 @@ export function unpackProcessorEvents( indices: ApmIndicesConfig ) { const { apm, ...params } = request; - const events = uniq(apm.events); - const index = events.map((event) => indices[processorEventIndexMap[event]]); const withFilterForProcessorEvent: ESSearchRequest & { diff --git a/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts b/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts index 28c7e97ea7d95..d62386ed02835 100644 --- a/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts +++ b/x-pack/plugins/apm/server/lib/index_pattern/create_static_index_pattern.ts @@ -14,6 +14,7 @@ import { hasHistoricalAgentData } from '../services/get_services/has_historical_ import { Setup } from '../helpers/setup_request'; import { APMRequestHandlerContext } from '../../routes/typings'; import { InternalSavedObjectsClient } from '../helpers/get_internal_saved_objects_client.js'; +import { getApmIndexPatternTitle } from './get_apm_index_pattern_title'; export async function createStaticIndexPattern( setup: Setup, @@ -35,7 +36,7 @@ export async function createStaticIndexPattern( } try { - const apmIndexPatternTitle = config['apm_oss.indexPattern']; + const apmIndexPatternTitle = getApmIndexPatternTitle(context); await savedObjectsClient.create( 'index-pattern', { diff --git a/x-pack/plugins/apm/server/lib/index_pattern/get_dynamic_index_pattern.ts b/x-pack/plugins/apm/server/lib/index_pattern/get_dynamic_index_pattern.ts index 45cb9319ed0bc..c427588f8d860 100644 --- a/x-pack/plugins/apm/server/lib/index_pattern/get_dynamic_index_pattern.ts +++ b/x-pack/plugins/apm/server/lib/index_pattern/get_dynamic_index_pattern.ts @@ -10,11 +10,6 @@ import { IndexPatternsFetcher, FieldDescriptor, } from '../../../../../../src/plugins/data/server'; -import { ApmIndicesConfig } from '../settings/apm_indices/get_apm_indices'; -import { - ProcessorEvent, - UIProcessorEvent, -} from '../../../common/processor_event'; import { APMRequestHandlerContext } from '../../routes/typings'; interface IndexPatternTitleAndFields { @@ -30,15 +25,11 @@ const cache = new LRU({ // TODO: this is currently cached globally. In the future we might want to cache this per user export const getDynamicIndexPattern = async ({ context, - indices, - processorEvent, }: { context: APMRequestHandlerContext; - indices: ApmIndicesConfig; - processorEvent?: UIProcessorEvent; }) => { - const patternIndices = getPatternIndices(indices, processorEvent); - const indexPatternTitle = patternIndices.join(','); + const indexPatternTitle = context.config['apm_oss.indexPattern']; + const CACHE_KEY = `apm_dynamic_index_pattern_${indexPatternTitle}`; if (cache.has(CACHE_KEY)) { return cache.get(CACHE_KEY); @@ -54,7 +45,7 @@ export const getDynamicIndexPattern = async ({ // (would be a bad first time experience) try { const fields = await indexPatternsFetcher.getFieldsForWildcard({ - pattern: patternIndices, + pattern: indexPatternTitle, }); const indexPattern: IndexPatternTitleAndFields = { @@ -79,20 +70,3 @@ export const getDynamicIndexPattern = async ({ throw e; } }; - -function getPatternIndices( - indices: ApmIndicesConfig, - processorEvent?: UIProcessorEvent -) { - const indexNames = processorEvent - ? [processorEvent] - : [ProcessorEvent.transaction, ProcessorEvent.metric, ProcessorEvent.error]; - - const indicesMap = { - [ProcessorEvent.transaction]: indices['apm_oss.transactionIndices'], - [ProcessorEvent.metric]: indices['apm_oss.metricsIndices'], - [ProcessorEvent.error]: indices['apm_oss.errorIndices'], - }; - - return indexNames.map((name) => indicesMap[name as UIProcessorEvent]); -} diff --git a/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap index 239b909e1572c..606ce87035156 100644 --- a/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap @@ -6,7 +6,6 @@ Object { "events": Array [ "error", "metric", - "sourcemap", "transaction", ], }, diff --git a/x-pack/plugins/apm/server/lib/services/get_services/has_historical_agent_data.ts b/x-pack/plugins/apm/server/lib/services/get_services/has_historical_agent_data.ts index b1877533ca514..8363e59f2522e 100644 --- a/x-pack/plugins/apm/server/lib/services/get_services/has_historical_agent_data.ts +++ b/x-pack/plugins/apm/server/lib/services/get_services/has_historical_agent_data.ts @@ -18,7 +18,6 @@ export async function hasHistoricalAgentData(setup: Setup) { events: [ ProcessorEvent.error, ProcessorEvent.metric, - ProcessorEvent.sourcemap, ProcessorEvent.transaction, ], }, diff --git a/x-pack/plugins/apm/server/plugin.ts b/x-pack/plugins/apm/server/plugin.ts index 49fded8649c46..8804941914529 100644 --- a/x-pack/plugins/apm/server/plugin.ts +++ b/x-pack/plugins/apm/server/plugin.ts @@ -16,7 +16,8 @@ import { Plugin, PluginInitializerContext, } from 'src/core/server'; -import { APMConfig, APMXPackConfig, mergeConfigs } from '.'; +import { APMConfig, APMXPackConfig } from '.'; +import { mergeConfigs } from './index'; import { APMOSSPluginSetup } from '../../../../src/plugins/apm_oss/server'; import { HomeServerPluginSetup } from '../../../../src/plugins/home/server'; import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/server'; diff --git a/x-pack/plugins/apm/server/routes/index_pattern.ts b/x-pack/plugins/apm/server/routes/index_pattern.ts index 5f42a33533c4f..7f2b45072454f 100644 --- a/x-pack/plugins/apm/server/routes/index_pattern.ts +++ b/x-pack/plugins/apm/server/routes/index_pattern.ts @@ -5,15 +5,12 @@ * 2.0. */ -import * as t from 'io-ts'; import { createStaticIndexPattern } from '../lib/index_pattern/create_static_index_pattern'; import { createRoute } from './create_route'; import { setupRequest } from '../lib/helpers/setup_request'; import { getInternalSavedObjectsClient } from '../lib/helpers/get_internal_saved_objects_client'; import { getApmIndexPatternTitle } from '../lib/index_pattern/get_apm_index_pattern_title'; import { getDynamicIndexPattern } from '../lib/index_pattern/get_dynamic_index_pattern'; -import { getApmIndices } from '../lib/settings/apm_indices/get_apm_indices'; -import { UIProcessorEvent } from '../../common/processor_event'; export const staticIndexPatternRoute = createRoute((core) => ({ endpoint: 'POST /api/apm/index_pattern/static', @@ -31,32 +28,9 @@ export const staticIndexPatternRoute = createRoute((core) => ({ export const dynamicIndexPatternRoute = createRoute({ endpoint: 'GET /api/apm/index_pattern/dynamic', - params: t.partial({ - query: t.partial({ - processorEvent: t.union([ - t.literal('transaction'), - t.literal('metric'), - t.literal('error'), - ]), - }), - }), options: { tags: ['access:apm'] }, handler: async ({ context }) => { - const indices = await getApmIndices({ - config: context.config, - savedObjectsClient: context.core.savedObjects.client, - }); - - const processorEvent = context.params.query.processorEvent as - | UIProcessorEvent - | undefined; - - const dynamicIndexPattern = await getDynamicIndexPattern({ - context, - indices, - processorEvent, - }); - + const dynamicIndexPattern = await getDynamicIndexPattern({ context }); return { dynamicIndexPattern }; }, });