diff --git a/packages/kbn-apm-types/src/es_fields/apm.ts b/packages/kbn-apm-types/src/es_fields/apm.ts index a72930edb5906..b58fb0e23c467 100644 --- a/packages/kbn-apm-types/src/es_fields/apm.ts +++ b/packages/kbn-apm-types/src/es_fields/apm.ts @@ -131,6 +131,7 @@ export const ERROR_EXC_MESSAGE = 'error.exception.message'; // only to be used i export const ERROR_EXC_HANDLED = 'error.exception.handled'; // only to be used in es queries, since error.exception is now an array export const ERROR_EXC_TYPE = 'error.exception.type'; export const ERROR_PAGE_URL = 'error.page.url'; +export const ERROR_STACK_TRACE = 'error.stack_trace'; export const ERROR_TYPE = 'error.type'; // METRICS diff --git a/x-pack/plugins/observability_solution/apm/common/es_fields/__snapshots__/es_fields.test.ts.snap b/x-pack/plugins/observability_solution/apm/common/es_fields/__snapshots__/es_fields.test.ts.snap index 2bae834f8098e..2832d107185b7 100644 --- a/x-pack/plugins/observability_solution/apm/common/es_fields/__snapshots__/es_fields.test.ts.snap +++ b/x-pack/plugins/observability_solution/apm/common/es_fields/__snapshots__/es_fields.test.ts.snap @@ -114,6 +114,8 @@ exports[`Error ERROR_LOG_MESSAGE 1`] = `undefined`; exports[`Error ERROR_PAGE_URL 1`] = `undefined`; +exports[`Error ERROR_STACK_TRACE 1`] = `undefined`; + exports[`Error ERROR_TYPE 1`] = `undefined`; exports[`Error EVENT_NAME 1`] = `undefined`; @@ -509,6 +511,8 @@ exports[`Span ERROR_LOG_MESSAGE 1`] = `undefined`; exports[`Span ERROR_PAGE_URL 1`] = `undefined`; +exports[`Span ERROR_STACK_TRACE 1`] = `undefined`; + exports[`Span ERROR_TYPE 1`] = `undefined`; exports[`Span EVENT_NAME 1`] = `undefined`; @@ -900,6 +904,8 @@ exports[`Transaction ERROR_LOG_MESSAGE 1`] = `undefined`; exports[`Transaction ERROR_PAGE_URL 1`] = `undefined`; +exports[`Transaction ERROR_STACK_TRACE 1`] = `undefined`; + exports[`Transaction ERROR_TYPE 1`] = `undefined`; exports[`Transaction EVENT_NAME 1`] = `undefined`; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts b/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts index 1e9576ea2f7e4..b493dd8cbc562 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts @@ -7,6 +7,8 @@ import { AggregationsAggregateOrder } from '@elastic/elasticsearch/lib/api/types'; import { kqlQuery, rangeQuery, termQuery, wildcardQuery } from '@kbn/observability-plugin/server'; +import { APMError } from '@kbn/apm-types'; +import { errorGroupMainStatisticsMapping } from '../../../utils/es_fields_mappings/error'; import { ERROR_CULPRIT, ERROR_EXC_HANDLED, @@ -129,7 +131,7 @@ export async function getErrorGroupMainStatistics({ sample: { top_hits: { size: 1, - _source: [ + fields: [ TRACE_ID, ERROR_LOG_MESSAGE, ERROR_EXC_MESSAGE, @@ -157,15 +159,17 @@ export async function getErrorGroupMainStatistics({ const errorGroups = response.aggregations?.error_groups.buckets.map((bucket) => { + const normalizedFields = errorGroupMainStatisticsMapping(bucket.sample.hits.hits[0].fields); + return { groupId: bucket.key as string, - name: getErrorName(bucket.sample.hits.hits[0]._source), - lastSeen: new Date(bucket.sample.hits.hits[0]._source['@timestamp']).getTime(), + name: getErrorName({ error: normalizedFields?.error } as APMError), + lastSeen: new Date(normalizedFields?.['@timestamp'] as string).getTime(), occurrences: bucket.doc_count, - culprit: bucket.sample.hits.hits[0]._source.error.culprit, - handled: bucket.sample.hits.hits[0]._source.error.exception?.[0].handled, - type: bucket.sample.hits.hits[0]._source.error.exception?.[0].type, - traceId: bucket.sample.hits.hits[0]._source.trace?.id, + culprit: normalizedFields?.error.culprit, + handled: normalizedFields?.error.exception[0].handled, + type: normalizedFields?.error.exception[0].type, + traceId: normalizedFields?.trace.id, }; }) ?? []; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_group_sample_ids.ts b/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_group_sample_ids.ts index dc35c963b14b6..43b950f3a2293 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_group_sample_ids.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_group_sample_ids.ts @@ -6,6 +6,7 @@ */ import { rangeQuery, kqlQuery } from '@kbn/observability-plugin/server'; +import { normalizeValue } from '../../../utils/es_fields_mappings/es_fields_mappings_helpers'; import { asMutableArray } from '../../../../common/utils/as_mutable_array'; import { ERROR_GROUP_ID, @@ -66,7 +67,7 @@ export async function getErrorGroupSampleIds({ should: [{ term: { [TRANSACTION_SAMPLED]: true } }], // prefer error samples with related transactions }, }, - _source: [ERROR_ID, 'transaction'], + fields: [ERROR_ID], sort: asMutableArray([ { _score: { order: 'desc' } }, // sort by _score first to ensure that errors with transaction.sampled:true ends up on top { '@timestamp': { order: 'desc' } }, // sort by timestamp to get the most recent error @@ -74,8 +75,10 @@ export async function getErrorGroupSampleIds({ }, }); const errorSampleIds = resp.hits.hits.map((item) => { - const source = item._source; - return source?.error?.id; + const fields = item.fields; + const errorId = normalizeValue(fields?.['error.id']); + + return errorId; }); return { diff --git a/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_sample_details.ts b/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_sample_details.ts index 287fce04478ec..0e515ee6493f8 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_sample_details.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/errors/get_error_groups/get_error_sample_details.ts @@ -14,6 +14,7 @@ import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm import { getTransaction } from '../../transactions/get_transaction'; import { Transaction } from '../../../../typings/es_schemas/ui/transaction'; import { APMError } from '../../../../typings/es_schemas/ui/apm_error'; +import { errorSampleDetailsMapping } from '../../../utils/es_fields_mappings/error'; export interface ErrorSampleDetailsResponse { transaction: Transaction | undefined; @@ -60,24 +61,25 @@ export async function getErrorSampleDetails({ ], }, }, + fields: ['*'], }, }; const resp = await apmEventClient.search('get_error_sample_details', params); - const error = resp.hits.hits[0]?._source; + const error = errorSampleDetailsMapping(resp.hits.hits[0]?.fields) as APMError; const transactionId = error?.transaction?.id; const traceId = error?.trace?.id; - let transaction; + let transaction: Transaction | undefined; if (transactionId && traceId) { - transaction = await getTransaction({ + transaction = (await getTransaction({ transactionId, traceId, apmEventClient, start, end, - }); + })) as Transaction; } return { diff --git a/x-pack/plugins/observability_solution/apm/server/utils/es_fields_mappings/error.ts b/x-pack/plugins/observability_solution/apm/server/utils/es_fields_mappings/error.ts index f5ecea338aabd..7746820b46617 100644 --- a/x-pack/plugins/observability_solution/apm/server/utils/es_fields_mappings/error.ts +++ b/x-pack/plugins/observability_solution/apm/server/utils/es_fields_mappings/error.ts @@ -17,6 +17,7 @@ import { ERROR_EXC_HANDLED, ERROR_EXC_TYPE, ERROR_CULPRIT, + ERROR_STACK_TRACE, AT_TIMESTAMP, APMError, OBSERVER_TYPE, @@ -73,7 +74,6 @@ export const errorGroupMainStatisticsMapping = (fields: Fields) => { id: normalizeValue(fields[TRACE_ID]), }, error: { - id: normalizeValue(fields[ERROR_ID]), log: { message: normalizeValue(fields[ERROR_LOG_MESSAGE]), }, @@ -85,7 +85,6 @@ export const errorGroupMainStatisticsMapping = (fields: Fields) => { }, ], culprit: normalizeValue(fields[ERROR_CULPRIT]), - grouping_key: normalizeValue(fields[ERROR_GROUP_ID]), }, '@timestamp': normalizeValue(fields[AT_TIMESTAMP]), }; @@ -121,6 +120,7 @@ export const errorSampleDetailsMapping = (fields: Fields): APMError | undefined }, ], grouping_key: normalizeValue(fields[ERROR_GROUP_ID]), + stack_trace: normalizeValue(fields[ERROR_STACK_TRACE]), }, processor: { name: normalizeValue<'error'>(fields[PROCESSOR_NAME]),