mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[UX/Maps] Fixing APM data view id (#179257)
closes https://github.com/elastic/kibana/issues/177461 UX fix: <img width="813" alt="Screenshot 2024-03-22 at 14 03 58" src="48352560
-d5c4-4258-8bfe-5b8dc6e4bf41"> Maps Obs layer <img width="1325" alt="Screenshot 2024-03-22 at 16 11 31" src="a68bbef3
-a30a-45e4-987f-b472ee0db394"> --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
4ffd310b92
commit
aadfa5dffd
37 changed files with 408 additions and 175 deletions
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
|
@ -41,6 +41,7 @@ packages/analytics/shippers/elastic_v3/server @elastic/kibana-core
|
|||
packages/analytics/shippers/fullstory @elastic/kibana-core
|
||||
packages/kbn-apm-config-loader @elastic/kibana-core @vigneshshanmugam
|
||||
x-pack/plugins/observability_solution/apm_data_access @elastic/obs-knowledge-team @elastic/obs-ux-infra_services-team
|
||||
packages/kbn-apm-data-view @elastic/obs-ux-infra_services-team
|
||||
x-pack/plugins/observability_solution/apm @elastic/obs-ux-infra_services-team
|
||||
packages/kbn-apm-synthtrace @elastic/obs-ux-infra_services-team @elastic/obs-ux-logs-team
|
||||
packages/kbn-apm-synthtrace-client @elastic/obs-ux-infra_services-team @elastic/obs-ux-logs-team
|
||||
|
|
|
@ -164,6 +164,7 @@
|
|||
"@kbn/analytics-shippers-fullstory": "link:packages/analytics/shippers/fullstory",
|
||||
"@kbn/apm-config-loader": "link:packages/kbn-apm-config-loader",
|
||||
"@kbn/apm-data-access-plugin": "link:x-pack/plugins/observability_solution/apm_data_access",
|
||||
"@kbn/apm-data-view": "link:packages/kbn-apm-data-view",
|
||||
"@kbn/apm-plugin": "link:x-pack/plugins/observability_solution/apm",
|
||||
"@kbn/apm-utils": "link:packages/kbn-apm-utils",
|
||||
"@kbn/app-link-test-plugin": "link:test/plugin_functional/plugins/app_link_test",
|
||||
|
|
17
packages/kbn-apm-data-view/index.ts
Normal file
17
packages/kbn-apm-data-view/index.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
const APM_STATIC_DATA_VIEW_ID_PREFIX = 'apm_static_data_view_id';
|
||||
|
||||
export function getStaticDataViewId(spaceId: string) {
|
||||
return `${APM_STATIC_DATA_VIEW_ID_PREFIX}_${spaceId}`;
|
||||
}
|
||||
|
||||
export function isAPMDataView(dataViewId: string) {
|
||||
return dataViewId.includes(APM_STATIC_DATA_VIEW_ID_PREFIX);
|
||||
}
|
5
packages/kbn-apm-data-view/kibana.jsonc
Normal file
5
packages/kbn-apm-data-view/kibana.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"type": "shared-common",
|
||||
"id": "@kbn/apm-data-view",
|
||||
"owner": "@elastic/obs-ux-infra_services-team"
|
||||
}
|
6
packages/kbn-apm-data-view/package.json
Normal file
6
packages/kbn-apm-data-view/package.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "@kbn/apm-data-view",
|
||||
"version": "1.0.0",
|
||||
"license": "SSPL-1.0 OR Elastic License 2.0",
|
||||
"private": true
|
||||
}
|
15
packages/kbn-apm-data-view/tsconfig.json
Normal file
15
packages/kbn-apm-data-view/tsconfig.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "target/types",
|
||||
"types": [
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
]
|
||||
}
|
|
@ -76,6 +76,8 @@
|
|||
"@kbn/apm-config-loader/*": ["packages/kbn-apm-config-loader/*"],
|
||||
"@kbn/apm-data-access-plugin": ["x-pack/plugins/observability_solution/apm_data_access"],
|
||||
"@kbn/apm-data-access-plugin/*": ["x-pack/plugins/observability_solution/apm_data_access/*"],
|
||||
"@kbn/apm-data-view": ["packages/kbn-apm-data-view"],
|
||||
"@kbn/apm-data-view/*": ["packages/kbn-apm-data-view/*"],
|
||||
"@kbn/apm-plugin": ["x-pack/plugins/observability_solution/apm"],
|
||||
"@kbn/apm-plugin/*": ["x-pack/plugins/observability_solution/apm/*"],
|
||||
"@kbn/apm-synthtrace": ["packages/kbn-apm-synthtrace"],
|
||||
|
|
|
@ -20,6 +20,9 @@ jest.mock('../../../../../kibana_services', () => {
|
|||
},
|
||||
};
|
||||
},
|
||||
getSpaceId() {
|
||||
return 'default';
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -52,7 +55,7 @@ describe('createLayerDescriptor', () => {
|
|||
applyGlobalQuery: true,
|
||||
applyGlobalTime: true,
|
||||
id: '12345',
|
||||
indexPatternId: 'apm_static_index_pattern_id',
|
||||
indexPatternId: 'apm_static_data_view_id_default',
|
||||
metrics: [
|
||||
{
|
||||
field: 'transaction.duration.us',
|
||||
|
@ -135,7 +138,7 @@ describe('createLayerDescriptor', () => {
|
|||
applyGlobalTime: true,
|
||||
geoField: 'client.geo.location',
|
||||
id: '12345',
|
||||
indexPatternId: 'apm_static_index_pattern_id',
|
||||
indexPatternId: 'apm_static_data_view_id_default',
|
||||
metrics: [
|
||||
{
|
||||
field: 'transaction.duration.us',
|
||||
|
@ -181,7 +184,7 @@ describe('createLayerDescriptor', () => {
|
|||
applyGlobalTime: true,
|
||||
geoField: 'client.geo.location',
|
||||
id: '12345',
|
||||
indexPatternId: 'apm_static_index_pattern_id',
|
||||
indexPatternId: 'apm_static_data_view_id_default',
|
||||
metrics: [
|
||||
{
|
||||
field: 'transaction.duration.us',
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { getStaticDataViewId } from '@kbn/apm-data-view';
|
||||
import {
|
||||
AggDescriptor,
|
||||
ColorDynamicOptions,
|
||||
|
@ -36,10 +37,7 @@ import { ESGeoGridSource } from '../../../../sources/es_geo_grid_source';
|
|||
import { GeoJsonVectorLayer } from '../../../vector_layer';
|
||||
import { HeatmapLayer } from '../../../heatmap_layer';
|
||||
import { getDefaultDynamicProperties } from '../../../../styles/vector/vector_style_defaults';
|
||||
|
||||
// redefining APM constant to avoid making maps app depend on APM plugin
|
||||
export const APM_INDEX_PATTERN_ID = 'apm_static_index_pattern_id';
|
||||
export const APM_INDEX_PATTERN_TITLE = 'traces-apm*,logs-apm*,metrics-apm*,apm-*';
|
||||
import { getSpaceId } from '../../../../../kibana_services';
|
||||
|
||||
const defaultDynamicProperties = getDefaultDynamicProperties();
|
||||
|
||||
|
@ -152,10 +150,10 @@ export function createLayerDescriptor({
|
|||
if (!layer || !metric || !display) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const apmSourceQuery = createAmpSourceQuery(layer);
|
||||
const label = createLayerLabel(layer, metric);
|
||||
const metricsDescriptor = createAggDescriptor(metric);
|
||||
const apmDataViewId = getStaticDataViewId(getSpaceId());
|
||||
|
||||
if (display === DISPLAY.CHOROPLETH) {
|
||||
const joinId = uuidv4();
|
||||
|
@ -172,7 +170,7 @@ export function createLayerDescriptor({
|
|||
right: {
|
||||
type: SOURCE_TYPES.ES_TERM_SOURCE,
|
||||
id: joinId,
|
||||
indexPatternId: APM_INDEX_PATTERN_ID,
|
||||
indexPatternId: apmDataViewId,
|
||||
term: 'client.geo.country_iso_code',
|
||||
metrics: [metricsDescriptor],
|
||||
whereQuery: apmSourceQuery,
|
||||
|
@ -202,7 +200,7 @@ export function createLayerDescriptor({
|
|||
}
|
||||
|
||||
const geoGridSourceDescriptor = ESGeoGridSource.createDescriptor({
|
||||
indexPatternId: APM_INDEX_PATTERN_ID,
|
||||
indexPatternId: apmDataViewId,
|
||||
geoField: 'client.geo.location',
|
||||
metrics: [metricsDescriptor],
|
||||
requestType: getGeoGridRequestType(display),
|
||||
|
|
|
@ -6,4 +6,3 @@
|
|||
*/
|
||||
|
||||
export { ObservabilityLayerWizardConfig } from './observability_layer_wizard';
|
||||
export { APM_INDEX_PATTERN_TITLE } from './create_layer_descriptor';
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { getStaticDataViewId } from '@kbn/apm-data-view';
|
||||
import { LAYER_WIZARD_CATEGORY, WIZARD_ID } from '../../../../../../common/constants';
|
||||
import { LayerWizard, RenderWizardArguments } from '../../layer_wizard_registry';
|
||||
import { ObservabilityLayerTemplate } from './observability_layer_template';
|
||||
import { APM_INDEX_PATTERN_ID } from './create_layer_descriptor';
|
||||
import { getIndexPatternService } from '../../../../../kibana_services';
|
||||
import { getIndexPatternService, getSpaceId } from '../../../../../kibana_services';
|
||||
|
||||
export const ObservabilityLayerWizardConfig: LayerWizard = {
|
||||
id: WIZARD_ID.OBSERVABILITY,
|
||||
|
@ -19,7 +19,7 @@ export const ObservabilityLayerWizardConfig: LayerWizard = {
|
|||
categories: [LAYER_WIZARD_CATEGORY.ELASTICSEARCH, LAYER_WIZARD_CATEGORY.SOLUTIONS],
|
||||
getIsDisabled: async () => {
|
||||
try {
|
||||
await getIndexPatternService().get(APM_INDEX_PATTERN_ID);
|
||||
await getIndexPatternService().get(getStaticDataViewId(getSpaceId()));
|
||||
return false;
|
||||
} catch (e) {
|
||||
return true;
|
||||
|
|
|
@ -19,6 +19,9 @@ jest.mock('../../../../../kibana_services', () => {
|
|||
},
|
||||
};
|
||||
},
|
||||
getSpaceId() {
|
||||
return 'default';
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -30,7 +33,9 @@ import { createSecurityLayerDescriptors } from './create_layer_descriptors';
|
|||
|
||||
describe('createLayerDescriptor', () => {
|
||||
test('apm index', () => {
|
||||
expect(createSecurityLayerDescriptors('id', 'apm-*-transaction*')).toEqual([
|
||||
expect(
|
||||
createSecurityLayerDescriptors('apm_static_data_view_id_default', 'apm-*-transaction*')
|
||||
).toEqual([
|
||||
{
|
||||
__dataRequests: [],
|
||||
alpha: 0.75,
|
||||
|
@ -48,7 +53,7 @@ describe('createLayerDescriptor', () => {
|
|||
filterByMapBounds: true,
|
||||
geoField: 'client.geo.location',
|
||||
id: '12345',
|
||||
indexPatternId: 'id',
|
||||
indexPatternId: 'apm_static_data_view_id_default',
|
||||
applyForceRefresh: true,
|
||||
scalingType: 'TOP_HITS',
|
||||
sortField: '',
|
||||
|
@ -127,7 +132,7 @@ describe('createLayerDescriptor', () => {
|
|||
filterByMapBounds: true,
|
||||
geoField: 'server.geo.location',
|
||||
id: '12345',
|
||||
indexPatternId: 'id',
|
||||
indexPatternId: 'apm_static_data_view_id_default',
|
||||
applyForceRefresh: true,
|
||||
scalingType: 'TOP_HITS',
|
||||
sortField: '',
|
||||
|
@ -205,7 +210,7 @@ describe('createLayerDescriptor', () => {
|
|||
applyGlobalTime: true,
|
||||
destGeoField: 'server.geo.location',
|
||||
id: '12345',
|
||||
indexPatternId: 'id',
|
||||
indexPatternId: 'apm_static_data_view_id_default',
|
||||
metrics: [
|
||||
{
|
||||
field: 'client.bytes',
|
||||
|
@ -488,7 +493,9 @@ describe('createLayerDescriptor', () => {
|
|||
});
|
||||
|
||||
test('apm data stream', () => {
|
||||
expect(createSecurityLayerDescriptors('id', 'traces-apm-opbean-node')).toEqual([
|
||||
expect(
|
||||
createSecurityLayerDescriptors('apm_static_data_view_id_foo', 'traces-apm-opbean-node')
|
||||
).toEqual([
|
||||
{
|
||||
__dataRequests: [],
|
||||
alpha: 0.75,
|
||||
|
@ -507,7 +514,7 @@ describe('createLayerDescriptor', () => {
|
|||
geoField: 'client.geo.location',
|
||||
id: '12345',
|
||||
applyForceRefresh: true,
|
||||
indexPatternId: 'id',
|
||||
indexPatternId: 'apm_static_data_view_id_foo',
|
||||
scalingType: 'TOP_HITS',
|
||||
sortField: '',
|
||||
sortOrder: 'desc',
|
||||
|
@ -585,7 +592,7 @@ describe('createLayerDescriptor', () => {
|
|||
filterByMapBounds: true,
|
||||
geoField: 'server.geo.location',
|
||||
id: '12345',
|
||||
indexPatternId: 'id',
|
||||
indexPatternId: 'apm_static_data_view_id_foo',
|
||||
scalingType: 'TOP_HITS',
|
||||
applyForceRefresh: true,
|
||||
sortField: '',
|
||||
|
@ -657,7 +664,7 @@ describe('createLayerDescriptor', () => {
|
|||
applyGlobalTime: true,
|
||||
destGeoField: 'server.geo.location',
|
||||
id: '12345',
|
||||
indexPatternId: 'id',
|
||||
indexPatternId: 'apm_static_data_view_id_foo',
|
||||
metrics: [
|
||||
{
|
||||
field: 'client.bytes',
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import minimatch from 'minimatch';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { euiPaletteColorBlind } from '@elastic/eui';
|
||||
import { isAPMDataView } from '@kbn/apm-data-view';
|
||||
import {
|
||||
LayerDescriptor,
|
||||
SizeDynamicOptions,
|
||||
|
@ -28,25 +28,16 @@ import { VectorStyle } from '../../../../styles/vector/vector_style';
|
|||
import { ESSearchSource } from '../../../../sources/es_search_source';
|
||||
import { ESPewPewSource } from '../../../../sources/es_pew_pew_source';
|
||||
import { getDefaultDynamicProperties } from '../../../../styles/vector/vector_style_defaults';
|
||||
import { APM_INDEX_PATTERN_TITLE } from '../observability';
|
||||
|
||||
const defaultDynamicProperties = getDefaultDynamicProperties();
|
||||
const euiVisColorPalette = euiPaletteColorBlind();
|
||||
|
||||
function isApmIndex(indexPatternTitle: string) {
|
||||
return APM_INDEX_PATTERN_TITLE.split(',')
|
||||
.map((pattern) => {
|
||||
return minimatch(indexPatternTitle, pattern);
|
||||
})
|
||||
.some(Boolean);
|
||||
function getSourceField(indexPatternId: string) {
|
||||
return isAPMDataView(indexPatternId) ? 'client.geo.location' : 'source.geo.location';
|
||||
}
|
||||
|
||||
function getSourceField(indexPatternTitle: string) {
|
||||
return isApmIndex(indexPatternTitle) ? 'client.geo.location' : 'source.geo.location';
|
||||
}
|
||||
|
||||
function getDestinationField(indexPatternTitle: string) {
|
||||
return isApmIndex(indexPatternTitle) ? 'server.geo.location' : 'destination.geo.location';
|
||||
function getDestinationField(indexPatternId: string) {
|
||||
return isAPMDataView(indexPatternId) ? 'server.geo.location' : 'destination.geo.location';
|
||||
}
|
||||
|
||||
function createSourceLayerDescriptor(
|
||||
|
@ -56,10 +47,10 @@ function createSourceLayerDescriptor(
|
|||
) {
|
||||
const sourceDescriptor = ESSearchSource.createDescriptor({
|
||||
indexPatternId,
|
||||
geoField: getSourceField(indexPatternTitle),
|
||||
geoField: getSourceField(indexPatternId),
|
||||
scalingType: SCALING_TYPES.TOP_HITS,
|
||||
topHitsSplitField: isApmIndex(indexPatternTitle) ? 'client.ip' : 'source.ip',
|
||||
tooltipProperties: isApmIndex(indexPatternTitle)
|
||||
topHitsSplitField: isAPMDataView(indexPatternId) ? 'client.ip' : 'source.ip',
|
||||
tooltipProperties: isAPMDataView(indexPatternId)
|
||||
? [
|
||||
'host.name',
|
||||
'client.ip',
|
||||
|
@ -114,10 +105,10 @@ function createDestinationLayerDescriptor(
|
|||
) {
|
||||
const sourceDescriptor = ESSearchSource.createDescriptor({
|
||||
indexPatternId,
|
||||
geoField: getDestinationField(indexPatternTitle),
|
||||
geoField: getDestinationField(indexPatternId),
|
||||
scalingType: SCALING_TYPES.TOP_HITS,
|
||||
topHitsSplitField: isApmIndex(indexPatternTitle) ? 'server.ip' : 'destination.ip',
|
||||
tooltipProperties: isApmIndex(indexPatternTitle)
|
||||
topHitsSplitField: isAPMDataView(indexPatternId) ? 'server.ip' : 'destination.ip',
|
||||
tooltipProperties: isAPMDataView(indexPatternId)
|
||||
? [
|
||||
'host.name',
|
||||
'server.ip',
|
||||
|
@ -172,16 +163,16 @@ function createLineLayerDescriptor(
|
|||
) {
|
||||
const sourceDescriptor = ESPewPewSource.createDescriptor({
|
||||
indexPatternId,
|
||||
sourceGeoField: getSourceField(indexPatternTitle),
|
||||
destGeoField: getDestinationField(indexPatternTitle),
|
||||
sourceGeoField: getSourceField(indexPatternId),
|
||||
destGeoField: getDestinationField(indexPatternId),
|
||||
metrics: [
|
||||
{
|
||||
type: AGG_TYPE.SUM,
|
||||
field: isApmIndex(indexPatternTitle) ? 'client.bytes' : 'source.bytes',
|
||||
field: isAPMDataView(indexPatternId) ? 'client.bytes' : 'source.bytes',
|
||||
},
|
||||
{
|
||||
type: AGG_TYPE.SUM,
|
||||
field: isApmIndex(indexPatternTitle) ? 'server.bytes' : 'destination.bytes',
|
||||
field: isAPMDataView(indexPatternId) ? 'server.bytes' : 'destination.bytes',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import { getSecurityIndexPatterns } from './security_index_pattern_utils';
|
||||
|
||||
jest.mock('../../../../../kibana_services', () => {
|
||||
return {
|
||||
getUiSettings() {
|
||||
return {
|
||||
get() {
|
||||
return ['logs-*', 'traces-apm*', 'endgame-*'];
|
||||
},
|
||||
};
|
||||
},
|
||||
getIndexPatternService() {
|
||||
return {
|
||||
getCache() {
|
||||
return [
|
||||
{
|
||||
id: 'kibana-event-log-data-view',
|
||||
type: 'index-pattern',
|
||||
managed: true,
|
||||
updatedAt: '2024-03-22T15:56:28.816Z',
|
||||
createdAt: '2024-03-22T15:56:28.816Z',
|
||||
attributes: {
|
||||
title: '.kibana-event-log-*',
|
||||
name: '.kibana-event-log-*',
|
||||
},
|
||||
references: [],
|
||||
namespaces: ['default'],
|
||||
version: 'WzExNCwxXQ==',
|
||||
},
|
||||
{
|
||||
id: 'apm_static_data_view_id_default',
|
||||
type: 'index-pattern',
|
||||
managed: false,
|
||||
updatedAt: '2024-03-21T16:50:57.705Z',
|
||||
createdAt: '2024-03-21T16:50:57.705Z',
|
||||
attributes: {
|
||||
title: 'traces-apm*,apm-*,apm-*,metrics-apm*,apm-*',
|
||||
name: 'APM',
|
||||
},
|
||||
references: [],
|
||||
namespaces: ['default'],
|
||||
version: 'WzUsMV0=',
|
||||
},
|
||||
{
|
||||
id: 'security-solution-default',
|
||||
type: 'index-pattern',
|
||||
managed: false,
|
||||
updatedAt: '2024-03-22T15:52:37.132Z',
|
||||
createdAt: '2024-03-22T15:52:37.132Z',
|
||||
attributes: {
|
||||
title:
|
||||
'.alerts-security.alerts-default,apm-*-transaction*,auditbeat-*,endgame-*,filebeat-*,packetbeat-*,winlogbeat-*,-*elastic-cloud-logs-*',
|
||||
name: '.alerts-security.alerts-default,apm-*-transaction*,auditbeat-*,endgame-*,filebeat-*,packetbeat-*,winlogbeat-*,-*elastic-cloud-logs-*',
|
||||
},
|
||||
references: [],
|
||||
namespaces: ['default'],
|
||||
version: 'WzEwMCwxXQ==',
|
||||
},
|
||||
{
|
||||
id: 'metrics-*',
|
||||
type: 'index-pattern',
|
||||
managed: true,
|
||||
updatedAt: '2024-03-22T15:52:44.340Z',
|
||||
createdAt: '2024-03-22T15:52:43.544Z',
|
||||
attributes: {
|
||||
title: 'metrics-*',
|
||||
},
|
||||
references: [],
|
||||
namespaces: ['*', 'default'],
|
||||
version: 'WzEwNiwxXQ==',
|
||||
},
|
||||
{
|
||||
id: 'logs-*',
|
||||
type: 'index-pattern',
|
||||
managed: true,
|
||||
updatedAt: '2024-03-22T15:52:43.600Z',
|
||||
createdAt: '2024-03-22T15:52:43.544Z',
|
||||
attributes: {
|
||||
title: 'logs-*',
|
||||
},
|
||||
references: [],
|
||||
namespaces: ['*', 'default'],
|
||||
version: 'WzEwNSwxXQ==',
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe('getSecurityIndexPatterns', () => {
|
||||
afterAll(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
it('returns logs, apm and security index patterns only', async () => {
|
||||
const resp = await getSecurityIndexPatterns();
|
||||
expect(resp).toEqual([
|
||||
{
|
||||
id: 'apm_static_data_view_id_default',
|
||||
title: 'traces-apm*,apm-*,apm-*,metrics-apm*,apm-*',
|
||||
},
|
||||
{
|
||||
id: 'security-solution-default',
|
||||
title:
|
||||
'.alerts-security.alerts-default,apm-*-transaction*,auditbeat-*,endgame-*,filebeat-*,packetbeat-*,winlogbeat-*,-*elastic-cloud-logs-*',
|
||||
},
|
||||
{ id: 'logs-*', title: 'logs-*' },
|
||||
]);
|
||||
});
|
||||
});
|
|
@ -29,10 +29,11 @@ export async function getSecurityIndexPatterns(): Promise<IndexPatternMeta[]> {
|
|||
const indexPatternCache = await getIndexPatternService().getCache();
|
||||
return indexPatternCache!
|
||||
.filter((savedObject) => {
|
||||
return (securityIndexPatternTitles as string[]).some((indexPatternTitle) => {
|
||||
// glob matching index pattern title
|
||||
return minimatch(indexPatternTitle, savedObject?.attributes?.title);
|
||||
});
|
||||
return securityIndexPatternTitles.some((indexPatternTitle) =>
|
||||
savedObject.attributes.title
|
||||
.split(',')
|
||||
.some((pattern) => minimatch(indexPatternTitle, pattern))
|
||||
);
|
||||
})
|
||||
.map((savedObject) => {
|
||||
return {
|
||||
|
|
|
@ -33,6 +33,12 @@ export function setIsCloudEnabled(enabled: boolean) {
|
|||
}
|
||||
export const getIsCloud = () => isCloudEnabled;
|
||||
|
||||
let spaceId = 'default';
|
||||
export const getSpaceId = () => spaceId;
|
||||
export const setSpaceId = (_spaceId: string) => {
|
||||
spaceId = _spaceId;
|
||||
};
|
||||
|
||||
export const getIndexNameFormComponent = () => pluginsStart.fileUpload.IndexNameFormComponent;
|
||||
export const getFileUploadComponent = () => pluginsStart.fileUpload.FileUploadComponent;
|
||||
export const getIndexPatternService = () => pluginsStart.data.dataViews;
|
||||
|
|
|
@ -81,7 +81,12 @@ import { visualizeGeoFieldAction } from './trigger_actions/visualize_geo_field_a
|
|||
import { APP_NAME, APP_ICON_SOLUTION, APP_ID, MAP_SAVED_OBJECT_TYPE } from '../common/constants';
|
||||
import { getMapsVisTypeAlias } from './maps_vis_type_alias';
|
||||
import { featureCatalogueEntry } from './feature_catalogue_entry';
|
||||
import { setIsCloudEnabled, setMapAppConfig, setStartServices } from './kibana_services';
|
||||
import {
|
||||
setIsCloudEnabled,
|
||||
setMapAppConfig,
|
||||
setSpaceId,
|
||||
setStartServices,
|
||||
} from './kibana_services';
|
||||
import { MapInspectorView } from './inspector/map_adapter/map_inspector_view';
|
||||
import { VectorTileInspectorView } from './inspector/vector_tile_adapter/vector_tile_inspector_view';
|
||||
|
||||
|
@ -204,9 +209,13 @@ export class MapsPlugin
|
|||
euiIconType: APP_ICON_SOLUTION,
|
||||
category: DEFAULT_APP_CATEGORIES.kibana,
|
||||
async mount(params: AppMountParameters) {
|
||||
const [coreStart, { savedObjectsTagging }] = await core.getStartServices();
|
||||
const [coreStart, { savedObjectsTagging, spaces }] = await core.getStartServices();
|
||||
const UsageTracker =
|
||||
plugins.usageCollection?.components.ApplicationUsageTrackingProvider ?? React.Fragment;
|
||||
const activeSpace = await spaces?.getActiveSpace();
|
||||
if (activeSpace) {
|
||||
setSpaceId(activeSpace.id);
|
||||
}
|
||||
const { renderApp } = await import('./render_app');
|
||||
return renderApp(params, { coreStart, AppUsageTracker: UsageTracker, savedObjectsTagging });
|
||||
},
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
"@kbn/presentation-publishing",
|
||||
"@kbn/saved-objects-finder-plugin",
|
||||
"@kbn/esql-utils",
|
||||
"@kbn/apm-data-view"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const DO_NOT_USE_LEGACY_APM_STATIC_DATA_VIEW_ID =
|
||||
'apm_static_index_pattern_id';
|
||||
|
||||
const APM_STATIC_DATA_VIEW_ID_PREFIX = 'apm_static_data_view_id';
|
||||
|
||||
export function getDataViewId(spaceId: string) {
|
||||
return `${APM_STATIC_DATA_VIEW_ID_PREFIX}_${spaceId}`;
|
||||
}
|
|
@ -80,6 +80,8 @@ async function saveApmIndices({
|
|||
});
|
||||
|
||||
clearCache();
|
||||
// Reload window to update APM data view with new indices
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
type ApiResponse =
|
||||
|
|
|
@ -12,7 +12,7 @@ import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_ev
|
|||
import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes';
|
||||
import * as HistoricalAgentData from '../historical_data/has_historical_agent_data';
|
||||
import { APMCore } from '../typings';
|
||||
import { createStaticDataView } from './create_static_data_view';
|
||||
import { createOrUpdateStaticDataView } from './create_static_data_view';
|
||||
|
||||
function getMockedDataViewService(existingDataViewTitle: string) {
|
||||
return {
|
||||
|
@ -55,7 +55,7 @@ const apmEventClientMock = {
|
|||
describe('createStaticDataView', () => {
|
||||
it(`should not create data view if 'xpack.apm.autocreateApmIndexPattern=false'`, async () => {
|
||||
const dataViewService = getMockedDataViewService('apm-*');
|
||||
await createStaticDataView({
|
||||
await createOrUpdateStaticDataView({
|
||||
apmEventClient: apmEventClientMock,
|
||||
resources: {
|
||||
config: { autoCreateApmDataView: false },
|
||||
|
@ -75,7 +75,7 @@ describe('createStaticDataView', () => {
|
|||
|
||||
const dataViewService = getMockedDataViewService('apm-*');
|
||||
|
||||
await createStaticDataView({
|
||||
await createOrUpdateStaticDataView({
|
||||
apmEventClient: apmEventClientMock,
|
||||
resources: {
|
||||
config: { autoCreateApmDataView: false },
|
||||
|
@ -95,7 +95,7 @@ describe('createStaticDataView', () => {
|
|||
|
||||
const dataViewService = getMockedDataViewService('apm-*');
|
||||
|
||||
await createStaticDataView({
|
||||
await createOrUpdateStaticDataView({
|
||||
apmEventClient: apmEventClientMock,
|
||||
resources: {
|
||||
core: coreMock,
|
||||
|
@ -119,7 +119,7 @@ describe('createStaticDataView', () => {
|
|||
const expectedDataViewTitle =
|
||||
'apm-*-transaction-*,apm-*-span-*,apm-*-error-*,apm-*-metrics-*';
|
||||
|
||||
await createStaticDataView({
|
||||
await createOrUpdateStaticDataView({
|
||||
apmEventClient: apmEventClientMock,
|
||||
resources: {
|
||||
core: coreMock,
|
||||
|
@ -150,7 +150,7 @@ describe('createStaticDataView', () => {
|
|||
'apm-*-transaction-*,apm-*-span-*,apm-*-error-*,apm-*-metrics-*'
|
||||
);
|
||||
|
||||
await createStaticDataView({
|
||||
await createOrUpdateStaticDataView({
|
||||
apmEventClient: apmEventClientMock,
|
||||
resources: {
|
||||
core: coreMock,
|
||||
|
|
|
@ -8,10 +8,7 @@
|
|||
import { Logger, SavedObjectsErrorHelpers } from '@kbn/core/server';
|
||||
import { DataView, DataViewsService } from '@kbn/data-views-plugin/common';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
DO_NOT_USE_LEGACY_APM_STATIC_DATA_VIEW_ID,
|
||||
getDataViewId,
|
||||
} from '../../../common/data_view_constants';
|
||||
import { getStaticDataViewId } from '@kbn/apm-data-view';
|
||||
import {
|
||||
TRACE_ID,
|
||||
TRANSACTION_ID,
|
||||
|
@ -28,7 +25,7 @@ export type CreateDataViewResponse = Promise<
|
|||
| { created: boolean; reason?: string }
|
||||
>;
|
||||
|
||||
export async function createStaticDataView({
|
||||
export async function createOrUpdateStaticDataView({
|
||||
dataViewService,
|
||||
resources,
|
||||
apmEventClient,
|
||||
|
@ -42,7 +39,7 @@ export async function createStaticDataView({
|
|||
logger: Logger;
|
||||
}): CreateDataViewResponse {
|
||||
const { config } = resources;
|
||||
const dataViewId = getDataViewId(spaceId);
|
||||
const dataViewId = getStaticDataViewId(spaceId);
|
||||
logger.info(`create static data view ${dataViewId}`);
|
||||
|
||||
return withApmSpan('create_static_data_view', async () => {
|
||||
|
@ -100,15 +97,6 @@ export async function createStaticDataView({
|
|||
dataViewId,
|
||||
});
|
||||
|
||||
try {
|
||||
await dataViewService.delete(DO_NOT_USE_LEGACY_APM_STATIC_DATA_VIEW_ID);
|
||||
} catch (e) {
|
||||
// swallow error if caused by the data view (saved object) not existing
|
||||
if (!SavedObjectsErrorHelpers.isNotFoundError(e)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
return { created: true, dataView };
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common';
|
||||
import {
|
||||
CreateDataViewResponse,
|
||||
createStaticDataView,
|
||||
createOrUpdateStaticDataView,
|
||||
} from './create_static_data_view';
|
||||
import { createApmServerRoute } from '../apm_routes/create_apm_server_route';
|
||||
import { getApmDataViewIndexPattern } from './get_apm_data_view_index_pattern';
|
||||
|
@ -39,7 +39,7 @@ const staticDataViewRoute = createApmServerRoute({
|
|||
true
|
||||
);
|
||||
|
||||
const res = await createStaticDataView({
|
||||
const res = await createOrUpdateStaticDataView({
|
||||
dataViewService,
|
||||
resources,
|
||||
apmEventClient,
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
"@kbn/config-schema",
|
||||
"@kbn/repo-info",
|
||||
"@kbn/apm-utils",
|
||||
"@kbn/apm-data-view",
|
||||
"@kbn/logging",
|
||||
"@kbn/std",
|
||||
"@kbn/core-saved-objects-api-server-mocks",
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
"observability",
|
||||
"security",
|
||||
"maps",
|
||||
"lens"
|
||||
"lens",
|
||||
"spaces"
|
||||
],
|
||||
"requiredBundles": [
|
||||
"kibanaReact",
|
||||
|
|
|
@ -119,12 +119,14 @@ export function UXAppRoot({
|
|||
lens,
|
||||
},
|
||||
isDev,
|
||||
spaceId,
|
||||
}: {
|
||||
appMountParameters: AppMountParameters;
|
||||
core: CoreStart;
|
||||
deps: ApmPluginSetupDeps;
|
||||
corePlugins: ApmPluginStartDeps;
|
||||
isDev: boolean;
|
||||
spaceId: string;
|
||||
}) {
|
||||
const { history } = appMountParameters;
|
||||
const i18nCore = core.i18n;
|
||||
|
@ -168,6 +170,7 @@ export function UXAppRoot({
|
|||
appMountParameters,
|
||||
exploratoryView,
|
||||
observabilityShared,
|
||||
spaceId,
|
||||
}}
|
||||
>
|
||||
<i18nCore.Context>
|
||||
|
@ -207,12 +210,14 @@ export const renderApp = ({
|
|||
appMountParameters,
|
||||
corePlugins,
|
||||
isDev,
|
||||
spaceId,
|
||||
}: {
|
||||
core: CoreStart;
|
||||
deps: ApmPluginSetupDeps;
|
||||
appMountParameters: AppMountParameters;
|
||||
corePlugins: ApmPluginStartDeps;
|
||||
isDev: boolean;
|
||||
spaceId: string;
|
||||
}) => {
|
||||
const { element } = appMountParameters;
|
||||
|
||||
|
@ -231,6 +236,7 @@ export const renderApp = ({
|
|||
deps={deps}
|
||||
corePlugins={corePlugins}
|
||||
isDev={isDev}
|
||||
spaceId={spaceId}
|
||||
/>,
|
||||
element
|
||||
);
|
||||
|
|
|
@ -29,7 +29,7 @@ export const mockLayerList = [
|
|||
label: 'Page load duration',
|
||||
},
|
||||
],
|
||||
indexPatternId: 'apm_static_index_pattern_id',
|
||||
indexPatternId: 'apm_static_data_view_id_default',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -101,7 +101,7 @@ export const mockLayerList = [
|
|||
'transaction.type : "page-load" and service.name : "undefined"',
|
||||
},
|
||||
metrics: [{ type: 'avg', field: 'transaction.duration.us' }],
|
||||
indexPatternId: 'apm_static_index_pattern_id',
|
||||
indexPatternId: 'apm_static_data_view_id_default',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -9,7 +9,14 @@ import { renderHook } from '@testing-library/react-hooks';
|
|||
import { mockLayerList } from './__mocks__/regions_layer.mock';
|
||||
import { useLayerList } from './use_layer_list';
|
||||
|
||||
jest.mock('../../../../context/use_ux_plugin_context', () => {
|
||||
return { useUxPluginContext: () => ({ spaceId: 'default' }) };
|
||||
});
|
||||
|
||||
describe('useLayerList', () => {
|
||||
afterAll(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
test('it returns the region layer', () => {
|
||||
const { result } = renderHook(() => useLayerList());
|
||||
expect(result.current).toStrictEqual(mockLayerList);
|
||||
|
|
|
@ -5,62 +5,32 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { getStaticDataViewId } from '@kbn/apm-data-view';
|
||||
import {
|
||||
EMSFileSourceDescriptor,
|
||||
ESTermSourceDescriptor,
|
||||
LayerDescriptor as BaseLayerDescriptor,
|
||||
VectorLayerDescriptor as BaseVectorLayerDescriptor,
|
||||
VectorStyleDescriptor,
|
||||
AGG_TYPE,
|
||||
COLOR_MAP_TYPE,
|
||||
EMSFileSourceDescriptor,
|
||||
ESTermSourceDescriptor,
|
||||
FIELD_ORIGIN,
|
||||
LABEL_BORDER_SIZES,
|
||||
LABEL_POSITIONS,
|
||||
LayerDescriptor as BaseLayerDescriptor,
|
||||
LAYER_TYPE,
|
||||
SOURCE_TYPES,
|
||||
STYLE_TYPE,
|
||||
SYMBOLIZE_AS_TYPES,
|
||||
VectorLayerDescriptor as BaseVectorLayerDescriptor,
|
||||
VectorStyleDescriptor,
|
||||
} from '@kbn/maps-plugin/common';
|
||||
|
||||
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
|
||||
import { useMemo } from 'react';
|
||||
import {
|
||||
SERVICE_NAME,
|
||||
TRANSACTION_TYPE,
|
||||
} from '../../../../../common/elasticsearch_fieldnames';
|
||||
import { TRANSACTION_PAGE_LOAD } from '../../../../../common/transaction_types';
|
||||
import { APM_STATIC_INDEX_PATTERN_ID } from '../../../../../common/index_pattern_constants';
|
||||
|
||||
const ES_TERM_SOURCE_COUNTRY: ESTermSourceDescriptor = {
|
||||
type: SOURCE_TYPES.ES_TERM_SOURCE,
|
||||
id: '3657625d-17b0-41ef-99ba-3a2b2938655c',
|
||||
term: 'client.geo.country_iso_code',
|
||||
metrics: [
|
||||
{
|
||||
type: AGG_TYPE.AVG,
|
||||
field: 'transaction.duration.us',
|
||||
label: 'Page load duration',
|
||||
},
|
||||
],
|
||||
indexPatternId: APM_STATIC_INDEX_PATTERN_ID,
|
||||
applyGlobalQuery: true,
|
||||
applyGlobalTime: true,
|
||||
applyForceRefresh: true,
|
||||
};
|
||||
|
||||
const ES_TERM_SOURCE_REGION: ESTermSourceDescriptor = {
|
||||
type: SOURCE_TYPES.ES_TERM_SOURCE,
|
||||
id: 'e62a1b9c-d7ff-4fd4-a0f6-0fdc44bb9e41',
|
||||
term: 'client.geo.region_iso_code',
|
||||
metrics: [{ type: AGG_TYPE.AVG, field: 'transaction.duration.us' }],
|
||||
whereQuery: {
|
||||
query: 'transaction.type : "page-load"',
|
||||
language: 'kuery',
|
||||
},
|
||||
indexPatternId: APM_STATIC_INDEX_PATTERN_ID,
|
||||
applyGlobalQuery: true,
|
||||
applyGlobalTime: true,
|
||||
applyForceRefresh: true,
|
||||
};
|
||||
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
|
||||
import { useUxPluginContext } from '../../../../context/use_ux_plugin_context';
|
||||
|
||||
const getWhereQuery = (serviceName: string) => {
|
||||
return {
|
||||
|
@ -84,10 +54,49 @@ interface VectorLayerDescriptor extends BaseVectorLayerDescriptor {
|
|||
|
||||
export function useLayerList() {
|
||||
const { urlParams } = useLegacyUrlParams();
|
||||
const { spaceId } = useUxPluginContext();
|
||||
|
||||
const { esTermSourceCountry, esTermSourceRegion } = useMemo(() => {
|
||||
const _esTermSourceCountry: ESTermSourceDescriptor = {
|
||||
type: SOURCE_TYPES.ES_TERM_SOURCE,
|
||||
id: '3657625d-17b0-41ef-99ba-3a2b2938655c',
|
||||
term: 'client.geo.country_iso_code',
|
||||
metrics: [
|
||||
{
|
||||
type: AGG_TYPE.AVG,
|
||||
field: 'transaction.duration.us',
|
||||
label: 'Page load duration',
|
||||
},
|
||||
],
|
||||
indexPatternId: getStaticDataViewId(spaceId),
|
||||
applyGlobalQuery: true,
|
||||
applyGlobalTime: true,
|
||||
applyForceRefresh: true,
|
||||
};
|
||||
|
||||
const _esTermSourceRegion: ESTermSourceDescriptor = {
|
||||
type: SOURCE_TYPES.ES_TERM_SOURCE,
|
||||
id: 'e62a1b9c-d7ff-4fd4-a0f6-0fdc44bb9e41',
|
||||
term: 'client.geo.region_iso_code',
|
||||
metrics: [{ type: AGG_TYPE.AVG, field: 'transaction.duration.us' }],
|
||||
whereQuery: {
|
||||
query: 'transaction.type : "page-load"',
|
||||
language: 'kuery',
|
||||
},
|
||||
indexPatternId: getStaticDataViewId(spaceId),
|
||||
applyGlobalQuery: true,
|
||||
applyGlobalTime: true,
|
||||
applyForceRefresh: true,
|
||||
};
|
||||
return {
|
||||
esTermSourceCountry: _esTermSourceCountry,
|
||||
esTermSourceRegion: _esTermSourceRegion,
|
||||
};
|
||||
}, [spaceId]);
|
||||
|
||||
const { serviceName } = urlParams;
|
||||
|
||||
ES_TERM_SOURCE_COUNTRY.whereQuery = getWhereQuery(serviceName!);
|
||||
esTermSourceCountry.whereQuery = getWhereQuery(serviceName!);
|
||||
|
||||
const getLayerStyle = (fieldName: string): VectorStyleDescriptor => {
|
||||
return {
|
||||
|
@ -151,7 +160,7 @@ export function useLayerList() {
|
|||
joins: [
|
||||
{
|
||||
leftField: 'iso2',
|
||||
right: ES_TERM_SOURCE_COUNTRY,
|
||||
right: esTermSourceCountry,
|
||||
},
|
||||
],
|
||||
sourceDescriptor: {
|
||||
|
@ -169,13 +178,13 @@ export function useLayerList() {
|
|||
type: LAYER_TYPE.GEOJSON_VECTOR,
|
||||
};
|
||||
|
||||
ES_TERM_SOURCE_REGION.whereQuery = getWhereQuery(serviceName!);
|
||||
esTermSourceRegion.whereQuery = getWhereQuery(serviceName!);
|
||||
|
||||
const pageLoadDurationByAdminRegionLayer: VectorLayerDescriptor = {
|
||||
joins: [
|
||||
{
|
||||
leftField: 'region_iso_code',
|
||||
right: ES_TERM_SOURCE_REGION,
|
||||
right: esTermSourceRegion,
|
||||
},
|
||||
],
|
||||
sourceDescriptor: {
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
import { useMemo } from 'react';
|
||||
import { FieldFilter as Filter } from '@kbn/es-query';
|
||||
import { getStaticDataViewId } from '@kbn/apm-data-view';
|
||||
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
|
||||
import { APM_STATIC_INDEX_PATTERN_ID } from '../../../../../common/index_pattern_constants';
|
||||
import {
|
||||
CLIENT_GEO_COUNTRY_ISO_CODE,
|
||||
SERVICE_NAME,
|
||||
|
@ -17,11 +17,16 @@ import {
|
|||
USER_AGENT_NAME,
|
||||
USER_AGENT_OS,
|
||||
} from '../../../../../common/elasticsearch_fieldnames';
|
||||
import { useUxPluginContext } from '../../../../context/use_ux_plugin_context';
|
||||
|
||||
const getWildcardFilter = (field: string, value: string): Filter => {
|
||||
const getWildcardFilter = (
|
||||
field: string,
|
||||
value: string,
|
||||
spaceId: string
|
||||
): Filter => {
|
||||
return {
|
||||
meta: {
|
||||
index: APM_STATIC_INDEX_PATTERN_ID,
|
||||
index: getStaticDataViewId(spaceId),
|
||||
alias: null,
|
||||
negate: false,
|
||||
disabled: false,
|
||||
|
@ -33,10 +38,14 @@ const getWildcardFilter = (field: string, value: string): Filter => {
|
|||
};
|
||||
};
|
||||
|
||||
const getMatchFilter = (field: string, value: string): Filter => {
|
||||
const getMatchFilter = (
|
||||
field: string,
|
||||
value: string,
|
||||
spaceId: string
|
||||
): Filter => {
|
||||
return {
|
||||
meta: {
|
||||
index: APM_STATIC_INDEX_PATTERN_ID,
|
||||
index: getStaticDataViewId(spaceId),
|
||||
alias: null,
|
||||
negate: false,
|
||||
disabled: false,
|
||||
|
@ -51,11 +60,12 @@ const getMatchFilter = (field: string, value: string): Filter => {
|
|||
const getMultiMatchFilter = (
|
||||
field: string,
|
||||
values: string[],
|
||||
spaceId: string,
|
||||
negate = false
|
||||
): Filter => {
|
||||
return {
|
||||
meta: {
|
||||
index: APM_STATIC_INDEX_PATTERN_ID,
|
||||
index: getStaticDataViewId(spaceId),
|
||||
type: 'phrases',
|
||||
key: field,
|
||||
value: values.join(', '),
|
||||
|
@ -73,25 +83,28 @@ const getMultiMatchFilter = (
|
|||
};
|
||||
};
|
||||
|
||||
const existFilter: Filter = {
|
||||
meta: {
|
||||
index: APM_STATIC_INDEX_PATTERN_ID,
|
||||
alias: null,
|
||||
negate: false,
|
||||
disabled: false,
|
||||
type: 'exists',
|
||||
key: 'transaction.marks.navigationTiming.fetchStart',
|
||||
value: 'exists',
|
||||
},
|
||||
query: {
|
||||
exists: {
|
||||
field: 'transaction.marks.navigationTiming.fetchStart',
|
||||
function getExistFilter(spaceId: string): Filter {
|
||||
return {
|
||||
meta: {
|
||||
index: getStaticDataViewId(spaceId),
|
||||
alias: null,
|
||||
negate: false,
|
||||
disabled: false,
|
||||
type: 'exists',
|
||||
key: 'transaction.marks.navigationTiming.fetchStart',
|
||||
value: 'exists',
|
||||
},
|
||||
},
|
||||
};
|
||||
query: {
|
||||
exists: {
|
||||
field: 'transaction.marks.navigationTiming.fetchStart',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const useMapFilters = (): Filter[] => {
|
||||
const { urlParams, uxUiFilters } = useLegacyUrlParams();
|
||||
const { spaceId } = useUxPluginContext();
|
||||
|
||||
const { serviceName, searchTerm } = urlParams;
|
||||
|
||||
|
@ -109,48 +122,66 @@ export const useMapFilters = (): Filter[] => {
|
|||
} = uxUiFilters;
|
||||
|
||||
return useMemo(() => {
|
||||
const filters: Filter[] = [existFilter];
|
||||
const filters: Filter[] = [getExistFilter(spaceId)];
|
||||
if (serviceName) {
|
||||
filters.push(getMatchFilter(SERVICE_NAME, serviceName));
|
||||
filters.push(getMatchFilter(SERVICE_NAME, serviceName, spaceId));
|
||||
}
|
||||
if (browser) {
|
||||
filters.push(getMultiMatchFilter(USER_AGENT_NAME, browser));
|
||||
filters.push(getMultiMatchFilter(USER_AGENT_NAME, browser, spaceId));
|
||||
}
|
||||
if (device) {
|
||||
filters.push(getMultiMatchFilter(USER_AGENT_DEVICE, device));
|
||||
filters.push(getMultiMatchFilter(USER_AGENT_DEVICE, device, spaceId));
|
||||
}
|
||||
if (os) {
|
||||
filters.push(getMultiMatchFilter(USER_AGENT_OS, os));
|
||||
filters.push(getMultiMatchFilter(USER_AGENT_OS, os, spaceId));
|
||||
}
|
||||
if (location) {
|
||||
filters.push(getMultiMatchFilter(CLIENT_GEO_COUNTRY_ISO_CODE, location));
|
||||
filters.push(
|
||||
getMultiMatchFilter(CLIENT_GEO_COUNTRY_ISO_CODE, location, spaceId)
|
||||
);
|
||||
}
|
||||
if (transactionUrl) {
|
||||
filters.push(getMultiMatchFilter(TRANSACTION_URL, transactionUrl));
|
||||
filters.push(
|
||||
getMultiMatchFilter(TRANSACTION_URL, transactionUrl, spaceId)
|
||||
);
|
||||
}
|
||||
if (browserExcluded) {
|
||||
filters.push(getMultiMatchFilter(USER_AGENT_NAME, browserExcluded, true));
|
||||
filters.push(
|
||||
getMultiMatchFilter(USER_AGENT_NAME, browserExcluded, spaceId, true)
|
||||
);
|
||||
}
|
||||
if (deviceExcluded) {
|
||||
filters.push(
|
||||
getMultiMatchFilter(USER_AGENT_DEVICE, deviceExcluded, true)
|
||||
getMultiMatchFilter(USER_AGENT_DEVICE, deviceExcluded, spaceId, true)
|
||||
);
|
||||
}
|
||||
if (osExcluded) {
|
||||
filters.push(getMultiMatchFilter(USER_AGENT_OS, osExcluded, true));
|
||||
filters.push(
|
||||
getMultiMatchFilter(USER_AGENT_OS, osExcluded, spaceId, true)
|
||||
);
|
||||
}
|
||||
if (locationExcluded) {
|
||||
filters.push(
|
||||
getMultiMatchFilter(CLIENT_GEO_COUNTRY_ISO_CODE, locationExcluded, true)
|
||||
getMultiMatchFilter(
|
||||
CLIENT_GEO_COUNTRY_ISO_CODE,
|
||||
locationExcluded,
|
||||
spaceId,
|
||||
true
|
||||
)
|
||||
);
|
||||
}
|
||||
if (transactionUrlExcluded) {
|
||||
filters.push(
|
||||
getMultiMatchFilter(TRANSACTION_URL, transactionUrlExcluded, true)
|
||||
getMultiMatchFilter(
|
||||
TRANSACTION_URL,
|
||||
transactionUrlExcluded,
|
||||
spaceId,
|
||||
true
|
||||
)
|
||||
);
|
||||
}
|
||||
if (searchTerm) {
|
||||
filters.push(getWildcardFilter(TRANSACTION_URL, searchTerm));
|
||||
filters.push(getWildcardFilter(TRANSACTION_URL, searchTerm, spaceId));
|
||||
}
|
||||
|
||||
return filters;
|
||||
|
@ -167,5 +198,6 @@ export const useMapFilters = (): Filter[] => {
|
|||
locationExcluded,
|
||||
transactionUrlExcluded,
|
||||
searchTerm,
|
||||
spaceId,
|
||||
]);
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@ export interface PluginContextValue {
|
|||
appMountParameters: AppMountParameters;
|
||||
exploratoryView: ExploratoryViewPublicStart;
|
||||
observabilityShared: ObservabilitySharedPluginStart;
|
||||
spaceId: string;
|
||||
}
|
||||
|
||||
export const PluginContext = createContext({} as PluginContextValue);
|
||||
|
|
|
@ -5,4 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export const APM_STATIC_INDEX_PATTERN_ID = 'apm_static_index_pattern_id';
|
||||
import { useContext } from 'react';
|
||||
import { PluginContext } from './plugin_context';
|
||||
|
||||
export function useUxPluginContext() {
|
||||
return useContext(PluginContext);
|
||||
}
|
|
@ -47,6 +47,7 @@ import {
|
|||
ObservabilityAIAssistantPublicSetup,
|
||||
ObservabilityAIAssistantPublicStart,
|
||||
} from '@kbn/observability-ai-assistant-plugin/public';
|
||||
import { SpacesPluginStart } from '@kbn/spaces-plugin/public';
|
||||
|
||||
export type UxPluginSetup = void;
|
||||
export type UxPluginStart = void;
|
||||
|
@ -75,6 +76,7 @@ export interface ApmPluginStartDeps {
|
|||
exploratoryView: ExploratoryViewPublicStart;
|
||||
dataViews: DataViewsPublicPluginStart;
|
||||
lens: LensPublicStart;
|
||||
spaces?: SpacesPluginStart;
|
||||
}
|
||||
|
||||
async function getDataStartPlugin(core: CoreSetup) {
|
||||
|
@ -201,12 +203,17 @@ export class UxPlugin implements Plugin<UxPluginSetup, UxPluginStart> {
|
|||
core.getStartServices(),
|
||||
]);
|
||||
|
||||
const activeSpace = await (
|
||||
corePlugins as ApmPluginStartDeps
|
||||
).spaces?.getActiveSpace();
|
||||
|
||||
return renderApp({
|
||||
isDev,
|
||||
core: coreStart,
|
||||
deps: pluginSetupDeps,
|
||||
appMountParameters,
|
||||
corePlugins: corePlugins as ApmPluginStartDeps,
|
||||
spaceId: activeSpace?.id || 'default',
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -42,7 +42,9 @@
|
|||
"@kbn/shared-ux-router",
|
||||
"@kbn/observability-ai-assistant-plugin",
|
||||
"@kbn/config-schema",
|
||||
"@kbn/shared-ux-link-redirect-app"
|
||||
"@kbn/shared-ux-link-redirect-app",
|
||||
"@kbn/apm-data-view",
|
||||
"@kbn/spaces-plugin",
|
||||
],
|
||||
"exclude": ["target/**/*"]
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
import { apm, timerange } from '@kbn/apm-synthtrace-client';
|
||||
import type { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace';
|
||||
import expect from '@kbn/expect';
|
||||
import { getDataViewId } from '@kbn/apm-plugin/common/data_view_constants';
|
||||
import { DataView } from '@kbn/data-views-plugin/common';
|
||||
import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
|
||||
import request from 'superagent';
|
||||
import { getStaticDataViewId } from '@kbn/apm-data-view';
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
import { SupertestReturnType, ApmApiError } from '../../common/apm_api_supertest';
|
||||
|
||||
|
@ -39,14 +39,16 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
|
||||
function deleteDataView(spaceId: string) {
|
||||
return supertest
|
||||
.delete(`/s/${spaceId}/api/saved_objects/index-pattern/${getDataViewId(spaceId)}?force=true`)
|
||||
.delete(
|
||||
`/s/${spaceId}/api/saved_objects/index-pattern/${getStaticDataViewId(spaceId)}?force=true`
|
||||
)
|
||||
.set('kbn-xsrf', 'foo');
|
||||
}
|
||||
|
||||
function getDataView({ spaceId }: { spaceId: string }) {
|
||||
const spacePrefix = spaceId !== 'default' ? `/s/${spaceId}` : '';
|
||||
return supertest.get(
|
||||
`${spacePrefix}/api/saved_objects/index-pattern/${getDataViewId(spaceId)}`
|
||||
`${spacePrefix}/api/saved_objects/index-pattern/${getStaticDataViewId(spaceId)}`
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -170,5 +170,6 @@
|
|||
"@kbn/slo-plugin",
|
||||
"@kbn/aiops-test-utils",
|
||||
"@kbn/observability-ai-assistant-app-plugin",
|
||||
"@kbn/apm-data-view",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -3198,6 +3198,10 @@
|
|||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@kbn/apm-data-view@link:packages/kbn-apm-data-view":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@kbn/apm-plugin@link:x-pack/plugins/observability_solution/apm":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue