From 5461cf8c2cd9f94d4f0bfbeae7b1f560aa42e8c3 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 29 Apr 2021 01:08:00 +0200 Subject: [PATCH 01/26] wip --- .../apm_observability_overview_fetchers.ts | 4 +- .../lib/observability_overview/has_data.ts | 10 +++- .../server/routes/observability_overview.ts | 3 +- .../configurations/constants/constants.ts | 10 ++++ .../configurations/default_configs.ts | 3 + .../mobile/response_duration_config.ts | 57 +++++++++++++++++++ .../hooks/use_app_index_pattern.tsx | 3 +- .../series_builder/columns/data_types_col.tsx | 1 + .../series_builder/series_builder.tsx | 6 ++ .../shared/exploratory_view/types.ts | 3 +- .../utils/observability_index_patterns.ts | 3 + .../typings/fetch_overview_data/index.ts | 2 +- 12 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts diff --git a/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.ts b/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.ts index 3a02efd05e5a5..ef61e25af4fc2 100644 --- a/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.ts +++ b/x-pack/plugins/apm/public/services/rest/apm_observability_overview_fetchers.ts @@ -53,10 +53,8 @@ export const fetchObservabilityOverviewPageData = async ({ }; export async function getHasData() { - const res = await callApmApi({ + return await callApmApi({ endpoint: 'GET /api/apm/observability_overview/has_data', signal: null, }); - - return res.hasData; } diff --git a/x-pack/plugins/apm/server/lib/observability_overview/has_data.ts b/x-pack/plugins/apm/server/lib/observability_overview/has_data.ts index bbe13874d7d3b..2a2696b65f931 100644 --- a/x-pack/plugins/apm/server/lib/observability_overview/has_data.ts +++ b/x-pack/plugins/apm/server/lib/observability_overview/has_data.ts @@ -28,9 +28,15 @@ export function getHasData({ setup }: { setup: Setup }) { }; const response = await apmEventClient.search(params); - return response.hits.total.value > 0; + return { + hasData: response.hits.total.value > 0, + indices: setup.indices['apm_oss.transactionIndices']!, + }; } catch (e) { - return false; + return { + hasData: false, + indices: setup.indices['apm_oss.transactionIndices']!, + }; } }); } diff --git a/x-pack/plugins/apm/server/routes/observability_overview.ts b/x-pack/plugins/apm/server/routes/observability_overview.ts index d459570cf7337..c2e3d0e81ce0a 100644 --- a/x-pack/plugins/apm/server/routes/observability_overview.ts +++ b/x-pack/plugins/apm/server/routes/observability_overview.ts @@ -21,8 +21,7 @@ const observabilityOverviewHasDataRoute = createApmServerRoute({ options: { tags: ['access:apm'] }, handler: async (resources) => { const setup = await setupRequest(resources); - const res = await getHasData({ setup }); - return { hasData: res }; + return await getHasData({ setup }); }, }); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts index 0e1e1681373cb..9c0d84f698c5b 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts @@ -41,6 +41,15 @@ export const FieldLabels: Record = { 'performance.metric': 'Metric', 'Business.KPI': 'KPI', + + 'labels.net_connection_carrier_name': 'Carrier Name', + 'http.request.method': 'Request Method', + 'labels.net_connection_type': 'Connection Type', + 'host.os.full': 'Host OS', + 'host.os.platform': 'OS Platform', + 'labels.device_model': ' Device Model', + // eslint-disable-next-line @typescript-eslint/naming-convention + 'labels.net_connection_carrier_isoCountryCode': 'Carrier Location', }; export const DataViewLabels: Record = { @@ -54,6 +63,7 @@ export const DataViewLabels: Record = { logs: 'Logs Frequency', mem: 'System Memory Usage', nwk: 'Network Activity', + mrp: 'Mobile response duration', }; export const ReportToDataTypeMap: Record = { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts index c6089b2316784..2ad3f8765db6e 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts @@ -17,6 +17,7 @@ import { getMemoryUsageLensConfig } from './metrics/memory_usage_config'; import { getNetworkActivityLensConfig } from './metrics/network_activity_config'; import { getLogsFrequencyLensConfig } from './logs/logs_frequency_config'; import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns'; +import { getResponseDurationLensConfig } from './mobile/response_duration_config'; interface Props { reportType: keyof typeof ReportViewTypes; @@ -34,6 +35,8 @@ export const getDefaultConfigs = ({ reportType, seriesId, indexPattern }: Props) return getMonitorDurationConfig({ seriesId, indexPattern }); case 'uptime-pings': return getMonitorPingsConfig({ seriesId, indexPattern }); + case 'response-duration': + return getResponseDurationLensConfig({ seriesId, indexPattern }); case 'service-latency': return getServiceLatencyLensConfig({ seriesId, indexPattern }); case 'service-throughput': diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts new file mode 100644 index 0000000000000..8c3dfc935bb0f --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts @@ -0,0 +1,57 @@ +/* + * 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 { ConfigProps, DataSeries } from '../../types'; +import { FieldLabels } from '../constants'; +import { buildPhraseFilter } from '../utils'; +import { SERVICE_NAME, TRANSACTION_DURATION } from '../constants/elasticsearch_fieldnames'; + +export function getResponseDurationLensConfig({ seriesId, indexPattern }: ConfigProps): DataSeries { + return { + id: seriesId, + reportType: 'service-latency', + defaultSeriesType: 'line', + seriesTypes: ['line', 'bar'], + xAxisColumn: { + sourceField: '@timestamp', + }, + yAxisColumns: [ + { + operationType: 'average', + sourceField: 'transaction.duration.us', + label: 'Latency', + }, + ], + hasOperationType: true, + defaultFilters: [ + 'labels.net_connection_carrier_name', + 'labels.device_model', + 'labels.net_connection_type', + 'host.os.platform', + 'host.os.full', + ], + breakdowns: [ + 'labels.net_connection_carrier_name', + 'labels.device_model', + 'labels.net_connection_type', + 'host.os.platform', + 'labels.net_connection_carrier_isoCountryCode', + ], + filters: buildPhraseFilter('transaction.type', 'request', indexPattern), + labels: { + ...FieldLabels, + [TRANSACTION_DURATION]: 'Response time', + [SERVICE_NAME]: 'Mobile app', + }, + reportDefinitions: [ + { + field: 'service.name', + required: true, + }, + ], + }; +} diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx index 4f13cf6a1f9ca..52a5624c000d3 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx @@ -41,6 +41,7 @@ export function IndexPatternContextProvider({ children }: ProviderProps) { synthetics: null, ux: null, apm: null, + mobile: null, } as HasAppDataState); const { @@ -48,7 +49,7 @@ export function IndexPatternContextProvider({ children }: ProviderProps) { } = useKibana(); const checkIfAppHasData = async (dataType: AppDataType) => { - const handler = getDataHandler(dataType); + const handler = getDataHandler(dataType === 'mobile' ? 'apm' : dataType); return handler?.hasData(); }; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/data_types_col.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/data_types_col.tsx index 9d15206db1e62..784ec947774be 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/data_types_col.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/data_types_col.tsx @@ -16,6 +16,7 @@ import { ReportToDataTypeMap } from '../../configurations/constants'; export const dataTypes: Array<{ id: AppDataType; label: string }> = [ { id: 'synthetics', label: 'Synthetic Monitoring' }, { id: 'ux', label: 'User Experience (RUM)' }, + { id: 'mobile', label: 'Mobile Experience' }, // { id: 'infra_logs', label: 'Logs' }, // { id: 'infra_metrics', label: 'Metrics' }, // { id: 'apm', label: 'APM' }, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx index 5e270524b1880..ce0b00e510267 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx @@ -28,6 +28,12 @@ export const ReportTypes: Record = T[keyof T]; @@ -95,7 +96,7 @@ export interface ConfigProps { indexPattern: IIndexPattern; } -export type AppDataType = 'synthetics' | 'ux' | 'infra_logs' | 'infra_metrics' | 'apm'; +export type AppDataType = 'synthetics' | 'ux' | 'infra_logs' | 'infra_metrics' | 'apm' | 'mobile'; type FormatType = 'duration' | 'number'; type InputFormat = 'microseconds' | 'milliseconds' | 'seconds'; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/utils/observability_index_patterns.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/utils/observability_index_patterns.ts index c265bad56e864..c9b634c78d83d 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/utils/observability_index_patterns.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/utils/observability_index_patterns.ts @@ -23,6 +23,7 @@ const appFieldFormats: Record = { ux: rumFieldFormats, apm: apmFieldFormats, synthetics: syntheticsFieldFormats, + mobile: null, }; function getFieldFormatsForApp(app: AppDataType) { @@ -35,6 +36,7 @@ export const indexPatternList: Record = { ux: 'rum_static_index_pattern_id', infra_logs: 'infra_logs_static_index_pattern_id', infra_metrics: 'infra_metrics_static_index_pattern_id', + mobile: 'mobile_static_index_pattern_id', }; const appToPatternMap: Record = { @@ -43,6 +45,7 @@ const appToPatternMap: Record = { ux: '(rum-data-view)*', infra_logs: '', infra_metrics: '', + mobile: '(mobile-data-view)*', }; const getAppIndicesWithPattern = (app: AppDataType, indices: string) => { diff --git a/x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts b/x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts index 6b69aa9888cf6..337a294cfb3be 100644 --- a/x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts +++ b/x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts @@ -134,7 +134,7 @@ export interface ObservabilityFetchDataResponse { } export interface ObservabilityHasDataResponse { - apm: boolean; + apm: HasDataResponse; infra_metrics: boolean; infra_logs: boolean; synthetics: HasDataResponse; From 9626988932885795d1171bedae3466a51366b853 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Fri, 7 May 2021 07:43:22 +0200 Subject: [PATCH 02/26] wip --- .../configurations/mobile/response_duration_config.ts | 5 ++++- .../exploratory_view/utils/observability_index_patterns.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts index 8c3dfc935bb0f..79f04aae40bc0 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts @@ -41,7 +41,10 @@ export function getResponseDurationLensConfig({ seriesId, indexPattern }: Config 'host.os.platform', 'labels.net_connection_carrier_isoCountryCode', ], - filters: buildPhraseFilter('transaction.type', 'request', indexPattern), + filters: [ + ...buildPhraseFilter('transaction.type', 'request', indexPattern), + ...buildPhraseFilter('agent.name', 'opentelemetry/swift', indexPattern), + ], labels: { ...FieldLabels, [TRANSACTION_DURATION]: 'Response time', diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/utils/observability_index_patterns.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/utils/observability_index_patterns.ts index c9b634c78d83d..c5fdbe6d8448c 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/utils/observability_index_patterns.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/utils/observability_index_patterns.ts @@ -23,7 +23,7 @@ const appFieldFormats: Record = { ux: rumFieldFormats, apm: apmFieldFormats, synthetics: syntheticsFieldFormats, - mobile: null, + mobile: apmFieldFormats, }; function getFieldFormatsForApp(app: AppDataType) { From 720c68fb01e8252ebe7f4112a5b14120c968e4ef Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 2 Jun 2021 19:21:00 +0200 Subject: [PATCH 03/26] update --- .../exploratory_view/configurations/constants/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts index a75a41a522daf..3471093caf8ed 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts @@ -81,7 +81,6 @@ export const FieldLabels: Record = { 'performance.metric': METRIC_LABEL, 'Business.KPI': KPI_LABEL, - 'labels.net_connection_carrier_name': 'Carrier Name', 'http.request.method': 'Request Method', 'labels.net_connection_type': 'Connection Type', @@ -119,6 +118,7 @@ export const ReportToDataTypeMap: Record = { logs: 'infra_logs', cpu: 'infra_metrics', cwv: 'ux', + mrp: 'ux', }; export const USE_BREAK_DOWN_COLUMN = 'USE_BREAK_DOWN_COLUMN'; From e8a678f51e72dd47d26f2c90d00ddd22da655989 Mon Sep 17 00:00:00 2001 From: Bryce Buchanan Date: Wed, 2 Jun 2021 15:34:31 -0700 Subject: [PATCH 04/26] updated agent filter name to 'iOS/swift' added additional default filters & breakdowns. --- .../exploratory_view/configurations/constants/constants.ts | 1 + .../configurations/mobile/response_duration_config.ts | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts index 00fdcb12e07b8..f2dd7b2fe24aa 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts @@ -85,6 +85,7 @@ export const FieldLabels: Record = { 'http.request.method': 'Request Method', 'labels.net_connection_type': 'Connection Type', 'host.os.full': 'Host OS', + 'service.version': 'Service Version', 'host.os.platform': 'OS Platform', 'labels.device_model': ' Device Model', // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts index 79f04aae40bc0..1547328562f0e 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts @@ -33,17 +33,20 @@ export function getResponseDurationLensConfig({ seriesId, indexPattern }: Config 'labels.net_connection_type', 'host.os.platform', 'host.os.full', + 'service.version', ], breakdowns: [ 'labels.net_connection_carrier_name', 'labels.device_model', 'labels.net_connection_type', 'host.os.platform', + 'host.os.full', + 'service.version', 'labels.net_connection_carrier_isoCountryCode', ], filters: [ ...buildPhraseFilter('transaction.type', 'request', indexPattern), - ...buildPhraseFilter('agent.name', 'opentelemetry/swift', indexPattern), + ...buildPhraseFilter('agent.name', 'iOS/swift', indexPattern), ], labels: { ...FieldLabels, From 9884d27b344cc9e555a6321650a34cf664494d41 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 8 Jun 2021 20:28:39 +0200 Subject: [PATCH 05/26] update memory and cpu --- .../configurations/apm/field_formats.ts | 14 ++- .../constants/elasticsearch_fieldnames.ts | 2 + .../configurations/default_configs.ts | 6 +- .../mobile/kpi_over_time_config.ts | 90 +++++++++++++++++++ .../mobile/response_duration_config.ts | 63 ------------- .../series_builder/series_builder.tsx | 4 +- .../shared/exploratory_view/types.ts | 8 +- 7 files changed, 114 insertions(+), 73 deletions(-) create mode 100644 x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts delete mode 100644 x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/apm/field_formats.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/apm/field_formats.ts index 8d33dfbab2c62..6fb46929e07e4 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/apm/field_formats.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/apm/field_formats.ts @@ -6,7 +6,11 @@ */ import { FieldFormat } from '../../types'; -import { TRANSACTION_DURATION } from '../constants/elasticsearch_fieldnames'; +import { + METRIC_SYSTEM_CPU_USAGE, + METRIC_SYSTEM_MEMORY_USAGE, + TRANSACTION_DURATION, +} from '../constants/elasticsearch_fieldnames'; export const apmFieldFormats: FieldFormat[] = [ { @@ -21,4 +25,12 @@ export const apmFieldFormats: FieldFormat[] = [ }, }, }, + { + field: METRIC_SYSTEM_MEMORY_USAGE, + format: { id: 'bytes', params: {} }, + }, + { + field: METRIC_SYSTEM_CPU_USAGE, + format: { id: 'percent', params: {} }, + }, ]; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/elasticsearch_fieldnames.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/elasticsearch_fieldnames.ts index 5ecc5b758de84..01dd2a49b9be0 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/elasticsearch_fieldnames.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/elasticsearch_fieldnames.ts @@ -86,6 +86,8 @@ export const ERROR_PAGE_URL = 'error.page.url'; // METRICS export const METRIC_SYSTEM_FREE_MEMORY = 'system.memory.actual.free'; +export const METRIC_SYSTEM_MEMORY_USAGE = 'system.memory.usage'; +export const METRIC_SYSTEM_CPU_USAGE = 'system.cpu.usage'; export const METRIC_SYSTEM_TOTAL_MEMORY = 'system.memory.total'; export const METRIC_SYSTEM_CPU_PERCENT = 'system.cpu.total.norm.pct'; export const METRIC_PROCESS_CPU_PERCENT = 'system.process.cpu.total.norm.pct'; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts index 174b7506a8a5c..83c4061443666 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts @@ -18,7 +18,7 @@ import { getNetworkActivityLensConfig } from './metrics/network_activity_config' import { getLogsFrequencyLensConfig } from './logs/logs_frequency_config'; import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns'; import { getCoreWebVitalsConfig } from './rum/core_web_vitals_config'; -import { getResponseDurationLensConfig } from './mobile/response_duration_config'; +import { getMobileKPIConfig } from './mobile/kpi_over_time_config'; interface Props { reportType: keyof typeof ReportViewTypes; @@ -38,8 +38,8 @@ export const getDefaultConfigs = ({ reportType, seriesId, indexPattern }: Props) return getMonitorDurationConfig({ seriesId, indexPattern }); case 'uptime-pings': return getMonitorPingsConfig({ seriesId, indexPattern }); - case 'response-duration': - return getResponseDurationLensConfig({ seriesId, indexPattern }); + case 'mobile-kpi': + return getMobileKPIConfig({ seriesId, indexPattern }); case 'service-latency': return getServiceLatencyLensConfig({ seriesId, indexPattern }); case 'service-throughput': diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts new file mode 100644 index 0000000000000..451582c13916d --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts @@ -0,0 +1,90 @@ +/* + * 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 { ConfigProps, DataSeries } from '../../types'; +import { FieldLabels, OPERATION_COLUMN } from '../constants'; +import { buildPhraseFilter } from '../utils'; +import { + METRIC_SYSTEM_CPU_USAGE, + METRIC_SYSTEM_MEMORY_USAGE, + SERVICE_NAME, + TRANSACTION_DURATION, +} from '../constants/elasticsearch_fieldnames'; + +export function getMobileKPIConfig({ seriesId, indexPattern }: ConfigProps): DataSeries { + return { + id: seriesId, + reportType: 'service-latency', + defaultSeriesType: 'line', + seriesTypes: ['line', 'bar'], + xAxisColumn: { + sourceField: '@timestamp', + }, + yAxisColumns: [ + { + sourceField: 'business.kpi', + operationType: 'median', + }, + ], + hasOperationType: true, + defaultFilters: [ + 'labels.net_connection_carrier_name', + 'labels.device_model', + 'labels.net_connection_type', + 'host.os.platform', + 'host.os.full', + 'service.version', + ], + breakdowns: [ + 'labels.net_connection_carrier_name', + 'labels.device_model', + 'labels.net_connection_type', + 'host.os.platform', + 'host.os.full', + 'service.version', + 'labels.net_connection_carrier_isoCountryCode', + ], + filters: [...buildPhraseFilter('agent.name', 'iOS/swift', indexPattern)], + labels: { + ...FieldLabels, + [TRANSACTION_DURATION]: 'Response latency', + [SERVICE_NAME]: 'Mobile app', + [METRIC_SYSTEM_MEMORY_USAGE]: 'Memory usage', + [METRIC_SYSTEM_MEMORY_USAGE]: 'CPU usage', + }, + reportDefinitions: [ + { + field: SERVICE_NAME, + required: true, + }, + { + field: 'business.kpi', + custom: true, + options: [ + { + label: 'Response latency', + field: TRANSACTION_DURATION, + id: TRANSACTION_DURATION, + columnType: OPERATION_COLUMN, + }, + { + label: 'Memory Usage', + field: METRIC_SYSTEM_MEMORY_USAGE, + id: METRIC_SYSTEM_MEMORY_USAGE, + columnType: OPERATION_COLUMN, + }, + { + label: 'CPU Usage', + field: METRIC_SYSTEM_CPU_USAGE, + id: METRIC_SYSTEM_CPU_USAGE, + columnType: OPERATION_COLUMN, + }, + ], + }, + ], + }; +} diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts deleted file mode 100644 index 1547328562f0e..0000000000000 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/response_duration_config.ts +++ /dev/null @@ -1,63 +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. - */ - -import { ConfigProps, DataSeries } from '../../types'; -import { FieldLabels } from '../constants'; -import { buildPhraseFilter } from '../utils'; -import { SERVICE_NAME, TRANSACTION_DURATION } from '../constants/elasticsearch_fieldnames'; - -export function getResponseDurationLensConfig({ seriesId, indexPattern }: ConfigProps): DataSeries { - return { - id: seriesId, - reportType: 'service-latency', - defaultSeriesType: 'line', - seriesTypes: ['line', 'bar'], - xAxisColumn: { - sourceField: '@timestamp', - }, - yAxisColumns: [ - { - operationType: 'average', - sourceField: 'transaction.duration.us', - label: 'Latency', - }, - ], - hasOperationType: true, - defaultFilters: [ - 'labels.net_connection_carrier_name', - 'labels.device_model', - 'labels.net_connection_type', - 'host.os.platform', - 'host.os.full', - 'service.version', - ], - breakdowns: [ - 'labels.net_connection_carrier_name', - 'labels.device_model', - 'labels.net_connection_type', - 'host.os.platform', - 'host.os.full', - 'service.version', - 'labels.net_connection_carrier_isoCountryCode', - ], - filters: [ - ...buildPhraseFilter('transaction.type', 'request', indexPattern), - ...buildPhraseFilter('agent.name', 'iOS/swift', indexPattern), - ], - labels: { - ...FieldLabels, - [TRANSACTION_DURATION]: 'Response time', - [SERVICE_NAME]: 'Mobile app', - }, - reportDefinitions: [ - { - field: 'service.name', - required: true, - }, - ], - }; -} diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx index 732b7b842c869..6d2d6dbcc0c1d 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx @@ -31,8 +31,8 @@ export const ReportTypes: Record = T[keyof T]; @@ -107,13 +107,13 @@ export interface ConfigProps { export type AppDataType = 'synthetics' | 'ux' | 'infra_logs' | 'infra_metrics' | 'apm' | 'mobile'; -type FormatType = 'duration' | 'number'; +type FormatType = 'duration' | 'number' | 'bytes' | 'percent'; type InputFormat = 'microseconds' | 'milliseconds' | 'seconds'; type OutputFormat = 'asSeconds' | 'asMilliseconds' | 'humanize'; export interface FieldFormatParams { - inputFormat: InputFormat; - outputFormat: OutputFormat; + inputFormat?: InputFormat; + outputFormat?: OutputFormat; outputPrecision?: number; showSuffix?: boolean; } From 487e9c44db43dac2b0fe73ca69c62601b5ece0b6 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 8 Jun 2021 20:30:33 +0200 Subject: [PATCH 06/26] fix --- .../configurations/mobile/kpi_over_time_config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts index 451582c13916d..6466aa427d393 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts @@ -54,7 +54,7 @@ export function getMobileKPIConfig({ seriesId, indexPattern }: ConfigProps): Dat [TRANSACTION_DURATION]: 'Response latency', [SERVICE_NAME]: 'Mobile app', [METRIC_SYSTEM_MEMORY_USAGE]: 'Memory usage', - [METRIC_SYSTEM_MEMORY_USAGE]: 'CPU usage', + [METRIC_SYSTEM_CPU_USAGE]: 'CPU usage', }, reportDefinitions: [ { From f71aa4814564245986e54288f7c0c59221c02b41 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 10 Jun 2021 11:01:58 +0200 Subject: [PATCH 07/26] fix types --- .../public/context/has_data_context.test.tsx | 8 ++++++-- .../public/pages/overview/overview.stories.tsx | 14 +++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/observability/public/context/has_data_context.test.tsx b/x-pack/plugins/observability/public/context/has_data_context.test.tsx index b5a0806306461..f0ef17bd0ccad 100644 --- a/x-pack/plugins/observability/public/context/has_data_context.test.tsx +++ b/x-pack/plugins/observability/public/context/has_data_context.test.tsx @@ -279,7 +279,9 @@ describe('HasDataContextProvider', () => { describe('only apm is registered', () => { describe('when apm returns true', () => { beforeAll(() => { - registerApps([{ appName: 'apm', hasData: async () => true }]); + registerApps([ + { appName: 'apm', hasData: async () => ({ hasData: true, indices: 'apm-*' }) }, + ]); }); afterAll(unregisterAll); @@ -317,7 +319,9 @@ describe('HasDataContextProvider', () => { describe('when apm returns false', () => { beforeAll(() => { - registerApps([{ appName: 'apm', hasData: async () => false }]); + registerApps([ + { appName: 'apm', hasData: async () => ({ indices: 'apm-*', hasData: false }) }, + ]); }); afterAll(unregisterAll); diff --git a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx index 2482ae7a8e7ab..f1f1d7ea41ee5 100644 --- a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx +++ b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx @@ -177,7 +177,7 @@ storiesOf('app/Overview', module) registerDataHandler({ appName: 'apm', fetchData: fetchApmData, - hasData: async () => false, + hasData: async () => ({ hasData: false, indices: 'apm-*' }), }); registerDataHandler({ appName: 'infra_logs', @@ -272,7 +272,7 @@ storiesOf('app/Overview', module) registerDataHandler({ appName: 'apm', fetchData: fetchApmData, - hasData: async () => true, + hasData: async () => ({ hasData: true, indices: 'apm-*' }), }); return ( @@ -289,7 +289,7 @@ storiesOf('app/Overview', module) registerDataHandler({ appName: 'apm', fetchData: fetchApmData, - hasData: async () => true, + hasData: async () => ({ hasData: true, indices: 'apm-*' }), }); registerDataHandler({ appName: 'infra_logs', @@ -321,7 +321,7 @@ storiesOf('app/Overview', module) registerDataHandler({ appName: 'apm', fetchData: fetchApmData, - hasData: async () => true, + hasData: async () => ({ hasData: true, indices: 'apm-*' }), }); registerDataHandler({ appName: 'infra_logs', @@ -355,7 +355,7 @@ storiesOf('app/Overview', module) registerDataHandler({ appName: 'apm', fetchData: fetchApmData, - hasData: async () => true, + hasData: async () => ({ hasData: true, indices: 'apm-*' }), }); registerDataHandler({ appName: 'infra_logs', @@ -386,7 +386,7 @@ storiesOf('app/Overview', module) registerDataHandler({ appName: 'apm', fetchData: async () => emptyAPMResponse, - hasData: async () => true, + hasData: async () => ({ hasData: true, indices: 'apm-*' }), }); registerDataHandler({ appName: 'infra_logs', @@ -420,7 +420,7 @@ storiesOf('app/Overview', module) fetchData: async () => { throw new Error('Error fetching APM data'); }, - hasData: async () => true, + hasData: async () => ({ hasData: true, indices: 'apm-*' }), }); registerDataHandler({ appName: 'infra_logs', From 2cb4f1aaafde0eecc9614da0e991545c30509252 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 10 Jun 2021 11:50:23 +0200 Subject: [PATCH 08/26] fix type and filters --- .../configurations/constants/constants.ts | 5 ++- .../configurations/constants/labels.ts | 7 ++++ .../series_builder/columns/report_filters.tsx | 1 + .../series_editor/columns/filter_expanded.tsx | 39 +++++++++++++++++-- .../series_editor/columns/series_filter.tsx | 4 +- .../observability/public/data_handler.test.ts | 4 +- 6 files changed, 52 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts index 8206a1192b8d8..13e4b1b9ae802 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts @@ -26,6 +26,7 @@ import { LOGS_FREQUENCY_LABEL, MEMORY_USAGE_LABEL, METRIC_LABEL, + MOBILE_RESPONSE_LABEL, MONITOR_DURATION_LABEL, MONITOR_ID_LABEL, MONITOR_NAME_LABEL, @@ -104,7 +105,7 @@ export const DataViewLabels: Record = { mem: MEMORY_USAGE_LABEL, nwk: NETWORK_ACTIVITY_LABEL, cwv: CORE_WEB_VITALS_LABEL, - mrp: 'Mobile response duration', + mkpi: MOBILE_RESPONSE_LABEL, }; export const ReportToDataTypeMap: Record = { @@ -119,7 +120,7 @@ export const ReportToDataTypeMap: Record = { logs: 'infra_logs', cpu: 'infra_metrics', cwv: 'ux', - mrp: 'ux', + mkpi: 'apm', }; export const USE_BREAK_DOWN_COLUMN = 'USE_BREAK_DOWN_COLUMN'; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts index 92150a76319f8..7cd285ffe8447 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts @@ -208,6 +208,13 @@ export const CORE_WEB_VITALS_LABEL = i18n.translate( } ); +export const MOBILE_RESPONSE_LABEL = i18n.translate( + 'xpack.observability.expView.fieldLabels.mobileReponse', + { + defaultMessage: 'Mobile response', + } +); + export const MEMORY_USAGE_LABEL = i18n.translate( 'xpack.observability.expView.fieldLabels.memoryUsage', { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.tsx index 9687f1bea4ec9..d0aad4c377a0d 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.tsx @@ -20,6 +20,7 @@ export function ReportFilters({ diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/filter_expanded.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/filter_expanded.tsx index cc1769cfa8c95..9591556a32fda 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/filter_expanded.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/filter_expanded.tsx @@ -6,16 +6,20 @@ */ import React, { useState, Fragment } from 'react'; -import { EuiFieldSearch, EuiSpacer, EuiButtonEmpty, EuiFilterGroup } from '@elastic/eui'; +import { EuiFieldSearch, EuiSpacer, EuiButtonEmpty, EuiFilterGroup, EuiText } from '@elastic/eui'; import styled from 'styled-components'; import { rgba } from 'polished'; import { i18n } from '@kbn/i18n'; +import { QueryDslQueryContainer } from '@elastic/elasticsearch/api/types'; import { useAppIndexPatternContext } from '../../hooks/use_app_index_pattern'; import { useSeriesStorage } from '../../hooks/use_series_storage'; -import { UrlFilter } from '../../types'; +import { DataSeries, UrlFilter } from '../../types'; import { FilterValueButton } from './filter_value_btn'; import { useValuesList } from '../../../../../hooks/use_values_list'; import { euiStyled } from '../../../../../../../../../src/plugins/kibana_react/common'; +import { ESFilter } from '../../../../../../../../../typings/elasticsearch'; +import { PersistableFilter } from '../../../../../../../lens/common'; +import { ExistsFilter } from '../../../../../../../../../src/plugins/data/common/es_query/filters'; interface Props { seriesId: string; @@ -24,9 +28,18 @@ interface Props { isNegated?: boolean; goBack: () => void; nestedField?: string; + filters: DataSeries['filters']; } -export function FilterExpanded({ seriesId, field, label, goBack, nestedField, isNegated }: Props) { +export function FilterExpanded({ + seriesId, + field, + label, + goBack, + nestedField, + isNegated, + filters: defaultFilters, +}: Props) { const { indexPattern } = useAppIndexPatternContext(); const [value, setValue] = useState(''); @@ -37,12 +50,25 @@ export function FilterExpanded({ seriesId, field, label, goBack, nestedField, is const series = getSeries(seriesId); + const queryFilters: ESFilter[] = []; + + defaultFilters?.forEach((qFilter: PersistableFilter | ExistsFilter) => { + if (qFilter.query) { + queryFilters.push(qFilter.query); + } + const asExistFilter = qFilter as ExistsFilter; + if (asExistFilter?.exists) { + queryFilters.push(asExistFilter.exists as QueryDslQueryContainer); + } + }); + const { values, loading } = useValuesList({ query: value, indexPattern, sourceField: field, time: series.time, keepHistory: true, + filters: queryFilters, }); const filters = series?.filters ?? []; @@ -70,6 +96,13 @@ export function FilterExpanded({ seriesId, field, label, goBack, nestedField, is /> + {displayValues.length === 0 && !loading && ( + + {i18n.translate('xpack.observability.filters.expanded.noFilter', { + defaultMessage: 'No filters found.', + })} + + )} {displayValues.map((opt) => ( diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/series_filter.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/series_filter.tsx index 9e5770c2de8f9..248279350ed35 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/series_filter.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/series_filter.tsx @@ -24,6 +24,7 @@ import { useSeriesStorage } from '../../hooks/use_series_storage'; interface Props { seriesId: string; defaultFilters: DataSeries['defaultFilters']; + filters: DataSeries['filters']; series: DataSeries; isNew?: boolean; } @@ -35,7 +36,7 @@ export interface Field { isNegated?: boolean; } -export function SeriesFilter({ series, isNew, seriesId, defaultFilters = [] }: Props) { +export function SeriesFilter({ series, isNew, seriesId, defaultFilters = [], filters }: Props) { const [isPopoverVisible, setIsPopoverVisible] = useState(false); const [selectedField, setSelectedField] = useState(); @@ -102,6 +103,7 @@ export function SeriesFilter({ series, isNew, seriesId, defaultFilters = [] }: P goBack={() => { setSelectedField(undefined); }} + filters={filters} /> ) : null; diff --git a/x-pack/plugins/observability/public/data_handler.test.ts b/x-pack/plugins/observability/public/data_handler.test.ts index 385a0c7d40c20..87d4c72d99aa7 100644 --- a/x-pack/plugins/observability/public/data_handler.test.ts +++ b/x-pack/plugins/observability/public/data_handler.test.ts @@ -23,7 +23,7 @@ const params = { describe('registerDataHandler', () => { const originalConsole = global.console; beforeAll(() => { - // mocks console to avoid poluting the test output + // mocks console to avoid polluting the test output global.console = ({ error: jest.fn() } as unknown) as typeof console; }); @@ -58,7 +58,7 @@ describe('registerDataHandler', () => { }, }; }, - hasData: async () => true, + hasData: async () => ({ hasData: true, indices: 'apm-*' }), }); it('registered data handler', () => { From e54969c873e5820372aa6f5247e6d612e811ca88 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 10 Jun 2021 16:57:35 +0200 Subject: [PATCH 09/26] fix image --- .../public/context/has_data_context.test.tsx | 10 ++++++++-- .../observability/public/context/has_data_context.tsx | 11 ++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/observability/public/context/has_data_context.test.tsx b/x-pack/plugins/observability/public/context/has_data_context.test.tsx index f0ef17bd0ccad..d8b91d7b4eeb9 100644 --- a/x-pack/plugins/observability/public/context/has_data_context.test.tsx +++ b/x-pack/plugins/observability/public/context/has_data_context.test.tsx @@ -302,7 +302,7 @@ describe('HasDataContextProvider', () => { expect(result.current).toEqual({ hasData: { - apm: { hasData: true, status: 'success' }, + apm: { hasData: { hasData: true, indices: 'apm-*' }, status: 'success' }, synthetics: { hasData: undefined, status: 'success' }, infra_logs: { hasData: undefined, status: 'success' }, infra_metrics: { hasData: undefined, status: 'success' }, @@ -342,7 +342,13 @@ describe('HasDataContextProvider', () => { expect(result.current).toEqual({ hasData: { - apm: { hasData: false, status: 'success' }, + apm: { + hasData: { + hasData: false, + indices: 'apm-*', + }, + status: 'success', + }, synthetics: { hasData: undefined, status: 'success' }, infra_logs: { hasData: undefined, status: 'success' }, infra_metrics: { hasData: undefined, status: 'success' }, diff --git a/x-pack/plugins/observability/public/context/has_data_context.tsx b/x-pack/plugins/observability/public/context/has_data_context.tsx index 97aa72f07b09c..25c8b50b39b5c 100644 --- a/x-pack/plugins/observability/public/context/has_data_context.tsx +++ b/x-pack/plugins/observability/public/context/has_data_context.tsx @@ -14,13 +14,17 @@ import { FETCH_STATUS } from '../hooks/use_fetcher'; import { usePluginContext } from '../hooks/use_plugin_context'; import { useTimeRange } from '../hooks/use_time_range'; import { getObservabilityAlerts } from '../services/get_observability_alerts'; -import { ObservabilityFetchDataPlugins, UXHasDataResponse } from '../typings/fetch_overview_data'; +import { + HasDataResponse, + ObservabilityFetchDataPlugins, + UXHasDataResponse, +} from '../typings/fetch_overview_data'; type DataContextApps = ObservabilityFetchDataPlugins | 'alert'; export type HasDataMap = Record< DataContextApps, - { status: FETCH_STATUS; hasData?: boolean | UXHasDataResponse | Alert[] } + { status: FETCH_STATUS; hasData?: boolean | HasDataResponse | UXHasDataResponse | Alert[] } >; export interface HasDataContextValue { @@ -110,7 +114,8 @@ export function HasDataContextProvider({ children }: { children: React.ReactNode }); const hasAnyData = (Object.keys(hasData) as ObservabilityFetchDataPlugins[]).some( - (app) => hasData[app]?.hasData === true + (app) => + hasData[app]?.hasData === true || (hasData[app]?.hasData as HasDataResponse)?.hasData === true ); return ( From 1f9c6adaaaa4866791409889a9c4393bf18c39b3 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 10 Jun 2021 17:24:16 +0200 Subject: [PATCH 10/26] added mobile experience --- .../series_editor/columns/filter_expanded.test.tsx | 4 ++++ .../exploratory_view/series_editor/series_editor.tsx | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/filter_expanded.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/filter_expanded.test.tsx index 1a8c5b335bc4f..e123765ded5f5 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/filter_expanded.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/filter_expanded.test.tsx @@ -22,6 +22,7 @@ describe('FilterExpanded', function () { label={'Browser Family'} field={USER_AGENT_NAME} goBack={jest.fn()} + filters={[]} />, { initSeries } ); @@ -38,6 +39,7 @@ describe('FilterExpanded', function () { label={'Browser Family'} field={USER_AGENT_NAME} goBack={goBack} + filters={[]} />, { initSeries } ); @@ -61,6 +63,7 @@ describe('FilterExpanded', function () { label={'Browser Family'} field={USER_AGENT_NAME} goBack={goBack} + filters={[]} />, { initSeries } ); @@ -84,6 +87,7 @@ describe('FilterExpanded', function () { label={'Browser Family'} field={USER_AGENT_NAME} goBack={jest.fn()} + filters={[]} />, { initSeries } ); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/series_editor.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/series_editor.tsx index 6e513fcd2fec9..bf80c1706e50c 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/series_editor.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/series_editor.tsx @@ -44,7 +44,12 @@ export function SeriesEditor() { field: 'defaultFilters', width: '15%', render: (defaultFilters: string[], series: DataSeries) => ( - + ), }, { From 9421c50b52cae180999f7a0b9b3f6ef35a7f9267 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Mon, 14 Jun 2021 16:51:18 +0200 Subject: [PATCH 11/26] resolve conflicts --- .../configurations/apm/field_formats.ts | 1 + .../configurations/default_configs.ts | 5 +---- .../configurations/mobile/kpi_over_time_config.ts | 11 ++++++----- .../exploratory_view/series_editor/series_editor.tsx | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/apm/field_formats.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/apm/field_formats.ts index 6fb46929e07e4..5c1afbca2a776 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/apm/field_formats.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/apm/field_formats.ts @@ -22,6 +22,7 @@ export const apmFieldFormats: FieldFormat[] = [ outputFormat: 'asMilliseconds', outputPrecision: 0, showSuffix: true, + useShortSuffix: true, }, }, }, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts index 1977928f24f89..30ce1f47dc3cc 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts @@ -35,10 +35,7 @@ export const getDefaultConfigs = ({ reportType, dataType, indexPattern }: Props) return getSyntheticsDistributionConfig({ indexPattern }); } return getSyntheticsKPIConfig({ indexPattern }); - case 'synthetics': - if (reportType === 'dist') { - return getMobileKPIConfig({ indexPattern }); - } + case 'mobile': return getMobileKPIConfig({ indexPattern }); default: diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts index 6466aa427d393..1c78e2a515c69 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts @@ -7,7 +7,7 @@ import { ConfigProps, DataSeries } from '../../types'; import { FieldLabels, OPERATION_COLUMN } from '../constants'; -import { buildPhraseFilter } from '../utils'; +import { buildPhrasesFilter } from '../utils'; import { METRIC_SYSTEM_CPU_USAGE, METRIC_SYSTEM_MEMORY_USAGE, @@ -15,10 +15,9 @@ import { TRANSACTION_DURATION, } from '../constants/elasticsearch_fieldnames'; -export function getMobileKPIConfig({ seriesId, indexPattern }: ConfigProps): DataSeries { +export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { return { - id: seriesId, - reportType: 'service-latency', + reportType: 'kpi-over-time', defaultSeriesType: 'line', seriesTypes: ['line', 'bar'], xAxisColumn: { @@ -48,7 +47,9 @@ export function getMobileKPIConfig({ seriesId, indexPattern }: ConfigProps): Dat 'service.version', 'labels.net_connection_carrier_isoCountryCode', ], - filters: [...buildPhraseFilter('agent.name', 'iOS/swift', indexPattern)], + filters: [ + ...buildPhrasesFilter('agent.name', ['iOS/swift', 'open-telemetry/swift'], indexPattern), + ], labels: { ...FieldLabels, [TRANSACTION_DURATION]: 'Response latency', diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/series_editor.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/series_editor.tsx index ed8706a8d4ac5..17d4356dcf65b 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/series_editor.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/series_editor.tsx @@ -53,7 +53,7 @@ export function SeriesEditor() { defaultFilters={defaultFilters} seriesId={id} series={seriesConfig} - filters={series.filters} + filters={seriesConfig.filters} /> ), }, From 5192aa0a9aad2331ddea8773acded154b42e0f8c Mon Sep 17 00:00:00 2001 From: Shahzad Date: Mon, 14 Jun 2021 19:25:53 +0200 Subject: [PATCH 12/26] refactor code for has data --- .../lib/observability_overview/has_data.ts | 4 +- .../settings/apm_indices/get_apm_indices.ts | 16 +---- .../plugins/observability/common/typings.ts | 13 ++++ .../components/app/empty_sections/index.tsx | 6 +- .../components/app/section/apm/index.test.tsx | 2 +- .../components/app/section/apm/index.tsx | 4 +- .../components/app/section/logs/index.tsx | 4 +- .../components/app/section/metrics/index.tsx | 4 +- .../components/app/section/uptime/index.tsx | 4 +- .../components/app/section/ux/index.test.tsx | 2 +- .../components/app/section/ux/index.tsx | 4 +- .../hooks/use_app_index_pattern.tsx | 30 +++++---- .../utils/observability_index_patterns.ts | 1 + .../public/context/has_data_context.tsx | 66 ++++++++++++------- .../public/pages/home/index.test.tsx | 42 +++++++----- .../public/pages/overview/index.tsx | 4 +- .../typings/fetch_overview_data/index.ts | 17 ++++- 17 files changed, 133 insertions(+), 90 deletions(-) diff --git a/x-pack/plugins/apm/server/lib/observability_overview/has_data.ts b/x-pack/plugins/apm/server/lib/observability_overview/has_data.ts index 2a2696b65f931..425f67d90f1bd 100644 --- a/x-pack/plugins/apm/server/lib/observability_overview/has_data.ts +++ b/x-pack/plugins/apm/server/lib/observability_overview/has_data.ts @@ -30,12 +30,12 @@ export function getHasData({ setup }: { setup: Setup }) { const response = await apmEventClient.search(params); return { hasData: response.hits.total.value > 0, - indices: setup.indices['apm_oss.transactionIndices']!, + indices: setup.indices, }; } catch (e) { return { hasData: false, - indices: setup.indices['apm_oss.transactionIndices']!, + indices: setup.indices, }; } }); diff --git a/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts b/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts index d8dbc242986a6..0ade96682b362 100644 --- a/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts +++ b/x-pack/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts @@ -16,21 +16,11 @@ import { import { APMConfig } from '../../..'; import { APMRouteHandlerResources } from '../../../routes/typings'; import { withApmSpan } from '../../../utils/with_apm_span'; +import { ApmIndicesConfig } from '../../../../../observability/common/typings'; -type ISavedObjectsClient = Pick; +export { ApmIndicesConfig }; -export interface ApmIndicesConfig { - /* eslint-disable @typescript-eslint/naming-convention */ - 'apm_oss.sourcemapIndices': string; - 'apm_oss.errorIndices': string; - 'apm_oss.onboardingIndices': string; - 'apm_oss.spanIndices': string; - 'apm_oss.transactionIndices': string; - 'apm_oss.metricsIndices': string; - /* eslint-enable @typescript-eslint/naming-convention */ - apmAgentConfigurationIndex: string; - apmCustomLinkIndex: string; -} +type ISavedObjectsClient = Pick; export type ApmIndicesName = keyof ApmIndicesConfig; diff --git a/x-pack/plugins/observability/common/typings.ts b/x-pack/plugins/observability/common/typings.ts index bd10543ef389b..305a18903fe7e 100644 --- a/x-pack/plugins/observability/common/typings.ts +++ b/x-pack/plugins/observability/common/typings.ts @@ -10,3 +10,16 @@ export type Maybe = T | null | undefined; export const alertStatusRt = t.union([t.literal('all'), t.literal('open'), t.literal('closed')]); export type AlertStatus = t.TypeOf; + +export interface ApmIndicesConfig { + /* eslint-disable @typescript-eslint/naming-convention */ + 'apm_oss.sourcemapIndices': string; + 'apm_oss.errorIndices': string; + 'apm_oss.onboardingIndices': string; + 'apm_oss.spanIndices': string; + 'apm_oss.transactionIndices': string; + 'apm_oss.metricsIndices': string; + /* eslint-enable @typescript-eslint/naming-convention */ + apmAgentConfigurationIndex: string; + apmCustomLinkIndex: string; +} diff --git a/x-pack/plugins/observability/public/components/app/empty_sections/index.tsx b/x-pack/plugins/observability/public/components/app/empty_sections/index.tsx index f7ce8675d8a45..3c24e1f9547d0 100644 --- a/x-pack/plugins/observability/public/components/app/empty_sections/index.tsx +++ b/x-pack/plugins/observability/public/components/app/empty_sections/index.tsx @@ -19,17 +19,17 @@ import { EmptySection } from './empty_section'; export function EmptySections() { const { core } = usePluginContext(); const theme = useContext(ThemeContext); - const { hasData } = useHasData(); + const { hasDataMap } = useHasData(); const appEmptySections = getEmptySections({ core }).filter(({ id }) => { if (id === 'alert') { - const { status, hasData: alerts } = hasData.alert || {}; + const { status, hasData: alerts } = hasDataMap.alert || {}; return ( status === FETCH_STATUS.FAILURE || (status === FETCH_STATUS.SUCCESS && (alerts as Alert[]).length === 0) ); } else { - const app = hasData[id]; + const app = hasDataMap[id]; if (app) { const _hasData = id === 'ux' ? (app.hasData as UXHasDataResponse)?.hasData : app.hasData; return app.status === FETCH_STATUS.FAILURE || !_hasData; diff --git a/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx b/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx index ad3ecd2740802..16eb8dd24d3c2 100644 --- a/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx +++ b/x-pack/plugins/observability/public/components/app/section/apm/index.test.tsx @@ -29,7 +29,7 @@ jest.mock('react-router-dom', () => ({ describe('APMSection', () => { beforeAll(() => { jest.spyOn(hasDataHook, 'useHasData').mockReturnValue({ - hasData: { + hasDataMap: { apm: { status: fetcherHook.FETCH_STATUS.SUCCESS, hasData: true, diff --git a/x-pack/plugins/observability/public/components/app/section/apm/index.tsx b/x-pack/plugins/observability/public/components/app/section/apm/index.tsx index e71468d3b028c..7a42e96c3823d 100644 --- a/x-pack/plugins/observability/public/components/app/section/apm/index.tsx +++ b/x-pack/plugins/observability/public/components/app/section/apm/index.tsx @@ -48,7 +48,7 @@ export function APMSection({ bucketSize }: Props) { const theme = useContext(ThemeContext); const chartTheme = useChartTheme(); const history = useHistory(); - const { forceUpdate, hasData } = useHasData(); + const { forceUpdate, hasDataMap } = useHasData(); const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useTimeRange(); const { data, status } = useFetcher( @@ -66,7 +66,7 @@ export function APMSection({ bucketSize }: Props) { [bucketSize, relativeStart, relativeEnd, forceUpdate] ); - if (!hasData.apm?.hasData) { + if (!hasDataMap.apm?.hasData) { return null; } diff --git a/x-pack/plugins/observability/public/components/app/section/logs/index.tsx b/x-pack/plugins/observability/public/components/app/section/logs/index.tsx index cb4c831d25022..da5a8f25045a5 100644 --- a/x-pack/plugins/observability/public/components/app/section/logs/index.tsx +++ b/x-pack/plugins/observability/public/components/app/section/logs/index.tsx @@ -47,7 +47,7 @@ function getColorPerItem(series?: LogsFetchDataResponse['series']) { export function LogsSection({ bucketSize }: Props) { const history = useHistory(); const chartTheme = useChartTheme(); - const { forceUpdate, hasData } = useHasData(); + const { forceUpdate, hasDataMap } = useHasData(); const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useTimeRange(); const { data, status } = useFetcher( @@ -65,7 +65,7 @@ export function LogsSection({ bucketSize }: Props) { [bucketSize, relativeStart, relativeEnd, forceUpdate] ); - if (!hasData.infra_logs?.hasData) { + if (!hasDataMap.infra_logs?.hasData) { return null; } diff --git a/x-pack/plugins/observability/public/components/app/section/metrics/index.tsx b/x-pack/plugins/observability/public/components/app/section/metrics/index.tsx index 5a642084733c7..2f5bb9bac9348 100644 --- a/x-pack/plugins/observability/public/components/app/section/metrics/index.tsx +++ b/x-pack/plugins/observability/public/components/app/section/metrics/index.tsx @@ -50,7 +50,7 @@ const bytesPerSecondFormatter = (value: NumberOrNull) => value === null ? '' : numeral(value).format('0b') + '/s'; export function MetricsSection({ bucketSize }: Props) { - const { forceUpdate, hasData } = useHasData(); + const { forceUpdate, hasDataMap } = useHasData(); const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useTimeRange(); const [sortDirection, setSortDirection] = useState('asc'); const [sortField, setSortField] = useState('uptime'); @@ -88,7 +88,7 @@ export function MetricsSection({ bucketSize }: Props) { [data, setSortField, setSortDirection] ); - if (!hasData.infra_metrics?.hasData) { + if (!hasDataMap.infra_metrics?.hasData) { return null; } diff --git a/x-pack/plugins/observability/public/components/app/section/uptime/index.tsx b/x-pack/plugins/observability/public/components/app/section/uptime/index.tsx index 1dbcdeaee800a..28cbd12663c1b 100644 --- a/x-pack/plugins/observability/public/components/app/section/uptime/index.tsx +++ b/x-pack/plugins/observability/public/components/app/section/uptime/index.tsx @@ -40,7 +40,7 @@ export function UptimeSection({ bucketSize }: Props) { const theme = useContext(ThemeContext); const chartTheme = useChartTheme(); const history = useHistory(); - const { forceUpdate, hasData } = useHasData(); + const { forceUpdate, hasDataMap } = useHasData(); const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useTimeRange(); const { data, status } = useFetcher( @@ -58,7 +58,7 @@ export function UptimeSection({ bucketSize }: Props) { [bucketSize, relativeStart, relativeEnd, forceUpdate] ); - if (!hasData.synthetics?.hasData) { + if (!hasDataMap.synthetics?.hasData) { return null; } diff --git a/x-pack/plugins/observability/public/components/app/section/ux/index.test.tsx b/x-pack/plugins/observability/public/components/app/section/ux/index.test.tsx index fab461476e713..fcee238942c72 100644 --- a/x-pack/plugins/observability/public/components/app/section/ux/index.test.tsx +++ b/x-pack/plugins/observability/public/components/app/section/ux/index.test.tsx @@ -28,7 +28,7 @@ jest.mock('react-router-dom', () => ({ describe('UXSection', () => { beforeAll(() => { jest.spyOn(hasDataHook, 'useHasData').mockReturnValue({ - hasData: { + hasDataMap: { ux: { status: fetcherHook.FETCH_STATUS.SUCCESS, hasData: { hasData: true, serviceName: 'elastic-co-frontend' }, diff --git a/x-pack/plugins/observability/public/components/app/section/ux/index.tsx b/x-pack/plugins/observability/public/components/app/section/ux/index.tsx index 0ac337e5ba0b1..59d4b5f0f80c6 100644 --- a/x-pack/plugins/observability/public/components/app/section/ux/index.tsx +++ b/x-pack/plugins/observability/public/components/app/section/ux/index.tsx @@ -20,9 +20,9 @@ interface Props { } export function UXSection({ bucketSize }: Props) { - const { forceUpdate, hasData } = useHasData(); + const { forceUpdate, hasDataMap } = useHasData(); const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useTimeRange(); - const uxHasDataResponse = (hasData.ux?.hasData as UXHasDataResponse) || {}; + const uxHasDataResponse = (hasDataMap.ux?.hasData as UXHasDataResponse) || {}; const serviceName = uxHasDataResponse.serviceName as string; const { data, status } = useFetcher( diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx index 52a5624c000d3..4259bb778e511 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_app_index_pattern.tsx @@ -12,7 +12,6 @@ import { useKibana } from '../../../../../../../../src/plugins/kibana_react/publ import { ObservabilityPublicPluginsStart } from '../../../../plugin'; import { ObservabilityIndexPatterns } from '../utils/observability_index_patterns'; import { getDataHandler } from '../../../../data_handler'; -import { HasDataResponse } from '../../../../typings/fetch_overview_data'; export interface IIndexPatternContext { loading: boolean; @@ -48,11 +47,6 @@ export function IndexPatternContextProvider({ children }: ProviderProps) { services: { data }, } = useKibana(); - const checkIfAppHasData = async (dataType: AppDataType) => { - const handler = getDataHandler(dataType === 'mobile' ? 'apm' : dataType); - return handler?.hasData(); - }; - const loadIndexPattern: IIndexPatternContext['loadIndexPattern'] = useCallback( async ({ dataType }) => { setSelectedApp(dataType); @@ -60,15 +54,27 @@ export function IndexPatternContextProvider({ children }: ProviderProps) { if (hasAppData[dataType] === null) { setLoading(true); try { - const hasDataResponse = (await checkIfAppHasData(dataType)) as HasDataResponse; - - const hasDataT = hasDataResponse.hasData; - + let hasDataT = false; + let indices: string | undefined = ''; + switch (dataType) { + case 'ux': + case 'synthetics': + const resultUx = await getDataHandler(dataType)?.hasData(); + hasDataT = Boolean(resultUx?.hasData); + indices = resultUx?.indices; + break; + case 'apm': + case 'mobile': + const resultApm = await getDataHandler('apm')?.hasData(); + hasDataT = Boolean(resultApm?.hasData); + indices = resultApm?.indices['apm_oss.transactionIndices']; + break; + } setHasAppData((prevState) => ({ ...prevState, [dataType]: hasDataT })); - if (hasDataT || hasAppData?.[dataType]) { + if (hasDataT && indices) { const obsvIndexP = new ObservabilityIndexPatterns(data); - const indPattern = await obsvIndexP.getIndexPattern(dataType, hasDataResponse.indices); + const indPattern = await obsvIndexP.getIndexPattern(dataType, indices); setIndexPatterns((prevState) => ({ ...prevState, [dataType]: indPattern })); } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/utils/observability_index_patterns.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/utils/observability_index_patterns.ts index 4f9b428cab72b..634408dd614da 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/utils/observability_index_patterns.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/utils/observability_index_patterns.ts @@ -127,6 +127,7 @@ export class ObservabilityIndexPatterns { if (!this.data) { throw new Error('data is not defined'); } + try { const indexPatternId = getAppIndexPatternId(app, indices); const indexPatternTitle = getAppIndicesWithPattern(app, indices); diff --git a/x-pack/plugins/observability/public/context/has_data_context.tsx b/x-pack/plugins/observability/public/context/has_data_context.tsx index 25c8b50b39b5c..5bff4d55fbe65 100644 --- a/x-pack/plugins/observability/public/context/has_data_context.tsx +++ b/x-pack/plugins/observability/public/context/has_data_context.tsx @@ -14,21 +14,22 @@ import { FETCH_STATUS } from '../hooks/use_fetcher'; import { usePluginContext } from '../hooks/use_plugin_context'; import { useTimeRange } from '../hooks/use_time_range'; import { getObservabilityAlerts } from '../services/get_observability_alerts'; -import { - HasDataResponse, - ObservabilityFetchDataPlugins, - UXHasDataResponse, -} from '../typings/fetch_overview_data'; +import { ObservabilityFetchDataPlugins } from '../typings/fetch_overview_data'; +import { ApmIndicesConfig } from '../../common/typings'; type DataContextApps = ObservabilityFetchDataPlugins | 'alert'; export type HasDataMap = Record< DataContextApps, - { status: FETCH_STATUS; hasData?: boolean | HasDataResponse | UXHasDataResponse | Alert[] } + { + status: FETCH_STATUS; + hasData?: boolean | Alert[]; + indices?: string | ApmIndicesConfig; + } >; export interface HasDataContextValue { - hasData: Partial; + hasDataMap: Partial; hasAnyData: boolean; isAllRequestsComplete: boolean; onRefreshTimeRange: () => void; @@ -44,7 +45,7 @@ export function HasDataContextProvider({ children }: { children: React.ReactNode const [forceUpdate, setForceUpdate] = useState(''); const { absoluteStart, absoluteEnd } = useTimeRange(); - const [hasData, setHasData] = useState({}); + const [hasDataMap, setHasDataMap] = useState({}); const isExploratoryView = useRouteMatch('/exploratory-view'); @@ -53,23 +54,39 @@ export function HasDataContextProvider({ children }: { children: React.ReactNode if (!isExploratoryView) apps.forEach(async (app) => { try { - if (app !== 'alert') { - const params = - app === 'ux' - ? { absoluteTime: { start: absoluteStart, end: absoluteEnd } } - : undefined; - - const result = await getDataHandler(app)?.hasData(params); - setHasData((prevState) => ({ + const updateState = (hasData?: boolean) => { + setHasDataMap((prevState) => ({ ...prevState, [app]: { - hasData: result, + hasData, status: FETCH_STATUS.SUCCESS, }, })); + }; + switch (app) { + case 'ux': + const params = { absoluteTime: { start: absoluteStart, end: absoluteEnd } }; + const resultUx = await getDataHandler(app)?.hasData(params); + updateState(resultUx?.hasData); + break; + case 'synthetics': + const resultSy = await getDataHandler(app)?.hasData(); + updateState(resultSy?.hasData); + + break; + case 'apm': + const resultApm = await getDataHandler(app)?.hasData(); + updateState(resultApm?.hasData); + + break; + case 'infra_logs': + case 'infra_metrics': + const resultInfra = await getDataHandler(app)?.hasData(); + updateState(resultInfra); + break; } } catch (e) { - setHasData((prevState) => ({ + setHasDataMap((prevState) => ({ ...prevState, [app]: { hasData: undefined, @@ -87,7 +104,7 @@ export function HasDataContextProvider({ children }: { children: React.ReactNode async function fetchAlerts() { try { const alerts = await getObservabilityAlerts({ core }); - setHasData((prevState) => ({ + setHasDataMap((prevState) => ({ ...prevState, alert: { hasData: alerts, @@ -95,7 +112,7 @@ export function HasDataContextProvider({ children }: { children: React.ReactNode }, })); } catch (e) { - setHasData((prevState) => ({ + setHasDataMap((prevState) => ({ ...prevState, alert: { hasData: undefined, @@ -109,19 +126,18 @@ export function HasDataContextProvider({ children }: { children: React.ReactNode }, [forceUpdate, core]); const isAllRequestsComplete = apps.every((app) => { - const appStatus = hasData[app]?.status; + const appStatus = hasDataMap[app]?.status; return appStatus !== undefined && appStatus !== FETCH_STATUS.LOADING; }); - const hasAnyData = (Object.keys(hasData) as ObservabilityFetchDataPlugins[]).some( - (app) => - hasData[app]?.hasData === true || (hasData[app]?.hasData as HasDataResponse)?.hasData === true + const hasAnyData = (Object.keys(hasDataMap) as ObservabilityFetchDataPlugins[]).some( + (app) => hasDataMap[app]?.hasData === true ); return ( { }); it('renders loading component while requests are not returned', () => { - jest - .spyOn(hasData, 'useHasData') - .mockImplementation( - () => - ({ hasData: {}, hasAnyData: false, isAllRequestsComplete: false } as HasDataContextValue) - ); + jest.spyOn(hasData, 'useHasData').mockImplementation( + () => + ({ + hasDataMap: {}, + hasAnyData: false, + isAllRequestsComplete: false, + } as HasDataContextValue) + ); const { getByText } = render(); expect(getByText('Loading Observability')).toBeInTheDocument(); }); it('renders landing page', () => { - jest - .spyOn(hasData, 'useHasData') - .mockImplementation( - () => - ({ hasData: {}, hasAnyData: false, isAllRequestsComplete: true } as HasDataContextValue) - ); + jest.spyOn(hasData, 'useHasData').mockImplementation( + () => + ({ + hasDataMap: {}, + hasAnyData: false, + isAllRequestsComplete: true, + } as HasDataContextValue) + ); render(); expect(mockHistoryPush).toHaveBeenCalledWith({ pathname: '/landing' }); }); it('renders overview page', () => { - jest - .spyOn(hasData, 'useHasData') - .mockImplementation( - () => - ({ hasData: {}, hasAnyData: true, isAllRequestsComplete: false } as HasDataContextValue) - ); + jest.spyOn(hasData, 'useHasData').mockImplementation( + () => + ({ + hasDataMap: {}, + hasAnyData: true, + isAllRequestsComplete: false, + } as HasDataContextValue) + ); render(); expect(mockHistoryPush).toHaveBeenCalledWith({ pathname: '/overview' }); }); diff --git a/x-pack/plugins/observability/public/pages/overview/index.tsx b/x-pack/plugins/observability/public/pages/overview/index.tsx index 4cb6792d50195..bc92e6695123b 100644 --- a/x-pack/plugins/observability/public/pages/overview/index.tsx +++ b/x-pack/plugins/observability/public/pages/overview/index.tsx @@ -48,13 +48,13 @@ export function OverviewPage({ routeParams }: Props) { const { data: newsFeed } = useFetcher(() => getNewsFeed({ core }), [core]); - const { hasData, hasAnyData } = useHasData(); + const { hasDataMap, hasAnyData } = useHasData(); if (hasAnyData === undefined) { return ; } - const alerts = (hasData.alert?.hasData as Alert[]) || []; + const alerts = (hasDataMap.alert?.hasData as Alert[]) || []; const { refreshInterval = 10000, refreshPaused = true } = routeParams.query; diff --git a/x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts b/x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts index 337a294cfb3be..7c4aacd1c51b7 100644 --- a/x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts +++ b/x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts @@ -7,6 +7,8 @@ import { ObservabilityApp } from '../../../typings/common'; import { UXMetrics } from '../../components/shared/core_web_vitals'; +import { ApmIndicesConfig } from '../../../common/typings'; + export interface Stat { type: 'number' | 'percent' | 'bytesPerSecond'; value: number; @@ -34,11 +36,20 @@ export interface HasDataParams { export interface HasDataResponse { hasData: boolean; - indices: string; } export interface UXHasDataResponse extends HasDataResponse { serviceName: string | number | undefined; + indices: string; +} + +export interface SyntheticsHasDataResponse extends HasDataResponse { + indices: string; +} + +export interface APMHasDataResponse { + hasData: boolean; + indices: ApmIndicesConfig; } export type FetchData = ( @@ -134,9 +145,9 @@ export interface ObservabilityFetchDataResponse { } export interface ObservabilityHasDataResponse { - apm: HasDataResponse; + apm: APMHasDataResponse; infra_metrics: boolean; infra_logs: boolean; - synthetics: HasDataResponse; + synthetics: SyntheticsHasDataResponse; ux: UXHasDataResponse; } From 716184f794dc63c1d5cc2f82a4967575ac055d37 Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Tue, 15 Jun 2021 10:54:40 +0200 Subject: [PATCH 13/26] added throughput and distribution configs for mobile data --- .../configurations/default_configs.ts | 6 +- .../configurations/lens_attributes.ts | 21 ++--- .../mobile/distribution_config.ts | 89 +++++++++++++++++++ .../mobile/kpi_over_time_config.ts | 14 ++- .../series_builder/series_builder.tsx | 6 +- .../shared/exploratory_view/types.ts | 1 + 6 files changed, 121 insertions(+), 16 deletions(-) create mode 100644 x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts index 30ce1f47dc3cc..639aba06998fc 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts @@ -13,6 +13,7 @@ import { getKPITrendsLensConfig } from './rum/kpi_over_time_config'; import { IndexPattern } from '../../../../../../../../src/plugins/data/common'; import { getCoreWebVitalsConfig } from './rum/core_web_vitals_config'; import { getMobileKPIConfig } from './mobile/kpi_over_time_config'; +import { getMobileKPIDistributionConfig } from './mobile/distribution_config'; interface Props { reportType: keyof typeof ReportViewTypes; @@ -20,6 +21,7 @@ interface Props { dataType: AppDataType; } + export const getDefaultConfigs = ({ reportType, dataType, indexPattern }: Props) => { switch (dataType) { case 'ux': @@ -36,8 +38,10 @@ export const getDefaultConfigs = ({ reportType, dataType, indexPattern }: Props) } return getSyntheticsKPIConfig({ indexPattern }); case 'mobile': + if (reportType === 'dist') { + return getMobileKPIDistributionConfig({ indexPattern }); + } return getMobileKPIConfig({ indexPattern }); - default: return getKPITrendsLensConfig({ indexPattern }); } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts index bc535e29ab435..ed7d3cb0665a3 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts @@ -55,6 +55,7 @@ export const parseCustomFieldName = ( let fieldName = sourceField; let columnType; let columnFilters; + let timeScale; let columnLabel; const rdf = reportViewConfig.reportDefinitions ?? []; @@ -70,17 +71,19 @@ export const parseCustomFieldName = ( ); columnType = currField?.columnType; columnFilters = currField?.columnFilters; + timeScale = currField?.timeScale; columnLabel = currField?.label; } } else if (customField.options?.[0].field || customField.options?.[0].id) { fieldName = customField.options?.[0].field || customField.options?.[0].id; columnType = customField.options?.[0].columnType; columnFilters = customField.options?.[0].columnFilters; + timeScale = customField.options?.[0].timeScale; columnLabel = customField.options?.[0].label; } } - return { fieldName, columnType, columnFilters, columnLabel }; + return { fieldName, columnType, columnFilters, timeScale, columnLabel }; }; export class LensAttributes { @@ -263,15 +266,14 @@ export class LensAttributes { label?: string, colIndex?: number ) { - const { fieldMeta, columnType, fieldName, columnFilters, columnLabel } = this.getFieldMeta( - sourceField - ); + const { fieldMeta, columnType, fieldName, columnFilters, timeScale, columnLabel } = this.getFieldMeta(sourceField); const { type: fieldType } = fieldMeta ?? {}; if (fieldName === 'Records' || columnType === FILTER_RECORDS) { return this.getRecordsColumn( columnLabel || label, - colIndex !== undefined ? columnFilters?.[colIndex] : undefined + colIndex !== undefined ? columnFilters?.[colIndex] : undefined, + timeScale ); } @@ -291,13 +293,11 @@ export class LensAttributes { } getFieldMeta(sourceField: string) { - const { fieldName, columnType, columnFilters, columnLabel } = this.getCustomFieldName( - sourceField - ); + const { fieldName, columnType, columnFilters, timeScale, columnLabel } = this.getCustomFieldName(sourceField); const fieldMeta = this.indexPattern.getFieldByName(fieldName); - return { fieldMeta, fieldName, columnType, columnFilters, columnLabel }; + return { fieldMeta, fieldName, columnType, columnFilters, timeScale, columnLabel }; } getMainYAxis() { @@ -330,7 +330,7 @@ export class LensAttributes { return lensColumns; } - getRecordsColumn(label?: string, columnFilter?: ColumnFilter): CountIndexPatternColumn { + getRecordsColumn(label?: string, columnFilter?: ColumnFilter, timeScale?: string): CountIndexPatternColumn { return { dataType: 'number', isBucketed: false, @@ -339,6 +339,7 @@ export class LensAttributes { scale: 'ratio', sourceField: 'Records', filter: columnFilter, + timeScale: timeScale, } as CountIndexPatternColumn; } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts new file mode 100644 index 0000000000000..7261c5a6d2d9b --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts @@ -0,0 +1,89 @@ +/* + * 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 { ConfigProps, DataSeries } from '../../types'; +import { FieldLabels, OPERATION_COLUMN, RECORDS_FIELD } from '../constants'; +import { buildPhraseFilter } from '../utils'; +import { + METRIC_SYSTEM_CPU_USAGE, + METRIC_SYSTEM_MEMORY_USAGE, + SERVICE_NAME, + TRANSACTION_DURATION, +} from '../constants/elasticsearch_fieldnames'; + +export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): DataSeries { + return { + reportType: 'data-distribution', + defaultSeriesType: 'bar', + seriesTypes: ['line', 'bar'], + xAxisColumn: { + sourceField: 'performance.metric', + }, + yAxisColumns: [ + { + sourceField: RECORDS_FIELD, + label: 'Transactions', + }, + ], + hasOperationType: false, + defaultFilters: [ + 'labels.net_connection_carrier_name', + 'labels.device_model', + 'labels.net_connection_type', + 'host.os.platform', + 'host.os.full', + 'service.version', + ], + breakdowns: [ + 'labels.net_connection_carrier_name', + 'labels.device_model', + 'labels.net_connection_type', + 'host.os.platform', + 'host.os.full', + 'service.version', + 'labels.net_connection_carrier_isoCountryCode', + ], + filters: [ + ...buildPhraseFilter('agent.name', 'iOS/swift', indexPattern), + ...buildPhraseFilter('processor.event', 'transaction', indexPattern) + ], + labels: { + ...FieldLabels, + [SERVICE_NAME]: 'Mobile app', + }, + reportDefinitions: [ + { + field: SERVICE_NAME, + required: true, + }, + { + field: 'performance.metric', + custom: true, + options: [ + { + label: 'Response latency', + field: TRANSACTION_DURATION, + id: TRANSACTION_DURATION, + columnType: OPERATION_COLUMN, + }, + { + label: 'Memory Usage', + field: METRIC_SYSTEM_MEMORY_USAGE, + id: METRIC_SYSTEM_MEMORY_USAGE, + columnType: OPERATION_COLUMN, + }, + { + label: 'CPU Usage', + field: METRIC_SYSTEM_CPU_USAGE, + id: METRIC_SYSTEM_CPU_USAGE, + columnType: OPERATION_COLUMN, + }, + ], + }, + ], + }; +} diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts index 1c78e2a515c69..4d8b957c47033 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts @@ -6,7 +6,7 @@ */ import { ConfigProps, DataSeries } from '../../types'; -import { FieldLabels, OPERATION_COLUMN } from '../constants'; +import { FieldLabels, OPERATION_COLUMN, RECORDS_FIELD } from '../constants'; import { buildPhrasesFilter } from '../utils'; import { METRIC_SYSTEM_CPU_USAGE, @@ -84,6 +84,18 @@ export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { id: METRIC_SYSTEM_CPU_USAGE, columnType: OPERATION_COLUMN, }, + { + field: RECORDS_FIELD, + id: RECORDS_FIELD, + label: "Transactions per minute", + columnFilters: [ + { + language: 'kuery', + query: `processor.event: transaction`, + } + ], + timeScale: 'm', + }, ], }, ], diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx index 6a4d876503a8c..648809908e2e3 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx @@ -30,10 +30,8 @@ export const ReportTypes: Record; } From 48ece1f04f8283dbeaaa22080213aa32e9c33b73 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 15 Jun 2021 17:42:55 +0200 Subject: [PATCH 14/26] update --- .../configurations/lens_attributes.ts | 31 ++++++++++++++----- .../mobile/distribution_config.ts | 7 ++--- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts index ed7d3cb0665a3..01dcdd18ba0c7 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts @@ -170,10 +170,10 @@ export class LensAttributes { this.visualization.layers[0].splitAccessor = undefined; } - getNumberRangeColumn(sourceField: string): RangeIndexPatternColumn { + getNumberRangeColumn(sourceField: string, label?: string): RangeIndexPatternColumn { return { sourceField, - label: this.reportViewConfig.labels[sourceField], + label: this.reportViewConfig.labels[sourceField] ?? label, dataType: 'number', operationType: 'range', isBucketed: true, @@ -200,7 +200,7 @@ export class LensAttributes { return this.getPercentileNumberColumn(sourceField, operationType); } } - return this.getNumberRangeColumn(sourceField); + return this.getNumberRangeColumn(sourceField, label); } getNumberOperationColumn( @@ -266,7 +266,14 @@ export class LensAttributes { label?: string, colIndex?: number ) { - const { fieldMeta, columnType, fieldName, columnFilters, timeScale, columnLabel } = this.getFieldMeta(sourceField); + const { + fieldMeta, + columnType, + fieldName, + columnFilters, + timeScale, + columnLabel, + } = this.getFieldMeta(sourceField); const { type: fieldType } = fieldMeta ?? {}; if (fieldName === 'Records' || columnType === FILTER_RECORDS) { @@ -293,7 +300,13 @@ export class LensAttributes { } getFieldMeta(sourceField: string) { - const { fieldName, columnType, columnFilters, timeScale, columnLabel } = this.getCustomFieldName(sourceField); + const { + fieldName, + columnType, + columnFilters, + timeScale, + columnLabel, + } = this.getCustomFieldName(sourceField); const fieldMeta = this.indexPattern.getFieldByName(fieldName); @@ -330,7 +343,11 @@ export class LensAttributes { return lensColumns; } - getRecordsColumn(label?: string, columnFilter?: ColumnFilter, timeScale?: string): CountIndexPatternColumn { + getRecordsColumn( + label?: string, + columnFilter?: ColumnFilter, + timeScale?: string + ): CountIndexPatternColumn { return { dataType: 'number', isBucketed: false, @@ -339,7 +356,7 @@ export class LensAttributes { scale: 'ratio', sourceField: 'Records', filter: columnFilter, - timeScale: timeScale, + timeScale, } as CountIndexPatternColumn; } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts index 7261c5a6d2d9b..db254f707152b 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts @@ -7,7 +7,7 @@ import { ConfigProps, DataSeries } from '../../types'; import { FieldLabels, OPERATION_COLUMN, RECORDS_FIELD } from '../constants'; -import { buildPhraseFilter } from '../utils'; +import { buildPhrasesFilter } from '../utils'; import { METRIC_SYSTEM_CPU_USAGE, METRIC_SYSTEM_MEMORY_USAGE, @@ -48,9 +48,8 @@ export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): D 'labels.net_connection_carrier_isoCountryCode', ], filters: [ - ...buildPhraseFilter('agent.name', 'iOS/swift', indexPattern), - ...buildPhraseFilter('processor.event', 'transaction', indexPattern) - ], + ...buildPhrasesFilter('agent.name', ['iOS/swift', 'open-telemetry/swift'], indexPattern), + ], labels: { ...FieldLabels, [SERVICE_NAME]: 'Mobile app', From 6754f80529ba3b175a4c2b1551549b93982510e5 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 15 Jun 2021 18:52:21 +0200 Subject: [PATCH 15/26] fix types --- .../components/app/empty_sections/index.tsx | 4 +--- .../configurations/constants/constants.ts | 2 -- .../public/context/has_data_context.test.tsx | 13 ++++++++++-- .../observability/public/data_handler.test.ts | 8 +++++++- .../pages/overview/overview.stories.tsx | 20 ++++++++++++------- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/observability/public/components/app/empty_sections/index.tsx b/x-pack/plugins/observability/public/components/app/empty_sections/index.tsx index 3c24e1f9547d0..47417a2bbb545 100644 --- a/x-pack/plugins/observability/public/components/app/empty_sections/index.tsx +++ b/x-pack/plugins/observability/public/components/app/empty_sections/index.tsx @@ -13,7 +13,6 @@ import { FETCH_STATUS } from '../../../hooks/use_fetcher'; import { useHasData } from '../../../hooks/use_has_data'; import { usePluginContext } from '../../../hooks/use_plugin_context'; import { getEmptySections } from '../../../pages/overview/empty_section'; -import { UXHasDataResponse } from '../../../typings'; import { EmptySection } from './empty_section'; export function EmptySections() { @@ -31,8 +30,7 @@ export function EmptySections() { } else { const app = hasDataMap[id]; if (app) { - const _hasData = id === 'ux' ? (app.hasData as UXHasDataResponse)?.hasData : app.hasData; - return app.status === FETCH_STATUS.FAILURE || !_hasData; + return app.status === FETCH_STATUS.FAILURE || !app.hasData; } } return false; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts index fc6dc89aa2656..307be440d2753 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts @@ -23,8 +23,6 @@ import { LCP_LABEL, LOCATION_LABEL, METRIC_LABEL, - MOBILE_RESPONSE_LABEL, - MONITOR_DURATION_LABEL, MONITOR_ID_LABEL, MONITOR_NAME_LABEL, MONITOR_STATUS_LABEL, diff --git a/x-pack/plugins/observability/public/context/has_data_context.test.tsx b/x-pack/plugins/observability/public/context/has_data_context.test.tsx index d8b91d7b4eeb9..88edb4a459b97 100644 --- a/x-pack/plugins/observability/public/context/has_data_context.test.tsx +++ b/x-pack/plugins/observability/public/context/has_data_context.test.tsx @@ -19,10 +19,16 @@ import * as pluginContext from '../hooks/use_plugin_context'; import { PluginContextValue } from './plugin_context'; import { Router } from 'react-router-dom'; import { createMemoryHistory } from 'history'; +import { ApmIndicesConfig } from '../../common/typings'; const relativeStart = '2020-10-08T06:00:00.000Z'; const relativeEnd = '2020-10-08T07:00:00.000Z'; +const sampleAPMIndices = { + // eslint-disable-next-line @typescript-eslint/naming-convention + 'apm_oss.transactionIndices': 'apm-*', +} as ApmIndicesConfig; + function wrapper({ children }: { children: React.ReactElement }) { const history = createMemoryHistory(); return ( @@ -280,7 +286,7 @@ describe('HasDataContextProvider', () => { describe('when apm returns true', () => { beforeAll(() => { registerApps([ - { appName: 'apm', hasData: async () => ({ hasData: true, indices: 'apm-*' }) }, + { appName: 'apm', hasData: async () => ({ hasData: true, indices: sampleAPMIndices }) }, ]); }); @@ -320,7 +326,10 @@ describe('HasDataContextProvider', () => { describe('when apm returns false', () => { beforeAll(() => { registerApps([ - { appName: 'apm', hasData: async () => ({ indices: 'apm-*', hasData: false }) }, + { + appName: 'apm', + hasData: async () => ({ indices: sampleAPMIndices, hasData: false }), + }, ]); }); diff --git a/x-pack/plugins/observability/public/data_handler.test.ts b/x-pack/plugins/observability/public/data_handler.test.ts index 87d4c72d99aa7..b7ad282c2cf93 100644 --- a/x-pack/plugins/observability/public/data_handler.test.ts +++ b/x-pack/plugins/observability/public/data_handler.test.ts @@ -7,6 +7,12 @@ import { registerDataHandler, getDataHandler } from './data_handler'; import moment from 'moment'; +import { ApmIndicesConfig } from '../common/typings'; + +const sampleAPMIndices = { + // eslint-disable-next-line @typescript-eslint/naming-convention + 'apm_oss.transactionIndices': 'apm-*', +} as ApmIndicesConfig; const params = { absoluteTime: { @@ -58,7 +64,7 @@ describe('registerDataHandler', () => { }, }; }, - hasData: async () => ({ hasData: true, indices: 'apm-*' }), + hasData: async () => ({ hasData: true, indices: sampleAPMIndices }), }); it('registered data handler', () => { diff --git a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx index f1f1d7ea41ee5..dd424cf221d15 100644 --- a/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx +++ b/x-pack/plugins/observability/public/pages/overview/overview.stories.tsx @@ -25,6 +25,7 @@ import { newsFeedFetchData } from './mock/news_feed.mock'; import { emptyResponse as emptyUptimeResponse, fetchUptimeData } from './mock/uptime.mock'; import { createObservabilityRuleTypeRegistryMock } from '../../rules/observability_rule_type_registry_mock'; import { KibanaPageTemplate } from '../../../../../../src/plugins/kibana_react/public'; +import { ApmIndicesConfig } from '../../../common/typings'; function unregisterAll() { unregisterDataHandler({ appName: 'apm' }); @@ -33,6 +34,11 @@ function unregisterAll() { unregisterDataHandler({ appName: 'synthetics' }); } +const sampleAPMIndices = { + // eslint-disable-next-line @typescript-eslint/naming-convention + 'apm_oss.transactionIndices': 'apm-*', +} as ApmIndicesConfig; + const withCore = makeDecorator({ name: 'withCore', parameterName: 'core', @@ -177,7 +183,7 @@ storiesOf('app/Overview', module) registerDataHandler({ appName: 'apm', fetchData: fetchApmData, - hasData: async () => ({ hasData: false, indices: 'apm-*' }), + hasData: async () => ({ hasData: false, indices: sampleAPMIndices }), }); registerDataHandler({ appName: 'infra_logs', @@ -272,7 +278,7 @@ storiesOf('app/Overview', module) registerDataHandler({ appName: 'apm', fetchData: fetchApmData, - hasData: async () => ({ hasData: true, indices: 'apm-*' }), + hasData: async () => ({ hasData: true, indices: sampleAPMIndices }), }); return ( @@ -289,7 +295,7 @@ storiesOf('app/Overview', module) registerDataHandler({ appName: 'apm', fetchData: fetchApmData, - hasData: async () => ({ hasData: true, indices: 'apm-*' }), + hasData: async () => ({ hasData: true, indices: sampleAPMIndices }), }); registerDataHandler({ appName: 'infra_logs', @@ -321,7 +327,7 @@ storiesOf('app/Overview', module) registerDataHandler({ appName: 'apm', fetchData: fetchApmData, - hasData: async () => ({ hasData: true, indices: 'apm-*' }), + hasData: async () => ({ hasData: true, indices: sampleAPMIndices }), }); registerDataHandler({ appName: 'infra_logs', @@ -355,7 +361,7 @@ storiesOf('app/Overview', module) registerDataHandler({ appName: 'apm', fetchData: fetchApmData, - hasData: async () => ({ hasData: true, indices: 'apm-*' }), + hasData: async () => ({ hasData: true, indices: sampleAPMIndices }), }); registerDataHandler({ appName: 'infra_logs', @@ -386,7 +392,7 @@ storiesOf('app/Overview', module) registerDataHandler({ appName: 'apm', fetchData: async () => emptyAPMResponse, - hasData: async () => ({ hasData: true, indices: 'apm-*' }), + hasData: async () => ({ hasData: true, indices: sampleAPMIndices }), }); registerDataHandler({ appName: 'infra_logs', @@ -420,7 +426,7 @@ storiesOf('app/Overview', module) fetchData: async () => { throw new Error('Error fetching APM data'); }, - hasData: async () => ({ hasData: true, indices: 'apm-*' }), + hasData: async () => ({ hasData: true, indices: sampleAPMIndices }), }); registerDataHandler({ appName: 'infra_logs', From fe641a0ec5cec791bf9f5f9c3a6f2b621c9f1f3b Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 16 Jun 2021 10:11:15 +0200 Subject: [PATCH 16/26] added environment --- .../configurations/default_configs.ts | 1 - .../configurations/mobile/distribution_config.ts | 5 +++++ .../configurations/mobile/kpi_over_time_config.ts | 15 ++++++++++----- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts index 639aba06998fc..d1660c9256fa3 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts @@ -21,7 +21,6 @@ interface Props { dataType: AppDataType; } - export const getDefaultConfigs = ({ reportType, dataType, indexPattern }: Props) => { switch (dataType) { case 'ux': diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts index db254f707152b..82122e0745188 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts @@ -11,6 +11,7 @@ import { buildPhrasesFilter } from '../utils'; import { METRIC_SYSTEM_CPU_USAGE, METRIC_SYSTEM_MEMORY_USAGE, + SERVICE_ENVIRONMENT, SERVICE_NAME, TRANSACTION_DURATION, } from '../constants/elasticsearch_fieldnames'; @@ -59,6 +60,10 @@ export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): D field: SERVICE_NAME, required: true, }, + { + field: SERVICE_ENVIRONMENT, + required: true, + }, { field: 'performance.metric', custom: true, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts index 4d8b957c47033..5155d7f247ae3 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts @@ -11,6 +11,7 @@ import { buildPhrasesFilter } from '../utils'; import { METRIC_SYSTEM_CPU_USAGE, METRIC_SYSTEM_MEMORY_USAGE, + SERVICE_ENVIRONMENT, SERVICE_NAME, TRANSACTION_DURATION, } from '../constants/elasticsearch_fieldnames'; @@ -62,6 +63,10 @@ export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { field: SERVICE_NAME, required: true, }, + { + field: SERVICE_ENVIRONMENT, + required: true, + }, { field: 'business.kpi', custom: true, @@ -84,15 +89,15 @@ export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { id: METRIC_SYSTEM_CPU_USAGE, columnType: OPERATION_COLUMN, }, - { - field: RECORDS_FIELD, - id: RECORDS_FIELD, - label: "Transactions per minute", + { + field: RECORDS_FIELD, + id: RECORDS_FIELD, + label: 'Transactions per minute', columnFilters: [ { language: 'kuery', query: `processor.event: transaction`, - } + }, ], timeScale: 'm', }, From 423fba97db861f47b51fd0bc0932c9a89529ceb3 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 16 Jun 2021 11:50:14 +0200 Subject: [PATCH 17/26] fix test --- .../components/app/section/ux/index.tsx | 5 +- .../public/context/has_data_context.test.tsx | 129 ++++++++++-------- .../public/context/has_data_context.tsx | 25 +++- .../typings/fetch_overview_data/index.ts | 4 +- 4 files changed, 94 insertions(+), 69 deletions(-) diff --git a/x-pack/plugins/observability/public/components/app/section/ux/index.tsx b/x-pack/plugins/observability/public/components/app/section/ux/index.tsx index 59d4b5f0f80c6..5aa89eb2d3074 100644 --- a/x-pack/plugins/observability/public/components/app/section/ux/index.tsx +++ b/x-pack/plugins/observability/public/components/app/section/ux/index.tsx @@ -12,7 +12,6 @@ import { getDataHandler } from '../../../../data_handler'; import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; import { useHasData } from '../../../../hooks/use_has_data'; import { useTimeRange } from '../../../../hooks/use_time_range'; -import { UXHasDataResponse } from '../../../../typings'; import CoreVitals from '../../../shared/core_web_vitals'; interface Props { @@ -22,8 +21,8 @@ interface Props { export function UXSection({ bucketSize }: Props) { const { forceUpdate, hasDataMap } = useHasData(); const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useTimeRange(); - const uxHasDataResponse = (hasDataMap.ux?.hasData as UXHasDataResponse) || {}; - const serviceName = uxHasDataResponse.serviceName as string; + const uxHasDataResponse = hasDataMap.ux; + const serviceName = uxHasDataResponse?.serviceName as string; const { data, status } = useFetcher( () => { diff --git a/x-pack/plugins/observability/public/context/has_data_context.test.tsx b/x-pack/plugins/observability/public/context/has_data_context.test.tsx index 88edb4a459b97..f2f550e35ac6b 100644 --- a/x-pack/plugins/observability/public/context/has_data_context.test.tsx +++ b/x-pack/plugins/observability/public/context/has_data_context.test.tsx @@ -5,7 +5,6 @@ * 2.0. */ -// import { act, getByText } from '@testing-library/react'; import { renderHook } from '@testing-library/react-hooks'; import { CoreStart } from 'kibana/public'; import React from 'react'; @@ -20,6 +19,7 @@ import { PluginContextValue } from './plugin_context'; import { Router } from 'react-router-dom'; import { createMemoryHistory } from 'history'; import { ApmIndicesConfig } from '../../common/typings'; +import { act } from '@testing-library/react'; const relativeStart = '2020-10-08T06:00:00.000Z'; const relativeEnd = '2020-10-08T07:00:00.000Z'; @@ -82,17 +82,18 @@ describe('HasDataContextProvider', () => { it('hasAnyData returns false and all apps return undefined', async () => { const { result, waitForNextUpdate } = renderHook(() => useHasData(), { wrapper }); expect(result.current).toMatchObject({ - hasData: {}, + hasDataMap: {}, hasAnyData: false, isAllRequestsComplete: false, forceUpdate: expect.any(String), onRefreshTimeRange: expect.any(Function), }); - - await waitForNextUpdate(); + await act(async () => { + await waitForNextUpdate(); + }); expect(result.current).toEqual({ - hasData: { + hasDataMap: { apm: { hasData: undefined, status: 'success' }, synthetics: { hasData: undefined, status: 'success' }, infra_logs: { hasData: undefined, status: 'success' }, @@ -111,16 +112,16 @@ describe('HasDataContextProvider', () => { describe('all apps return false', () => { beforeAll(() => { registerApps([ - { appName: 'apm', hasData: async () => false }, + { appName: 'apm', hasData: async () => ({ hasData: false }) }, { appName: 'infra_logs', hasData: async () => false }, { appName: 'infra_metrics', hasData: async () => false }, { appName: 'synthetics', - hasData: async () => ({ hasData: false, indices: 'heartbeat-*, synthetics-*' }), + hasData: async () => ({ hasData: false }), }, { appName: 'ux', - hasData: async () => ({ hasData: false, serviceName: undefined, indices: 'apm-*' }), + hasData: async () => ({ hasData: false }), }, ]); }); @@ -130,29 +131,28 @@ describe('HasDataContextProvider', () => { it('hasAnyData returns false and all apps return false', async () => { const { result, waitForNextUpdate } = renderHook(() => useHasData(), { wrapper }); expect(result.current).toEqual({ - hasData: {}, + hasDataMap: {}, hasAnyData: false, isAllRequestsComplete: false, forceUpdate: expect.any(String), onRefreshTimeRange: expect.any(Function), }); - await waitForNextUpdate(); + await act(async () => { + await waitForNextUpdate(); + }); expect(result.current).toEqual({ - hasData: { + hasDataMap: { apm: { hasData: false, status: 'success' }, synthetics: { - hasData: { - hasData: false, - indices: 'heartbeat-*, synthetics-*', - }, + hasData: false, status: 'success', }, infra_logs: { hasData: false, status: 'success' }, infra_metrics: { hasData: false, status: 'success' }, ux: { - hasData: { hasData: false, serviceName: undefined, indices: 'apm-*' }, + hasData: false, status: 'success', }, alert: { hasData: [], status: 'success' }, @@ -168,7 +168,7 @@ describe('HasDataContextProvider', () => { describe('at least one app returns true', () => { beforeAll(() => { registerApps([ - { appName: 'apm', hasData: async () => true }, + { appName: 'apm', hasData: async () => ({ hasData: true }) }, { appName: 'infra_logs', hasData: async () => false }, { appName: 'infra_metrics', hasData: async () => false }, { @@ -187,29 +187,30 @@ describe('HasDataContextProvider', () => { it('hasAnyData returns true apm returns true and all other apps return false', async () => { const { result, waitForNextUpdate } = renderHook(() => useHasData(), { wrapper }); expect(result.current).toEqual({ - hasData: {}, + hasDataMap: {}, hasAnyData: false, isAllRequestsComplete: false, forceUpdate: expect.any(String), onRefreshTimeRange: expect.any(Function), }); - await waitForNextUpdate(); + await act(async () => { + await waitForNextUpdate(); + }); expect(result.current).toEqual({ - hasData: { + hasDataMap: { apm: { hasData: true, status: 'success' }, synthetics: { - hasData: { - hasData: false, - indices: 'heartbeat-*, synthetics-*', - }, + hasData: false, + indices: 'heartbeat-*, synthetics-*', status: 'success', }, infra_logs: { hasData: false, status: 'success' }, infra_metrics: { hasData: false, status: 'success' }, ux: { - hasData: { hasData: false, serviceName: undefined, indices: 'apm-*' }, + hasData: false, + indices: 'apm-*', status: 'success', }, alert: { hasData: [], status: 'success' }, @@ -225,7 +226,7 @@ describe('HasDataContextProvider', () => { describe('all apps return true', () => { beforeAll(() => { registerApps([ - { appName: 'apm', hasData: async () => true }, + { appName: 'apm', hasData: async () => ({ hasData: true }) }, { appName: 'infra_logs', hasData: async () => true }, { appName: 'infra_metrics', hasData: async () => true }, { @@ -244,32 +245,34 @@ describe('HasDataContextProvider', () => { it('hasAnyData returns true and all apps return true', async () => { const { result, waitForNextUpdate } = renderHook(() => useHasData(), { wrapper }); expect(result.current).toEqual({ - hasData: {}, + hasDataMap: {}, hasAnyData: false, isAllRequestsComplete: false, forceUpdate: expect.any(String), onRefreshTimeRange: expect.any(Function), }); - await waitForNextUpdate(); + await act(async () => { + await waitForNextUpdate(); + }); expect(result.current).toEqual({ - hasData: { + hasDataMap: { apm: { hasData: true, status: 'success', }, synthetics: { - hasData: { - hasData: true, - indices: 'heartbeat-*, synthetics-*', - }, + hasData: true, + indices: 'heartbeat-*, synthetics-*', status: 'success', }, infra_logs: { hasData: true, status: 'success' }, infra_metrics: { hasData: true, status: 'success' }, ux: { - hasData: { hasData: true, serviceName: 'ux', indices: 'apm-*' }, + hasData: true, + serviceName: 'ux', + indices: 'apm-*', status: 'success', }, alert: { hasData: [], status: 'success' }, @@ -297,18 +300,20 @@ describe('HasDataContextProvider', () => { wrapper, }); expect(result.current).toEqual({ - hasData: {}, + hasDataMap: {}, hasAnyData: false, isAllRequestsComplete: false, forceUpdate: expect.any(String), onRefreshTimeRange: expect.any(Function), }); - await waitForNextUpdate(); + await act(async () => { + await waitForNextUpdate(); + }); expect(result.current).toEqual({ - hasData: { - apm: { hasData: { hasData: true, indices: 'apm-*' }, status: 'success' }, + hasDataMap: { + apm: { hasData: true, indices: sampleAPMIndices, status: 'success' }, synthetics: { hasData: undefined, status: 'success' }, infra_logs: { hasData: undefined, status: 'success' }, infra_metrics: { hasData: undefined, status: 'success' }, @@ -340,22 +345,22 @@ describe('HasDataContextProvider', () => { wrapper, }); expect(result.current).toEqual({ - hasData: {}, + hasDataMap: {}, hasAnyData: false, isAllRequestsComplete: false, forceUpdate: expect.any(String), onRefreshTimeRange: expect.any(Function), }); - await waitForNextUpdate(); + await act(async () => { + await waitForNextUpdate(); + }); expect(result.current).toEqual({ - hasData: { + hasDataMap: { apm: { - hasData: { - hasData: false, - indices: 'apm-*', - }, + hasData: false, + indices: sampleAPMIndices, status: 'success', }, synthetics: { hasData: undefined, status: 'success' }, @@ -400,29 +405,31 @@ describe('HasDataContextProvider', () => { it('hasAnyData returns true, apm is undefined and all other apps return true', async () => { const { result, waitForNextUpdate } = renderHook(() => useHasData(), { wrapper }); expect(result.current).toEqual({ - hasData: {}, + hasDataMap: {}, hasAnyData: false, isAllRequestsComplete: false, forceUpdate: expect.any(String), onRefreshTimeRange: expect.any(Function), }); - await waitForNextUpdate(); + await act(async () => { + await waitForNextUpdate(); + }); expect(result.current).toEqual({ - hasData: { + hasDataMap: { apm: { hasData: undefined, status: 'failure' }, synthetics: { - hasData: { - hasData: true, - indices: 'heartbeat-*, synthetics-*', - }, + hasData: true, + indices: 'heartbeat-*, synthetics-*', status: 'success', }, infra_logs: { hasData: true, status: 'success' }, infra_metrics: { hasData: true, status: 'success' }, ux: { - hasData: { hasData: true, serviceName: 'ux', indices: 'apm-*' }, + hasData: true, + serviceName: 'ux', + indices: 'apm-*', status: 'success', }, alert: { hasData: [], status: 'success' }, @@ -476,17 +483,19 @@ describe('HasDataContextProvider', () => { it('hasAnyData returns false and all apps return undefined', async () => { const { result, waitForNextUpdate } = renderHook(() => useHasData(), { wrapper }); expect(result.current).toEqual({ - hasData: {}, + hasDataMap: {}, hasAnyData: false, isAllRequestsComplete: false, forceUpdate: expect.any(String), onRefreshTimeRange: expect.any(Function), }); - await waitForNextUpdate(); + await act(async () => { + await waitForNextUpdate(); + }); expect(result.current).toEqual({ - hasData: { + hasDataMap: { apm: { hasData: undefined, status: 'failure' }, synthetics: { hasData: undefined, status: 'failure' }, infra_logs: { hasData: undefined, status: 'failure' }, @@ -524,17 +533,19 @@ describe('HasDataContextProvider', () => { it('returns all alerts available', async () => { const { result, waitForNextUpdate } = renderHook(() => useHasData(), { wrapper }); expect(result.current).toEqual({ - hasData: {}, + hasDataMap: {}, hasAnyData: false, isAllRequestsComplete: false, forceUpdate: expect.any(String), onRefreshTimeRange: expect.any(Function), }); - await waitForNextUpdate(); + await act(async () => { + await waitForNextUpdate(); + }); expect(result.current).toEqual({ - hasData: { + hasDataMap: { apm: { hasData: undefined, status: 'success' }, synthetics: { hasData: undefined, status: 'success' }, infra_logs: { hasData: undefined, status: 'success' }, diff --git a/x-pack/plugins/observability/public/context/has_data_context.tsx b/x-pack/plugins/observability/public/context/has_data_context.tsx index 5bff4d55fbe65..047a596ea349e 100644 --- a/x-pack/plugins/observability/public/context/has_data_context.tsx +++ b/x-pack/plugins/observability/public/context/has_data_context.tsx @@ -25,6 +25,7 @@ export type HasDataMap = Record< status: FETCH_STATUS; hasData?: boolean | Alert[]; indices?: string | ApmIndicesConfig; + serviceName?: string; } >; @@ -54,11 +55,21 @@ export function HasDataContextProvider({ children }: { children: React.ReactNode if (!isExploratoryView) apps.forEach(async (app) => { try { - const updateState = (hasData?: boolean) => { + const updateState = ({ + hasData, + indices, + serviceName, + }: { + hasData?: boolean; + serviceName?: string; + indices?: string | ApmIndicesConfig; + }) => { setHasDataMap((prevState) => ({ ...prevState, [app]: { hasData, + ...(serviceName ? { serviceName } : {}), + ...(indices ? { indices } : {}), status: FETCH_STATUS.SUCCESS, }, })); @@ -67,22 +78,26 @@ export function HasDataContextProvider({ children }: { children: React.ReactNode case 'ux': const params = { absoluteTime: { start: absoluteStart, end: absoluteEnd } }; const resultUx = await getDataHandler(app)?.hasData(params); - updateState(resultUx?.hasData); + updateState({ + hasData: resultUx?.hasData, + indices: resultUx?.indices, + serviceName: resultUx?.serviceName as string, + }); break; case 'synthetics': const resultSy = await getDataHandler(app)?.hasData(); - updateState(resultSy?.hasData); + updateState({ hasData: resultSy?.hasData, indices: resultSy?.indices }); break; case 'apm': const resultApm = await getDataHandler(app)?.hasData(); - updateState(resultApm?.hasData); + updateState({ hasData: resultApm?.hasData, indices: resultApm?.indices }); break; case 'infra_logs': case 'infra_metrics': const resultInfra = await getDataHandler(app)?.hasData(); - updateState(resultInfra); + updateState({ hasData: resultInfra }); break; } } catch (e) { diff --git a/x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts b/x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts index 7c4aacd1c51b7..197a8c1060cdb 100644 --- a/x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts +++ b/x-pack/plugins/observability/public/typings/fetch_overview_data/index.ts @@ -39,8 +39,8 @@ export interface HasDataResponse { } export interface UXHasDataResponse extends HasDataResponse { - serviceName: string | number | undefined; - indices: string; + serviceName?: string | number; + indices?: string; } export interface SyntheticsHasDataResponse extends HasDataResponse { From a802015a6e92ec20b3f1fc3eb4a843e25f26e160 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 16 Jun 2021 12:18:34 +0200 Subject: [PATCH 18/26] fix type --- .../public/components/app/section/ux/index.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/observability/public/components/app/section/ux/index.test.tsx b/x-pack/plugins/observability/public/components/app/section/ux/index.test.tsx index fcee238942c72..61bce8aaf845d 100644 --- a/x-pack/plugins/observability/public/components/app/section/ux/index.test.tsx +++ b/x-pack/plugins/observability/public/components/app/section/ux/index.test.tsx @@ -31,7 +31,8 @@ describe('UXSection', () => { hasDataMap: { ux: { status: fetcherHook.FETCH_STATUS.SUCCESS, - hasData: { hasData: true, serviceName: 'elastic-co-frontend' }, + hasData: true, + serviceName: 'elastic-co-frontend', }, }, } as HasDataContextValue); From dfc1690e056289b74f6d862f3652acc20889105b Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 16 Jun 2021 12:37:21 +0200 Subject: [PATCH 19/26] use i18n --- .../configurations/constants/constants.ts | 24 ++++--- .../configurations/constants/labels.ts | 69 +++++++++++++++++++ .../mobile/distribution_config.ts | 9 +-- .../mobile/kpi_over_time_config.ts | 23 ++++--- 4 files changed, 105 insertions(+), 20 deletions(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts index 307be440d2753..7a79cde88ae13 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts @@ -11,13 +11,18 @@ import { AGENT_HOST_LABEL, BROWSER_FAMILY_LABEL, BROWSER_VERSION_LABEL, + CARRIER_LOCATION, + CARRIER_NAME, CLS_LABEL, + CONNECTION_TYPE, CORE_WEB_VITALS_LABEL, DEVICE_LABEL, + DEVICE_MODEL, ENVIRONMENT_LABEL, FCP_LABEL, FID_LABEL, HOST_NAME_LABEL, + HOST_OS, KIP_OVER_TIME_LABEL, KPI_LABEL, LCP_LABEL, @@ -29,9 +34,12 @@ import { MONITOR_TYPE_LABEL, OBSERVER_LOCATION_LABEL, OS_LABEL, + OS_PLATFORM, PERF_DIST_LABEL, PORT_LABEL, + REQUEST_METHOD, SERVICE_NAME_LABEL, + SERVICE_VERSION, TAGS_LABEL, TBT_LABEL, URL_LABEL, @@ -73,15 +81,15 @@ export const FieldLabels: Record = { 'performance.metric': METRIC_LABEL, 'Business.KPI': KPI_LABEL, - 'labels.net_connection_carrier_name': 'Carrier Name', - 'http.request.method': 'Request Method', - 'labels.net_connection_type': 'Connection Type', - 'host.os.full': 'Host OS', - 'service.version': 'Service Version', - 'host.os.platform': 'OS Platform', - 'labels.device_model': ' Device Model', + 'labels.net_connection_carrier_name': CARRIER_NAME, + 'http.request.method': REQUEST_METHOD, + 'labels.net_connection_type': CONNECTION_TYPE, + 'host.os.full': HOST_OS, + 'service.version': SERVICE_VERSION, + 'host.os.platform': OS_PLATFORM, + 'labels.device_model': DEVICE_MODEL, // eslint-disable-next-line @typescript-eslint/naming-convention - 'labels.net_connection_carrier_isoCountryCode': 'Carrier Location', + 'labels.net_connection_carrier_isoCountryCode': CARRIER_LOCATION, }; export const DataViewLabels: Record = { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts index 08a22e48fa836..534bb652e4274 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts @@ -218,3 +218,72 @@ export const UP_LABEL = i18n.translate('xpack.observability.expView.fieldLabels. export const DOWN_LABEL = i18n.translate('xpack.observability.expView.fieldLabels.downPings', { defaultMessage: 'Down Pings', }); + +export const CARRIER_NAME = i18n.translate('xpack.observability.expView.fieldLabels.carrierName', { + defaultMessage: 'Carrier Name', +}); + +export const REQUEST_METHOD = i18n.translate( + 'xpack.observability.expView.fieldLabels.requestMethod', + { + defaultMessage: 'Request Method', + } +); + +export const CONNECTION_TYPE = i18n.translate( + 'xpack.observability.expView.fieldLabels.connectionType', + { + defaultMessage: 'Connection Type', + } +); +export const HOST_OS = i18n.translate('xpack.observability.expView.fieldLabels.hostOS', { + defaultMessage: 'Host OS', +}); + +export const SERVICE_VERSION = i18n.translate( + 'xpack.observability.expView.fieldLabels.serviceVersion', + { + defaultMessage: 'Service Version', + } +); + +export const OS_PLATFORM = i18n.translate('xpack.observability.expView.fieldLabels.osPlatform', { + defaultMessage: 'OS Platform', +}); + +export const DEVICE_MODEL = i18n.translate('xpack.observability.expView.fieldLabels.deviceModel', { + defaultMessage: 'Device Model', +}); + +export const CARRIER_LOCATION = i18n.translate( + 'xpack.observability.expView.fieldLabels.carrierLocation', + { + defaultMessage: 'Carrier Location', + } +); + +export const RESPONSE_LATENCY = i18n.translate( + 'xpack.observability.expView.fieldLabels.responseLatency', + { + defaultMessage: 'Response latency', + } +); + +export const MOBILE_APP = i18n.translate('xpack.observability.expView.fieldLabels.mobileApp', { + defaultMessage: 'Mobile App', +}); + +export const MEMORY_USAGE = i18n.translate('xpack.observability.expView.fieldLabels.memoryUsage', { + defaultMessage: 'Memory Usage', +}); + +export const CPU_USAGE = i18n.translate('xpack.observability.expView.fieldLabels.cpuUsage', { + defaultMessage: 'CPU Usage', +}); + +export const TRANSACTION_PER_MINUTE = i18n.translate( + 'xpack.observability.expView.fieldLabels.transactionPerMinute', + { + defaultMessage: 'Transactions per minute', + } +); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts index 82122e0745188..b11561b18a754 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts @@ -15,6 +15,7 @@ import { SERVICE_NAME, TRANSACTION_DURATION, } from '../constants/elasticsearch_fieldnames'; +import { CPU_USAGE, MEMORY_USAGE, MOBILE_APP, RESPONSE_LATENCY } from '../constants/labels'; export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): DataSeries { return { @@ -53,7 +54,7 @@ export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): D ], labels: { ...FieldLabels, - [SERVICE_NAME]: 'Mobile app', + [SERVICE_NAME]: MOBILE_APP, }, reportDefinitions: [ { @@ -69,19 +70,19 @@ export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): D custom: true, options: [ { - label: 'Response latency', + label: RESPONSE_LATENCY, field: TRANSACTION_DURATION, id: TRANSACTION_DURATION, columnType: OPERATION_COLUMN, }, { - label: 'Memory Usage', + label: MEMORY_USAGE, field: METRIC_SYSTEM_MEMORY_USAGE, id: METRIC_SYSTEM_MEMORY_USAGE, columnType: OPERATION_COLUMN, }, { - label: 'CPU Usage', + label: CPU_USAGE, field: METRIC_SYSTEM_CPU_USAGE, id: METRIC_SYSTEM_CPU_USAGE, columnType: OPERATION_COLUMN, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts index 5155d7f247ae3..6274d2ad79e43 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts @@ -15,6 +15,13 @@ import { SERVICE_NAME, TRANSACTION_DURATION, } from '../constants/elasticsearch_fieldnames'; +import { + CPU_USAGE, + MEMORY_USAGE, + MOBILE_APP, + RESPONSE_LATENCY, + TRANSACTION_PER_MINUTE, +} from '../constants/labels'; export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { return { @@ -53,10 +60,10 @@ export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { ], labels: { ...FieldLabels, - [TRANSACTION_DURATION]: 'Response latency', - [SERVICE_NAME]: 'Mobile app', - [METRIC_SYSTEM_MEMORY_USAGE]: 'Memory usage', - [METRIC_SYSTEM_CPU_USAGE]: 'CPU usage', + [TRANSACTION_DURATION]: RESPONSE_LATENCY, + [SERVICE_NAME]: MOBILE_APP, + [METRIC_SYSTEM_MEMORY_USAGE]: MEMORY_USAGE, + [METRIC_SYSTEM_CPU_USAGE]: CPU_USAGE, }, reportDefinitions: [ { @@ -72,19 +79,19 @@ export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { custom: true, options: [ { - label: 'Response latency', + label: RESPONSE_LATENCY, field: TRANSACTION_DURATION, id: TRANSACTION_DURATION, columnType: OPERATION_COLUMN, }, { - label: 'Memory Usage', + label: MEMORY_USAGE, field: METRIC_SYSTEM_MEMORY_USAGE, id: METRIC_SYSTEM_MEMORY_USAGE, columnType: OPERATION_COLUMN, }, { - label: 'CPU Usage', + label: CPU_USAGE, field: METRIC_SYSTEM_CPU_USAGE, id: METRIC_SYSTEM_CPU_USAGE, columnType: OPERATION_COLUMN, @@ -92,7 +99,7 @@ export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { { field: RECORDS_FIELD, id: RECORDS_FIELD, - label: 'Transactions per minute', + label: TRANSACTION_PER_MINUTE, columnFilters: [ { language: 'kuery', From 7f3bbc3fee26fc9ad126914433f9b71f0772bff9 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 16 Jun 2021 12:48:51 +0200 Subject: [PATCH 20/26] fix i18n --- .../exploratory_view/configurations/constants/labels.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts index 534bb652e4274..6d397d893e48b 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts @@ -273,9 +273,12 @@ export const MOBILE_APP = i18n.translate('xpack.observability.expView.fieldLabel defaultMessage: 'Mobile App', }); -export const MEMORY_USAGE = i18n.translate('xpack.observability.expView.fieldLabels.memoryUsage', { - defaultMessage: 'Memory Usage', -}); +export const MEMORY_USAGE = i18n.translate( + 'xpack.observability.expView.fieldLabels.mobile.memoryUsage', + { + defaultMessage: 'Memory Usage', + } +); export const CPU_USAGE = i18n.translate('xpack.observability.expView.fieldLabels.cpuUsage', { defaultMessage: 'CPU Usage', From b1005cd84de11cffaa16e02486294ea1ed68c017 Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Thu, 17 Jun 2021 11:23:07 +0200 Subject: [PATCH 21/26] Added mobile device distribution config + fixed mobile field names --- .../configurations/constants/constants.ts | 17 +------ .../configurations/constants/labels.ts | 9 +++- .../configurations/default_configs.ts | 5 ++ .../configurations/lens_attributes.ts | 44 ++++++++++++++-- .../mobile/device_distribution_config.ts | 51 +++++++++++++++++++ .../mobile/distribution_config.ts | 22 ++------ .../mobile/kpi_over_time_config.ts | 25 +++------ .../configurations/mobile/mobile_fields.ts | 19 +++++++ .../series_builder/series_builder.tsx | 1 + .../shared/exploratory_view/types.ts | 3 +- 10 files changed, 137 insertions(+), 59 deletions(-) create mode 100644 x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/device_distribution_config.ts create mode 100644 x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/mobile_fields.ts diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts index 7a79cde88ae13..77a99c3d30d41 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts @@ -11,18 +11,13 @@ import { AGENT_HOST_LABEL, BROWSER_FAMILY_LABEL, BROWSER_VERSION_LABEL, - CARRIER_LOCATION, - CARRIER_NAME, CLS_LABEL, - CONNECTION_TYPE, CORE_WEB_VITALS_LABEL, DEVICE_LABEL, - DEVICE_MODEL, ENVIRONMENT_LABEL, FCP_LABEL, FID_LABEL, HOST_NAME_LABEL, - HOST_OS, KIP_OVER_TIME_LABEL, KPI_LABEL, LCP_LABEL, @@ -34,12 +29,10 @@ import { MONITOR_TYPE_LABEL, OBSERVER_LOCATION_LABEL, OS_LABEL, - OS_PLATFORM, PERF_DIST_LABEL, PORT_LABEL, REQUEST_METHOD, SERVICE_NAME_LABEL, - SERVICE_VERSION, TAGS_LABEL, TBT_LABEL, URL_LABEL, @@ -80,16 +73,7 @@ export const FieldLabels: Record = { 'performance.metric': METRIC_LABEL, 'Business.KPI': KPI_LABEL, - - 'labels.net_connection_carrier_name': CARRIER_NAME, 'http.request.method': REQUEST_METHOD, - 'labels.net_connection_type': CONNECTION_TYPE, - 'host.os.full': HOST_OS, - 'service.version': SERVICE_VERSION, - 'host.os.platform': OS_PLATFORM, - 'labels.device_model': DEVICE_MODEL, - // eslint-disable-next-line @typescript-eslint/naming-convention - 'labels.net_connection_carrier_isoCountryCode': CARRIER_LOCATION, }; export const DataViewLabels: Record = { @@ -100,4 +84,5 @@ export const DataViewLabels: Record = { export const USE_BREAK_DOWN_COLUMN = 'USE_BREAK_DOWN_COLUMN'; export const FILTER_RECORDS = 'FILTER_RECORDS'; +export const TERMS_COLUMN = 'TERMS_COLUMN'; export const OPERATION_COLUMN = 'operation'; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts index 6d397d893e48b..571fc657f7449 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts @@ -284,9 +284,16 @@ export const CPU_USAGE = i18n.translate('xpack.observability.expView.fieldLabels defaultMessage: 'CPU Usage', }); -export const TRANSACTION_PER_MINUTE = i18n.translate( +export const TRANSACTIONS_PER_MINUTE = i18n.translate( 'xpack.observability.expView.fieldLabels.transactionPerMinute', { defaultMessage: 'Transactions per minute', } ); + +export const NUMBER_OF_DEVICES = i18n.translate( + 'xpack.observability.expView.fieldLabels.numberOfDevices', + { + defaultMessage: 'Number of Devices', + } +); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts index d1660c9256fa3..1162fa9dabef0 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts @@ -14,6 +14,8 @@ import { IndexPattern } from '../../../../../../../../src/plugins/data/common'; import { getCoreWebVitalsConfig } from './rum/core_web_vitals_config'; import { getMobileKPIConfig } from './mobile/kpi_over_time_config'; import { getMobileKPIDistributionConfig } from './mobile/distribution_config'; +import { getMobileDeviceDistributionConfig } from './mobile/device_distribution_config'; + interface Props { reportType: keyof typeof ReportViewTypes; @@ -40,6 +42,9 @@ export const getDefaultConfigs = ({ reportType, dataType, indexPattern }: Props) if (reportType === 'dist') { return getMobileKPIDistributionConfig({ indexPattern }); } + if (reportType === 'mdd') { + return getMobileDeviceDistributionConfig({ indexPattern }); + } return getMobileKPIConfig({ indexPattern }); default: return getKPITrendsLensConfig({ indexPattern }); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts index 01dcdd18ba0c7..a7104d75fb401 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts @@ -25,13 +25,14 @@ import { FieldBasedIndexPatternColumn, SumIndexPatternColumn, TermsIndexPatternColumn, + CardinalityIndexPatternColumn, } from '../../../../../../lens/public'; import { buildPhraseFilter, buildPhrasesFilter, IndexPattern, } from '../../../../../../../../src/plugins/data/common'; -import { FieldLabels, FILTER_RECORDS, USE_BREAK_DOWN_COLUMN } from './constants'; +import { FieldLabels, FILTER_RECORDS, USE_BREAK_DOWN_COLUMN, TERMS_COLUMN } from './constants'; import { ColumnFilter, DataSeries, UrlFilter, URLReportDefinition } from '../types'; function getLayerReferenceName(layerId: string) { @@ -186,6 +187,11 @@ export class LensAttributes { }; } + getCardinalityColumn(sourceField: string, + label?: string) { + return this.getNumberOperationColumn(sourceField, 'unique_count', label); + } + getNumberColumn( sourceField: string, columnType?: string, @@ -193,7 +199,7 @@ export class LensAttributes { label?: string ) { if (columnType === 'operation' || operationType) { - if (operationType === 'median' || operationType === 'average' || operationType === 'sum') { + if (operationType === 'median' || operationType === 'average' || operationType === 'sum' || operationType === 'unique_count') { return this.getNumberOperationColumn(sourceField, operationType, label); } if (operationType?.includes('th')) { @@ -205,9 +211,9 @@ export class LensAttributes { getNumberOperationColumn( sourceField: string, - operationType: 'average' | 'median' | 'sum', + operationType: 'average' | 'median' | 'sum' | 'unique_count', label?: string - ): AvgIndexPatternColumn | MedianIndexPatternColumn | SumIndexPatternColumn { + ): AvgIndexPatternColumn | MedianIndexPatternColumn | SumIndexPatternColumn | CardinalityIndexPatternColumn { return { ...buildNumberColumn(sourceField), label: @@ -237,7 +243,7 @@ export class LensAttributes { params: { percentile: Number(percentileValue.split('th')[0]) }, }; } - + getDateHistogramColumn(sourceField: string): DateHistogramIndexPatternColumn { return { sourceField, @@ -250,6 +256,25 @@ export class LensAttributes { }; } + getTermsColumn(sourceField: string, label?: string) : TermsIndexPatternColumn{ + return { + operationType: 'terms', + sourceField: sourceField, + label: label || 'Top values of ' + sourceField, + dataType: 'string', + isBucketed: true, + scale: 'ordinal', + params: { + size: 10, + orderBy: { + type: 'alphabetical', + fallback: false + }, + orderDirection: 'desc', + } + }; + } + getXAxis() { const { xAxisColumn } = this.reportViewConfig; @@ -276,6 +301,12 @@ export class LensAttributes { } = this.getFieldMeta(sourceField); const { type: fieldType } = fieldMeta ?? {}; + if(columnType === TERMS_COLUMN){ + return this.getTermsColumn( + fieldName, columnLabel || label + ); + } + if (fieldName === 'Records' || columnType === FILTER_RECORDS) { return this.getRecordsColumn( columnLabel || label, @@ -290,6 +321,9 @@ export class LensAttributes { if (fieldType === 'number') { return this.getNumberColumn(fieldName, columnType, operationType, columnLabel || label); } + if (operationType === 'unique_count') { + return this.getCardinalityColumn(fieldName, columnLabel || label); + } // FIXME review my approach again return this.getDateHistogramColumn(fieldName); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/device_distribution_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/device_distribution_config.ts new file mode 100644 index 0000000000000..92ae10cfb041f --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/device_distribution_config.ts @@ -0,0 +1,51 @@ +/* + * 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 { ConfigProps, DataSeries } from '../../types'; +import { FieldLabels, USE_BREAK_DOWN_COLUMN } from '../constants'; +import { buildPhraseFilter } from '../utils'; +import { + SERVICE_NAME, +} from '../constants/elasticsearch_fieldnames'; +import { MOBILE_APP, NUMBER_OF_DEVICES } from '../constants/labels'; +import { MobileFields } from './mobile_fields'; + +export function getMobileDeviceDistributionConfig({ indexPattern }: ConfigProps): DataSeries { + return { + reportType: 'mobile-device-distribution', + defaultSeriesType: 'bar', + seriesTypes: ['bar', 'bar_horizontal' ], + xAxisColumn: { + sourceField: USE_BREAK_DOWN_COLUMN, + }, + yAxisColumns: [ + { + sourceField: 'labels.device_id', + operationType: 'unique_count', + label: NUMBER_OF_DEVICES, + }, + ], + hasOperationType: false, + defaultFilters: Object.keys(MobileFields), + breakdowns: Object.keys(MobileFields), + filters: [ + ...buildPhraseFilter('agent.name', 'iOS/swift', indexPattern), + ...buildPhraseFilter('processor.event', 'transaction', indexPattern), + ], + labels: { + ...FieldLabels, + ...MobileFields, + [SERVICE_NAME]: MOBILE_APP, + }, + reportDefinitions: [ + { + field: SERVICE_NAME, + required: true, + }, + ], + }; +} diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts index b11561b18a754..8ceace2d56970 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts @@ -15,7 +15,9 @@ import { SERVICE_NAME, TRANSACTION_DURATION, } from '../constants/elasticsearch_fieldnames'; + import { CPU_USAGE, MEMORY_USAGE, MOBILE_APP, RESPONSE_LATENCY } from '../constants/labels'; +import { MobileFields } from './mobile_fields'; export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): DataSeries { return { @@ -32,28 +34,14 @@ export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): D }, ], hasOperationType: false, - defaultFilters: [ - 'labels.net_connection_carrier_name', - 'labels.device_model', - 'labels.net_connection_type', - 'host.os.platform', - 'host.os.full', - 'service.version', - ], - breakdowns: [ - 'labels.net_connection_carrier_name', - 'labels.device_model', - 'labels.net_connection_type', - 'host.os.platform', - 'host.os.full', - 'service.version', - 'labels.net_connection_carrier_isoCountryCode', - ], + defaultFilters: Object.keys(MobileFields), + breakdowns: Object.keys(MobileFields), filters: [ ...buildPhrasesFilter('agent.name', ['iOS/swift', 'open-telemetry/swift'], indexPattern), ], labels: { ...FieldLabels, + ...MobileFields, [SERVICE_NAME]: MOBILE_APP, }, reportDefinitions: [ diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts index 6274d2ad79e43..1c87daa8d2ce9 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts @@ -20,8 +20,9 @@ import { MEMORY_USAGE, MOBILE_APP, RESPONSE_LATENCY, - TRANSACTION_PER_MINUTE, + TRANSACTIONS_PER_MINUTE, } from '../constants/labels'; +import { MobileFields } from './mobile_fields'; export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { return { @@ -38,28 +39,14 @@ export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { }, ], hasOperationType: true, - defaultFilters: [ - 'labels.net_connection_carrier_name', - 'labels.device_model', - 'labels.net_connection_type', - 'host.os.platform', - 'host.os.full', - 'service.version', - ], - breakdowns: [ - 'labels.net_connection_carrier_name', - 'labels.device_model', - 'labels.net_connection_type', - 'host.os.platform', - 'host.os.full', - 'service.version', - 'labels.net_connection_carrier_isoCountryCode', - ], + defaultFilters: Object.keys(MobileFields), + breakdowns: Object.keys(MobileFields), filters: [ ...buildPhrasesFilter('agent.name', ['iOS/swift', 'open-telemetry/swift'], indexPattern), ], labels: { ...FieldLabels, + ...MobileFields, [TRANSACTION_DURATION]: RESPONSE_LATENCY, [SERVICE_NAME]: MOBILE_APP, [METRIC_SYSTEM_MEMORY_USAGE]: MEMORY_USAGE, @@ -99,7 +86,7 @@ export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { { field: RECORDS_FIELD, id: RECORDS_FIELD, - label: TRANSACTION_PER_MINUTE, + label: TRANSACTIONS_PER_MINUTE, columnFilters: [ { language: 'kuery', diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/mobile_fields.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/mobile_fields.ts new file mode 100644 index 0000000000000..2fcac0ac1d5ce --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/mobile_fields.ts @@ -0,0 +1,19 @@ +import { + CARRIER_LOCATION, + CARRIER_NAME, + CONNECTION_TYPE, + DEVICE_MODEL, + HOST_OS, + OS_PLATFORM, + SERVICE_VERSION, + } from '../constants/labels'; + +export const MobileFields : Record = { + 'host.os.platform': OS_PLATFORM, + 'host.os.full': HOST_OS, + 'service.version': SERVICE_VERSION, + 'network.carrier.icc': CARRIER_LOCATION, + 'network.carrier.name': CARRIER_NAME, + 'network.connection_type': CONNECTION_TYPE, + 'labels.device_model': DEVICE_MODEL, +}; \ No newline at end of file diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx index 648809908e2e3..cb7aad65cb630 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx @@ -32,6 +32,7 @@ export const ReportTypes: Record = T[keyof T]; @@ -45,7 +46,7 @@ export interface ReportDefinition { field?: string; label: string; description?: string; - columnType?: 'range' | 'operation' | 'FILTER_RECORDS'; + columnType?: 'range' | 'operation' | 'FILTER_RECORDS' | 'TERMS_COLUMN'; columnFilters?: ColumnFilter[]; timeScale?: string; }>; From c949862358617efb8b72a71b34da3d49b3a4dd06 Mon Sep 17 00:00:00 2001 From: Alexander Wert Date: Thu, 17 Jun 2021 11:37:14 +0200 Subject: [PATCH 22/26] fixing chart type options and label for distribution --- .../configurations/mobile/distribution_config.ts | 1 - .../configurations/mobile/kpi_over_time_config.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts index 8ceace2d56970..62dd38e55a32a 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts @@ -30,7 +30,6 @@ export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): D yAxisColumns: [ { sourceField: RECORDS_FIELD, - label: 'Transactions', }, ], hasOperationType: false, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts index 1c87daa8d2ce9..2ed4d95760db7 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts @@ -28,7 +28,7 @@ export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { return { reportType: 'kpi-over-time', defaultSeriesType: 'line', - seriesTypes: ['line', 'bar'], + seriesTypes: ['line', 'bar', 'area'], xAxisColumn: { sourceField: '@timestamp', }, From 22ef586c3f9edd6750a1226d8970aaa399173f1f Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 17 Jun 2021 13:44:42 +0200 Subject: [PATCH 23/26] fix types --- .../exploratory_view/configurations/constants/constants.ts | 2 ++ .../exploratory_view/configurations/constants/labels.ts | 7 +++++++ .../exploratory_view/series_builder/series_builder.tsx | 3 ++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts index 77a99c3d30d41..9156c0b1eb4b8 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts @@ -13,6 +13,7 @@ import { BROWSER_VERSION_LABEL, CLS_LABEL, CORE_WEB_VITALS_LABEL, + DEVICE_DISTRIBUTION_LABEL, DEVICE_LABEL, ENVIRONMENT_LABEL, FCP_LABEL, @@ -80,6 +81,7 @@ export const DataViewLabels: Record = { dist: PERF_DIST_LABEL, kpi: KIP_OVER_TIME_LABEL, cwv: CORE_WEB_VITALS_LABEL, + mdd: DEVICE_DISTRIBUTION_LABEL, }; export const USE_BREAK_DOWN_COLUMN = 'USE_BREAK_DOWN_COLUMN'; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts index 571fc657f7449..21ba90aef6815 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts @@ -176,6 +176,13 @@ export const CORE_WEB_VITALS_LABEL = i18n.translate( } ); +export const DEVICE_DISTRIBUTION_LABEL = i18n.translate( + 'xpack.observability.expView.fieldLabels.deviceDistribution', + { + defaultMessage: 'Device distribution', + } +); + export const MOBILE_RESPONSE_LABEL = i18n.translate( 'xpack.observability.expView.fieldLabels.mobileReponse', { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx index cb7aad65cb630..8f215dea7c3a1 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx @@ -18,6 +18,7 @@ import { ReportBreakdowns } from './columns/report_breakdowns'; import { NEW_SERIES_KEY, useSeriesStorage } from '../hooks/use_series_storage'; import { useAppIndexPatternContext } from '../hooks/use_app_index_pattern'; import { getDefaultConfigs } from '../configurations/default_configs'; +import { DEVICE_DISTRIBUTION_LABEL } from '../configurations/constants/labels'; export const ReportTypes: Record> = { synthetics: [ @@ -32,7 +33,7 @@ export const ReportTypes: Record Date: Thu, 17 Jun 2021 13:50:48 +0200 Subject: [PATCH 24/26] fix 18n --- .../configurations/constants/constants.ts | 4 ++-- .../configurations/constants/labels.ts | 6 +++--- .../series_builder/series_builder.tsx | 21 ++++++++++++------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts index 9156c0b1eb4b8..e119507860c5c 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts @@ -19,7 +19,7 @@ import { FCP_LABEL, FID_LABEL, HOST_NAME_LABEL, - KIP_OVER_TIME_LABEL, + KPI_OVER_TIME_LABEL, KPI_LABEL, LCP_LABEL, LOCATION_LABEL, @@ -79,7 +79,7 @@ export const FieldLabels: Record = { export const DataViewLabels: Record = { dist: PERF_DIST_LABEL, - kpi: KIP_OVER_TIME_LABEL, + kpi: KPI_OVER_TIME_LABEL, cwv: CORE_WEB_VITALS_LABEL, mdd: DEVICE_DISTRIBUTION_LABEL, }; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts index 21ba90aef6815..73739b7db12ef 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/labels.ts @@ -165,7 +165,7 @@ export const KPI_LABEL = i18n.translate('xpack.observability.expView.fieldLabels export const PERF_DIST_LABEL = i18n.translate( 'xpack.observability.expView.fieldLabels.performanceDistribution', { - defaultMessage: 'Performance Distribution', + defaultMessage: 'Performance distribution', } ); @@ -184,7 +184,7 @@ export const DEVICE_DISTRIBUTION_LABEL = i18n.translate( ); export const MOBILE_RESPONSE_LABEL = i18n.translate( - 'xpack.observability.expView.fieldLabels.mobileReponse', + 'xpack.observability.expView.fieldLabels.mobileResponse', { defaultMessage: 'Mobile response', } @@ -197,7 +197,7 @@ export const MEMORY_USAGE_LABEL = i18n.translate( } ); -export const KIP_OVER_TIME_LABEL = i18n.translate( +export const KPI_OVER_TIME_LABEL = i18n.translate( 'xpack.observability.expView.fieldLabels.kpiOverTime', { defaultMessage: 'KPI over time', diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx index 8f215dea7c3a1..9aef16931d7ec 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx @@ -18,21 +18,26 @@ import { ReportBreakdowns } from './columns/report_breakdowns'; import { NEW_SERIES_KEY, useSeriesStorage } from '../hooks/use_series_storage'; import { useAppIndexPatternContext } from '../hooks/use_app_index_pattern'; import { getDefaultConfigs } from '../configurations/default_configs'; -import { DEVICE_DISTRIBUTION_LABEL } from '../configurations/constants/labels'; +import { + CORE_WEB_VITALS_LABEL, + DEVICE_DISTRIBUTION_LABEL, + KPI_OVER_TIME_LABEL, + PERF_DIST_LABEL, +} from '../configurations/constants/labels'; export const ReportTypes: Record> = { synthetics: [ - { id: 'kpi', label: 'KPI over time' }, - { id: 'dist', label: 'Performance distribution' }, + { id: 'kpi', label: KPI_OVER_TIME_LABEL }, + { id: 'dist', label: PERF_DIST_LABEL }, ], ux: [ - { id: 'kpi', label: 'KPI over time' }, - { id: 'dist', label: 'Performance distribution' }, - { id: 'cwv', label: 'Core Web Vitals' }, + { id: 'kpi', label: KPI_OVER_TIME_LABEL }, + { id: 'dist', label: PERF_DIST_LABEL }, + { id: 'cwv', label: CORE_WEB_VITALS_LABEL }, ], mobile: [ - { id: 'kpi', label: 'KPI over time' }, - { id: 'dist', label: 'Performance distribution' }, + { id: 'kpi', label: KPI_OVER_TIME_LABEL }, + { id: 'dist', label: PERF_DIST_LABEL }, { id: 'mdd', label: DEVICE_DISTRIBUTION_LABEL }, ], apm: [], From 0ecb538b94f23955d48e46fd08c26b5f95ba5ef6 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 17 Jun 2021 14:12:12 +0200 Subject: [PATCH 25/26] fix test --- .../mobile/device_distribution_config.ts | 8 +++----- .../exploratory_view/exploratory_view.test.tsx | 2 +- .../series_builder/columns/report_filters.tsx | 1 + .../series_editor/columns/series_filter.tsx | 14 +++++++++++--- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/device_distribution_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/device_distribution_config.ts index 92ae10cfb041f..6f9806660e489 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/device_distribution_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/device_distribution_config.ts @@ -8,9 +8,7 @@ import { ConfigProps, DataSeries } from '../../types'; import { FieldLabels, USE_BREAK_DOWN_COLUMN } from '../constants'; import { buildPhraseFilter } from '../utils'; -import { - SERVICE_NAME, -} from '../constants/elasticsearch_fieldnames'; +import { SERVICE_NAME } from '../constants/elasticsearch_fieldnames'; import { MOBILE_APP, NUMBER_OF_DEVICES } from '../constants/labels'; import { MobileFields } from './mobile_fields'; @@ -18,7 +16,7 @@ export function getMobileDeviceDistributionConfig({ indexPattern }: ConfigProps) return { reportType: 'mobile-device-distribution', defaultSeriesType: 'bar', - seriesTypes: ['bar', 'bar_horizontal' ], + seriesTypes: ['bar', 'bar_horizontal'], xAxisColumn: { sourceField: USE_BREAK_DOWN_COLUMN, }, @@ -35,7 +33,7 @@ export function getMobileDeviceDistributionConfig({ indexPattern }: ConfigProps) filters: [ ...buildPhraseFilter('agent.name', 'iOS/swift', indexPattern), ...buildPhraseFilter('processor.event', 'transaction', indexPattern), - ], + ], labels: { ...FieldLabels, ...MobileFields, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/exploratory_view.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/exploratory_view.test.tsx index 487ecdb2bafcc..779049601bd6d 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/exploratory_view.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/exploratory_view.test.tsx @@ -63,7 +63,7 @@ describe('ExploratoryView', () => { render(, { initSeries }); expect(await screen.findByText(/open in lens/i)).toBeInTheDocument(); - expect(await screen.findByText('Performance Distribution')).toBeInTheDocument(); + expect((await screen.findAllByText('Performance distribution'))[0]).toBeInTheDocument(); expect(await screen.findByText(/Lens Embeddable Component/i)).toBeInTheDocument(); await waitFor(() => { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.tsx index d0aad4c377a0d..4571ecfe252e9 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.tsx @@ -23,6 +23,7 @@ export function ReportFilters({ filters={dataViewSeries.filters} seriesId={seriesId} isNew={true} + labels={dataViewSeries.labels} /> ); } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/series_filter.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/series_filter.tsx index 248279350ed35..b7e20b341b572 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/series_filter.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/series_filter.tsx @@ -27,6 +27,7 @@ interface Props { filters: DataSeries['filters']; series: DataSeries; isNew?: boolean; + labels?: Record; } export interface Field { @@ -36,21 +37,28 @@ export interface Field { isNegated?: boolean; } -export function SeriesFilter({ series, isNew, seriesId, defaultFilters = [], filters }: Props) { +export function SeriesFilter({ + series, + isNew, + seriesId, + defaultFilters = [], + filters, + labels, +}: Props) { const [isPopoverVisible, setIsPopoverVisible] = useState(false); const [selectedField, setSelectedField] = useState(); const options: Field[] = defaultFilters.map((field) => { if (typeof field === 'string') { - return { label: FieldLabels[field], field }; + return { label: labels?.[field] ?? FieldLabels[field], field }; } return { field: field.field, nested: field.nested, isNegated: field.isNegated, - label: FieldLabels[field.field], + label: labels?.[field.field] ?? FieldLabels[field.field], }; }); From 2289c585031dbfec8cc2f4f3ca33f50bb9d31772 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 17 Jun 2021 17:03:27 +0200 Subject: [PATCH 26/26] fix lint --- .../configurations/default_configs.ts | 1 - .../configurations/lens_attributes.ts | 34 +++++++++------ .../configurations/mobile/mobile_fields.ts | 43 +++++++++++-------- 3 files changed, 45 insertions(+), 33 deletions(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts index 1162fa9dabef0..07342d976cbea 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/default_configs.ts @@ -16,7 +16,6 @@ import { getMobileKPIConfig } from './mobile/kpi_over_time_config'; import { getMobileKPIDistributionConfig } from './mobile/distribution_config'; import { getMobileDeviceDistributionConfig } from './mobile/device_distribution_config'; - interface Props { reportType: keyof typeof ReportViewTypes; indexPattern: IndexPattern; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts index a7104d75fb401..22ad18c663b32 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts @@ -187,9 +187,8 @@ export class LensAttributes { }; } - getCardinalityColumn(sourceField: string, - label?: string) { - return this.getNumberOperationColumn(sourceField, 'unique_count', label); + getCardinalityColumn(sourceField: string, label?: string) { + return this.getNumberOperationColumn(sourceField, 'unique_count', label); } getNumberColumn( @@ -199,7 +198,12 @@ export class LensAttributes { label?: string ) { if (columnType === 'operation' || operationType) { - if (operationType === 'median' || operationType === 'average' || operationType === 'sum' || operationType === 'unique_count') { + if ( + operationType === 'median' || + operationType === 'average' || + operationType === 'sum' || + operationType === 'unique_count' + ) { return this.getNumberOperationColumn(sourceField, operationType, label); } if (operationType?.includes('th')) { @@ -213,7 +217,11 @@ export class LensAttributes { sourceField: string, operationType: 'average' | 'median' | 'sum' | 'unique_count', label?: string - ): AvgIndexPatternColumn | MedianIndexPatternColumn | SumIndexPatternColumn | CardinalityIndexPatternColumn { + ): + | AvgIndexPatternColumn + | MedianIndexPatternColumn + | SumIndexPatternColumn + | CardinalityIndexPatternColumn { return { ...buildNumberColumn(sourceField), label: @@ -243,7 +251,7 @@ export class LensAttributes { params: { percentile: Number(percentileValue.split('th')[0]) }, }; } - + getDateHistogramColumn(sourceField: string): DateHistogramIndexPatternColumn { return { sourceField, @@ -256,10 +264,10 @@ export class LensAttributes { }; } - getTermsColumn(sourceField: string, label?: string) : TermsIndexPatternColumn{ + getTermsColumn(sourceField: string, label?: string): TermsIndexPatternColumn { return { operationType: 'terms', - sourceField: sourceField, + sourceField, label: label || 'Top values of ' + sourceField, dataType: 'string', isBucketed: true, @@ -268,10 +276,10 @@ export class LensAttributes { size: 10, orderBy: { type: 'alphabetical', - fallback: false + fallback: false, }, orderDirection: 'desc', - } + }, }; } @@ -301,10 +309,8 @@ export class LensAttributes { } = this.getFieldMeta(sourceField); const { type: fieldType } = fieldMeta ?? {}; - if(columnType === TERMS_COLUMN){ - return this.getTermsColumn( - fieldName, columnLabel || label - ); + if (columnType === TERMS_COLUMN) { + return this.getTermsColumn(fieldName, columnLabel || label); } if (fieldName === 'Records' || columnType === FILTER_RECORDS) { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/mobile_fields.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/mobile_fields.ts index 2fcac0ac1d5ce..4ece4ff056a59 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/mobile_fields.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/mobile_fields.ts @@ -1,19 +1,26 @@ +/* + * 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 { - CARRIER_LOCATION, - CARRIER_NAME, - CONNECTION_TYPE, - DEVICE_MODEL, - HOST_OS, - OS_PLATFORM, - SERVICE_VERSION, - } from '../constants/labels'; - -export const MobileFields : Record = { - 'host.os.platform': OS_PLATFORM, - 'host.os.full': HOST_OS, - 'service.version': SERVICE_VERSION, - 'network.carrier.icc': CARRIER_LOCATION, - 'network.carrier.name': CARRIER_NAME, - 'network.connection_type': CONNECTION_TYPE, - 'labels.device_model': DEVICE_MODEL, -}; \ No newline at end of file + CARRIER_LOCATION, + CARRIER_NAME, + CONNECTION_TYPE, + DEVICE_MODEL, + HOST_OS, + OS_PLATFORM, + SERVICE_VERSION, +} from '../constants/labels'; + +export const MobileFields: Record = { + 'host.os.platform': OS_PLATFORM, + 'host.os.full': HOST_OS, + 'service.version': SERVICE_VERSION, + 'network.carrier.icc': CARRIER_LOCATION, + 'network.carrier.name': CARRIER_NAME, + 'network.connection_type': CONNECTION_TYPE, + 'labels.device_model': DEVICE_MODEL, +};