[APM Replace usage of idx with optional chaining (#50849)

Closes #50758
This commit is contained in:
Dario Gieselaar 2019-11-16 18:56:37 +01:00 committed by GitHub
parent ee7338e82d
commit cae3a472c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 168 additions and 185 deletions

View file

@ -6,7 +6,6 @@
import { i18n } from '@kbn/i18n';
import { isEmpty } from 'lodash';
import { idx } from '@kbn/elastic-idx';
import { APMError } from '../../../../../typings/es_schemas/ui/APMError';
export interface ErrorTab {
@ -39,7 +38,7 @@ export const metadataTab: ErrorTab = {
};
export function getTabs(error: APMError) {
const hasLogStacktrace = !isEmpty(idx(error, _ => _.error.log.stacktrace));
const hasLogStacktrace = !isEmpty(error.error.log?.stacktrace);
return [
...(hasLogStacktrace ? [logStacktraceTab] : []),
exceptionStacktraceTab,

View file

@ -6,7 +6,6 @@
import React from 'react';
import { EuiTitle } from '@elastic/eui';
import { idx } from '@kbn/elastic-idx/target';
import { Exception } from '../../../../../typings/es_schemas/raw/ErrorRaw';
import { Stacktrace } from '../../../shared/Stacktrace';
import { CauseStacktrace } from '../../../shared/Stacktrace/CauseStacktrace';
@ -20,7 +19,7 @@ export function ExceptionStacktrace({
codeLanguage,
exceptions
}: ExceptionStacktraceProps) {
const title = idx(exceptions, _ => _[0].message);
const title = exceptions[0]?.message;
return (
<>

View file

@ -52,6 +52,7 @@ exports[`DetailView should render TabContent 1`] = `
error={
Object {
"context": Object {},
"error": Object {},
"timestamp": Object {
"us": 0,
},

View file

@ -60,6 +60,7 @@ describe('DetailView', () => {
const errorGroup = {
occurrencesCount: 10,
error: {
error: {},
timestamp: {
us: 0
}
@ -85,6 +86,7 @@ describe('DetailView', () => {
timestamp: {
us: 0
},
error: {},
service: {},
user: {}
} as any
@ -109,6 +111,7 @@ describe('DetailView', () => {
timestamp: {
us: 0
},
error: {},
context: {}
} as any
};

View file

@ -19,7 +19,6 @@ import { Location } from 'history';
import React from 'react';
import styled from 'styled-components';
import { first } from 'lodash';
import { idx } from '@kbn/elastic-idx';
import { ErrorGroupAPIResponse } from '../../../../../server/lib/errors/get_error_group';
import { APMError } from '../../../../../typings/es_schemas/ui/APMError';
import { IUrlParams } from '../../../../context/UrlParamsContext/types';
@ -80,11 +79,12 @@ export function DetailView({ errorGroup, urlParams, location }: Props) {
const tabs = getTabs(error);
const currentTab = getCurrentTab(tabs, urlParams.detailTab);
const errorUrl =
idx(error, _ => _.error.page.url) || idx(error, _ => _.url.full);
const errorUrl = error.error.page?.url || error.url?.full;
const method = idx(error, _ => _.http.request.method);
const status = idx(error, _ => _.http.response.status_code);
const method = error.http?.request.method;
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
const status = error.http?.response?.status_code;
return (
<EuiPanel>
@ -188,9 +188,9 @@ function TabContent({
error: APMError;
currentTab: ErrorTab;
}) {
const codeLanguage = idx(error, _ => _.service.language.name);
const exceptions = idx(error, _ => _.error.exception) || [];
const logStackframes = idx(error, _ => _.error.log.stacktrace);
const codeLanguage = error.service.language?.name;
const exceptions = error.error.exception || [];
const logStackframes = error.error.log?.stacktrace;
switch (currentTab.key) {
case logStacktraceTab.key:

View file

@ -17,7 +17,6 @@ import theme from '@elastic/eui/dist/eui_theme_light.json';
import { i18n } from '@kbn/i18n';
import React, { Fragment } from 'react';
import styled from 'styled-components';
import { idx } from '@kbn/elastic-idx';
import { NOT_AVAILABLE_LABEL } from '../../../../common/i18n';
import { useFetcher } from '../../../hooks/useFetcher';
import { fontFamilyCode, fontSizes, px, units } from '../../../style/variables';
@ -115,14 +114,11 @@ export function ErrorGroupDetails() {
// If there are 0 occurrences, show only distribution chart w. empty message
const showDetails = errorGroupData.occurrencesCount !== 0;
const logMessage = idx(errorGroupData, _ => _.error.error.log.message);
const excMessage = idx(
errorGroupData,
_ => _.error.error.exception[0].message
);
const culprit = idx(errorGroupData, _ => _.error.error.culprit);
const logMessage = errorGroupData.error?.error.log?.message;
const excMessage = errorGroupData.error?.error.exception?.[0].message;
const culprit = errorGroupData.error?.error.culprit;
const isUnhandled =
idx(errorGroupData, _ => _.error.error.exception[0].handled) === false;
errorGroupData.error?.error.exception?.[0].handled === false;
return (
<div>

View file

@ -13,7 +13,6 @@ import {
import { i18n } from '@kbn/i18n';
import { memoize } from 'lodash';
import React, { Fragment } from 'react';
import { idx } from '@kbn/elastic-idx';
import { KibanaCoreContext } from '../../../../../../observability/public';
import { IUrlParams } from '../../../../context/UrlParamsContext/types';
import { LicenseContext } from '../../../../context/LicenseContext';
@ -149,9 +148,9 @@ export class ServiceIntegrations extends React.Component<Props, State> {
panels={[
{
id: 0,
items: this.getPanelItems(
idx(license, _ => _.features.ml.is_available)
)
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
items: this.getPanelItems(license.features.ml?.is_available)
}
]}
/>

View file

@ -19,7 +19,6 @@ import {
EuiText,
EuiSpacer
} from '@elastic/eui';
import { idx } from '@kbn/elastic-idx';
import React, { useState } from 'react';
import { i18n } from '@kbn/i18n';
import { isRight } from 'fp-ts/lib/Either';
@ -89,18 +88,21 @@ export function AddEditFlyout({
// config settings
const [sampleRate, setSampleRate] = useState<string>(
// TODO(TS-3.7-ESLINT)
(
idx(selectedConfig, _ => _.settings.transaction_sample_rate) ||
selectedConfig?.settings.transaction_sample_rate || // eslint-disable-line @typescript-eslint/camelcase
defaultSettings.TRANSACTION_SAMPLE_RATE
).toString()
);
const [captureBody, setCaptureBody] = useState<string>(
idx(selectedConfig, _ => _.settings.capture_body) ||
defaultSettings.CAPTURE_BODY
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
selectedConfig?.settings.capture_body || defaultSettings.CAPTURE_BODY
);
const [transactionMaxSpans, setTransactionMaxSpans] = useState<string>(
// TODO(TS-3.7-ESLINT)
(
idx(selectedConfig, _ => _.settings.transaction_max_spans) ||
selectedConfig?.settings.transaction_max_spans || // eslint-disable-line @typescript-eslint/camelcase
defaultSettings.TRANSACTION_MAX_SPANS
).toString()
);

View file

@ -9,7 +9,6 @@ import styled from 'styled-components';
import { EuiSpacer, EuiTitle } from '@elastic/eui';
import theme from '@elastic/eui/dist/eui_theme_light.json';
import { idx } from '@kbn/elastic-idx';
import {
borderRadius,
fontFamilyCode,
@ -34,7 +33,7 @@ interface Props {
}
export function HttpContext({ httpContext }: Props) {
const url = idx(httpContext, _ => _.url.original);
const url = httpContext?.url?.original;
if (!url) {
return null;

View file

@ -21,7 +21,6 @@ import {
import { i18n } from '@kbn/i18n';
import React, { Fragment } from 'react';
import styled from 'styled-components';
import { idx } from '@kbn/elastic-idx';
import { px, units } from '../../../../../../../style/variables';
import { Summary } from '../../../../../../shared/Summary';
import { TimestampTooltip } from '../../../../../../shared/TimestampTooltip';
@ -98,13 +97,15 @@ export function SpanFlyout({
}
const stackframes = span.span.stacktrace;
const codeLanguage = idx(parentTransaction, _ => _.service.language.name);
const dbContext = idx(span, _ => _.span.db);
const httpContext = idx(span, _ => _.span.http);
const codeLanguage = parentTransaction?.service.language?.name;
const dbContext = span.span.db;
const httpContext = span.span.http;
const spanTypes = getSpanTypes(span);
const spanHttpStatusCode = idx(httpContext, _ => _.response.status_code);
const spanHttpUrl = idx(httpContext, _ => _.url.original);
const spanHttpMethod = idx(httpContext, _ => _.method);
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
const spanHttpStatusCode = httpContext?.response.status_code;
const spanHttpUrl = httpContext?.url?.original;
const spanHttpMethod = httpContext?.method;
return (
<EuiPortal>

View file

@ -7,7 +7,6 @@
import { EuiCallOut, EuiHorizontalRule } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { idx } from '@kbn/elastic-idx';
import { Transaction } from '../../../../../../../../typings/es_schemas/ui/Transaction';
import { ElasticDocsLink } from '../../../../../../shared/Links/ElasticDocsLink';
@ -16,7 +15,7 @@ export function DroppedSpansWarning({
}: {
transactionDoc: Transaction;
}) {
const dropped = idx(transactionDoc, _ => _.transaction.span_count.dropped);
const dropped = transactionDoc.transaction.span_count?.dropped;
if (!dropped) {
return null;
}

View file

@ -15,7 +15,6 @@ import {
isEmpty,
first
} from 'lodash';
import { idx } from '@kbn/elastic-idx';
import { TraceAPIResponse } from '../../../../../../../../server/lib/traces/get_trace';
import { Span } from '../../../../../../../../typings/es_schemas/ui/Span';
import { Transaction } from '../../../../../../../../typings/es_schemas/ui/Transaction';
@ -224,7 +223,7 @@ function createGetTransactionById(itemsById: IWaterfallIndex) {
}
const item = itemsById[id];
const isTransaction = idx(item, _ => _.docType) === 'transaction';
const isTransaction = item?.docType === 'transaction';
if (isTransaction) {
return (item as IWaterfallItemTransaction).transaction;
}

View file

@ -7,7 +7,6 @@
import { EuiBasicTable } from '@elastic/eui';
import { sortByOrder } from 'lodash';
import React, { useMemo, useCallback, ReactNode } from 'react';
import { idx } from '@kbn/elastic-idx';
import { useUrlParams } from '../../../hooks/useUrlParams';
import { history } from '../../../utils/history';
import { fromQuery, toQuery } from '../Links/url_helpers';
@ -42,7 +41,7 @@ function UnoptimizedManagedTable<T>(props: Props<T>) {
columns,
initialPageIndex = 0,
initialPageSize = 10,
initialSortField = idx(props, _ => _.columns[0].field) || '',
initialSortField = props.columns[0]?.field || '',
initialSortDirection = 'asc',
hidePerPageOptions = true,
noItemsMessage,

View file

@ -22,7 +22,6 @@ import { registerLanguage } from 'react-syntax-highlighter/dist/light';
// @ts-ignore
import { xcode } from 'react-syntax-highlighter/dist/styles';
import styled from 'styled-components';
import { idx } from '@kbn/elastic-idx';
import { IStackframeWithLineContext } from '../../../../typings/es_schemas/raw/fields/Stackframe';
import { borderRadius, px, unit, units } from '../../../style/variables';
@ -106,13 +105,13 @@ const Code = styled.code`
function getStackframeLines(stackframe: IStackframeWithLineContext) {
const line = stackframe.line.context;
const preLines = idx(stackframe, _ => _.context.pre) || [];
const postLines = idx(stackframe, _ => _.context.post) || [];
const preLines = stackframe.context?.pre || [];
const postLines = stackframe.context?.post || [];
return [...preLines, line, ...postLines];
}
function getStartLineNumber(stackframe: IStackframeWithLineContext) {
const preLines = size(idx(stackframe, _ => _.context.pre) || []);
const preLines = size(stackframe.context?.pre || []);
return stackframe.line.number - preLines;
}
@ -125,7 +124,7 @@ interface Props {
export function Context({ stackframe, codeLanguage, isLibraryFrame }: Props) {
const lines = getStackframeLines(stackframe);
const startLineNumber = getStartLineNumber(stackframe);
const highlightedLineIndex = size(idx(stackframe, _ => _.context.pre) || []);
const highlightedLineIndex = size(stackframe.context?.pre || []);
const language = codeLanguage || 'javascript'; // TODO: Add support for more languages
return (

View file

@ -7,7 +7,6 @@
import theme from '@elastic/eui/dist/eui_theme_light.json';
import React, { Fragment } from 'react';
import styled from 'styled-components';
import { idx } from '@kbn/elastic-idx';
import { IStackframe } from '../../../../typings/es_schemas/raw/fields/Stackframe';
import { fontFamilyCode, fontSize, px, units } from '../../../style/variables';
@ -35,7 +34,7 @@ const FrameHeading: React.SFC<Props> = ({ stackframe, isLibraryFrame }) => {
const FileDetail = isLibraryFrame
? LibraryFrameFileDetail
: AppFrameFileDetail;
const lineNumber = idx(stackframe, _ => _.line.number) || 0;
const lineNumber = stackframe.line.number;
return (
<FileDetails>
<FileDetail>{stackframe.filename}</FileDetail> in{' '}

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { idx } from '@kbn/elastic-idx';
import { Transaction } from '../../../../typings/es_schemas/ui/Transaction';
import { Summary } from './';
import { TimestampTooltip } from '../TimestampTooltip';
@ -22,15 +21,17 @@ interface Props {
}
const getTransactionResultSummaryItem = (transaction: Transaction) => {
const result = idx(transaction, _ => _.transaction.result);
const result = transaction.transaction.result;
const isRumAgent = isRumAgentName(transaction.agent.name);
const url = isRumAgent
? idx(transaction, _ => _.transaction.page.url)
: idx(transaction, _ => _.url.full);
? transaction.transaction.page?.url
: transaction.url?.full;
if (url) {
const method = idx(transaction, _ => _.http.request.method);
const status = idx(transaction, _ => _.http.response.status_code);
const method = transaction.http?.request.method;
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
const status = transaction.http?.response?.status_code;
return <HttpInfoSummaryItem method={method} status={status} url={url} />;
}

View file

@ -17,7 +17,6 @@ import {
import url from 'url';
import { i18n } from '@kbn/i18n';
import React, { useState, FunctionComponent } from 'react';
import { idx } from '@kbn/elastic-idx';
import { pick } from 'lodash';
import { Transaction } from '../../../../typings/es_schemas/ui/Transaction';
import { DiscoverTransactionLink } from '../Links/DiscoverLinks/DiscoverTransactionLink';
@ -72,9 +71,9 @@ export const TransactionActionMenu: FunctionComponent<Props> = (
const { urlParams } = useUrlParams();
const hostName = idx(transaction, _ => _.host.hostname);
const podId = idx(transaction, _ => _.kubernetes.pod.uid);
const containerId = idx(transaction, _ => _.container.id);
const hostName = transaction.host?.hostname;
const podId = transaction.kubernetes?.pod.uid;
const containerId = transaction.container?.id;
const time = Math.round(transaction.timestamp.us / 1000);
const infraMetricsQuery = getInfraMetricsQuery(transaction);
@ -175,7 +174,7 @@ export const TransactionActionMenu: FunctionComponent<Props> = (
{
dateRangeStart: urlParams.rangeFrom,
dateRangeEnd: urlParams.rangeTo,
search: `url.domain:"${idx(transaction, t => t.url.domain)}"`
search: `url.domain:"${transaction.url?.domain}"`
},
(val: string) => !!val
)
@ -209,7 +208,7 @@ export const TransactionActionMenu: FunctionComponent<Props> = (
})}
</EuiLink>
),
condition: idx(transaction, _ => _.url.domain)
condition: transaction.url?.domain
}
]
.filter(({ condition }) => condition)

View file

@ -19,7 +19,6 @@ import { Location } from 'history';
import React, { Component } from 'react';
import { isEmpty, flatten } from 'lodash';
import styled from 'styled-components';
import { idx } from '@kbn/elastic-idx';
import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n';
import { Coordinate, TimeSeries } from '../../../../../typings/timeseries';
import { ITransactionChartData } from '../../../../selectors/chartSelectors';
@ -172,9 +171,9 @@ export class TransactionCharts extends Component<TransactionChartProps> {
</EuiFlexItem>
<LicenseContext.Consumer>
{license =>
this.renderMLHeader(
idx(license, _ => _.features.ml.is_available)
)
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
this.renderMLHeader(license.features.ml?.is_available)
}
</LicenseContext.Consumer>
</EuiFlexGroup>

View file

@ -5,7 +5,6 @@
*/
import React, { useContext, useEffect, useState, useMemo } from 'react';
import { idx } from '@kbn/elastic-idx';
import { i18n } from '@kbn/i18n';
import { IHttpFetchError } from 'src/core/public';
import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public';
@ -100,14 +99,13 @@ export function useFetcher<TReturn>(
defaultMessage: `Error`
})}
</h5>
{idx(err.response, r => r.statusText)} (
{idx(err.response, r => r.status)})
{err.response?.statusText} ({err.response?.status})
<h5>
{i18n.translate('xpack.apm.fetcher.error.url', {
defaultMessage: `URL`
})}
</h5>
{idx(err.response, r => r.url)}
{err.response?.url}
</div>
)
});

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import { ESFilter } from '../../../../typings/elasticsearch';
import {
ERROR_GROUP_ID,
@ -64,12 +63,12 @@ export async function getBuckets({
const resp = await client.search(params);
const buckets = (
idx(resp.aggregations, _ => _.distribution.buckets) || []
).map(bucket => ({
key: bucket.key,
count: bucket.doc_count
}));
const buckets = (resp.aggregations?.distribution.buckets || []).map(
bucket => ({
key: bucket.key,
count: bucket.doc_count
})
);
return {
noHits: resp.hits.total.value === 0,

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import {
ERROR_GROUP_ID,
PROCESSOR_EVENT,
@ -55,9 +54,9 @@ export async function getErrorGroup({
};
const resp = await client.search<APMError>(params);
const error = idx(resp, _ => _.hits.hits[0]._source);
const transactionId = idx(error, _ => _.transaction.id);
const traceId = idx(error, _ => _.trace.id);
const error = resp.hits.hits[0]?._source;
const transactionId = error?.transaction?.id;
const traceId = error?.trace?.id;
let transaction;
if (transactionId && traceId) {

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import {
ERROR_CULPRIT,
ERROR_EXC_HANDLED,
@ -106,23 +105,22 @@ export async function getErrorGroups({
// aggregations can be undefined when no matching indices are found.
// this is an exception rather than the rule so the ES type does not account for this.
const hits = (idx(resp, _ => _.aggregations.error_groups.buckets) || []).map(
bucket => {
const source = bucket.sample.hits.hits[0]._source;
const message =
idx(source, _ => _.error.log.message) ||
idx(source, _ => _.error.exception[0].message);
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
const hits = (resp.aggregations?.error_groups.buckets || []).map(bucket => {
const source = bucket.sample.hits.hits[0]._source;
const message =
source.error.log?.message || source.error.exception?.[0]?.message;
return {
message,
occurrenceCount: bucket.doc_count,
culprit: source.error.culprit,
groupId: source.error.grouping_key,
latestOccurrenceAt: source['@timestamp'],
handled: idx(source, _ => _.error.exception[0].handled)
};
}
);
return {
message,
occurrenceCount: bucket.doc_count,
culprit: source.error.culprit,
groupId: source.error.grouping_key,
latestOccurrenceAt: source['@timestamp'],
handled: source.error.exception?.[0].handled
};
});
return hits;
}

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import {
ERROR_LOG_LEVEL,
PROCESSOR_EVENT,
@ -55,7 +54,7 @@ export async function getTraceErrorsPerTransaction(
const resp = await client.search(params);
return (idx(resp.aggregations, _ => _.transactions.buckets) || []).reduce(
return (resp.aggregations?.transactions.buckets || []).reduce(
(acc, bucket) => ({
...acc,
[bucket.key]: bucket.doc_count

View file

@ -5,7 +5,6 @@
*/
import { Server } from 'hapi';
import { idx } from '@kbn/elastic-idx';
import { toElasticsearchQuery, fromKueryExpression } from '@kbn/es-query';
import { ESFilter } from '../../../../typings/elasticsearch';
import { ISavedObject } from '../../../../public/services/rest/savedObjects';
@ -31,8 +30,8 @@ export async function getKueryUiFilterES(
}
// lifted from src/legacy/ui/public/index_patterns/static_utils/index.js
export function getFromSavedObject(apmIndexPattern: ISavedObject) {
if (idx(apmIndexPattern, _ => _.attributes.fields) === undefined) {
export function getFromSavedObject(apmIndexPattern: ISavedObject | undefined) {
if (apmIndexPattern?.attributes.fields === undefined) {
return;
}

View file

@ -9,7 +9,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import { sum, round } from 'lodash';
import theme from '@elastic/eui/dist/eui_theme_light.json';
import { Setup } from '../../../../helpers/setup_request';
@ -113,7 +112,7 @@ export async function fetchAndTransformGcMetrics({
const response = await client.search(params);
const aggregations = idx(response, _ => _.aggregations);
const { aggregations } = response;
if (!aggregations) {
return {
@ -127,11 +126,12 @@ export async function fetchAndTransformGcMetrics({
const label = poolBucket.key as string;
const timeseriesData = poolBucket.over_time;
const data = (idx(timeseriesData, _ => _.buckets) || []).map(bucket => {
const data = timeseriesData.buckets.map(bucket => {
// derivative/value will be undefined for the first hit and if the `max` value is null
const bucketValue = bucket.value?.value;
const y =
'value' in bucket && bucket.value.value !== null
? round(bucket.value.value * (60 / bucketSize), 1)
bucketValue !== null && bucketValue !== undefined && bucket.value
? round(bucketValue * (60 / bucketSize), 1)
: null;
return {

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import theme from '@elastic/eui/dist/eui_theme_light.json';
import { idx } from '@kbn/elastic-idx';
import { Unionize, Overwrite } from 'utility-types';
import { ChartBase } from './types';
import {
@ -53,7 +52,7 @@ export function transformDataToMetricsChart(
chartBase: ChartBase
) {
const { aggregations, hits } = result;
const timeseriesData = idx(aggregations, _ => _.timeseriesData);
const timeseriesData = aggregations?.timeseriesData;
return {
title: chartBase.title,
@ -61,7 +60,7 @@ export function transformDataToMetricsChart(
yUnit: chartBase.yUnit,
noHits: hits.total.value === 0,
series: Object.keys(chartBase.series).map((seriesKey, i) => {
const overallValue = idx(aggregations, _ => _[seriesKey].value);
const overallValue = aggregations?.[seriesKey].value;
return {
title: chartBase.series[seriesKey].title,
@ -69,14 +68,15 @@ export function transformDataToMetricsChart(
type: chartBase.type,
color: chartBase.series[seriesKey].color || colors[i],
overallValue,
data: (idx(timeseriesData, _ => _.buckets) || []).map(bucket => {
const { value } = bucket[seriesKey] as { value: number | null };
const y = value === null || isNaN(value) ? null : value;
return {
x: bucket.key,
y
};
})
data:
timeseriesData?.buckets.map(bucket => {
const { value } = bucket[seriesKey] as { value: number | null };
const y = value === null || isNaN(value) ? null : value;
return {
x: bucket.key,
y
};
}) || []
};
})
};

View file

@ -3,7 +3,6 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import {
PROCESSOR_EVENT,
SERVICE_AGENT_NAME,
@ -44,8 +43,6 @@ export async function getServiceAgentName(serviceName: string, setup: Setup) {
};
const { aggregations } = await client.search(params);
const agentName = idx(aggregations, _ => _.agents.buckets[0].key) as
| string
| undefined;
const agentName = aggregations?.agents.buckets[0]?.key as string | undefined;
return { agentName };
}

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import { Setup } from '../helpers/setup_request';
import {
HOST_NAME,
@ -55,11 +54,8 @@ export async function getServiceNodeMetadata({
const response = await client.search(query);
return {
host:
idx(response, _ => _.aggregations.host.buckets[0].key) ||
NOT_AVAILABLE_LABEL,
host: response.aggregations?.host.buckets[0].key || NOT_AVAILABLE_LABEL,
containerId:
idx(response, _ => _.aggregations.containerId.buckets[0].key) ||
NOT_AVAILABLE_LABEL
response.aggregations?.containerId.buckets[0].key || NOT_AVAILABLE_LABEL
};
}

View file

@ -3,7 +3,6 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import {
PROCESSOR_EVENT,
SERVICE_NAME,
@ -40,7 +39,7 @@ export async function getServiceTransactionTypes(
};
const { aggregations } = await client.search(params);
const buckets = idx(aggregations, _ => _.types.buckets) || [];
const transactionTypes = buckets.map(bucket => bucket.key as string);
const transactionTypes =
aggregations?.types.buckets.map(bucket => bucket.key as string) || [];
return { transactionTypes };
}

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import { mergeProjection } from '../../../../common/projections/util/merge_projection';
import {
PROCESSOR_EVENT,
@ -53,16 +52,20 @@ export async function getServicesItems(setup: Setup) {
const resp = await client.search(params);
const aggs = resp.aggregations;
const serviceBuckets = idx(aggs, _ => _.services.buckets) || [];
const serviceBuckets = aggs?.services.buckets || [];
const items = serviceBuckets.map(bucket => {
const eventTypes = bucket.events.buckets;
const transactions = eventTypes.find(e => e.key === 'transaction');
const totalTransactions = idx(transactions, _ => _.doc_count) || 0;
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
const totalTransactions = transactions?.doc_count || 0;
const errors = eventTypes.find(e => e.key === 'error');
const totalErrors = idx(errors, _ => _.doc_count) || 0;
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
const totalErrors = errors?.doc_count || 0;
const deltaAsMinutes = (end - start) / 1000 / 60;
const transactionsPerMinute = totalTransactions / deltaAsMinutes;
@ -75,9 +78,7 @@ export async function getServicesItems(setup: Setup) {
return {
serviceName: bucket.key as string,
agentName: idx(bucket, _ => _.agents.buckets[0].key) as
| string
| undefined,
agentName: bucket.agents.buckets[0]?.key as string | undefined,
transactionsPerMinute,
errorsPerMinute,
avgResponseTime: bucket.avg.value,

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import { Setup } from '../../helpers/setup_request';
import {
PROCESSOR_EVENT,
@ -49,7 +48,9 @@ export async function getAgentNameByService({
};
const { aggregations } = await client.search(params);
const agentName = idx(aggregations, _ => _.agent_names.buckets[0].key) as
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
const agentName = aggregations?.agent_names.buckets[0].key as
| string
| undefined;
return { agentName };

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import { Setup } from '../../../helpers/setup_request';
import {
PROCESSOR_EVENT,
@ -57,7 +56,9 @@ export async function getAllEnvironments({
};
const resp = await client.search(params);
const buckets = idx(resp.aggregations, _ => _.environments.buckets) || [];
const environments = buckets.map(bucket => bucket.key as string);
const environments =
resp.aggregations?.environments.buckets.map(
bucket => bucket.key as string
) || [];
return [ALL_OPTION_VALUE, ...environments];
}

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import { Setup } from '../../../helpers/setup_request';
import {
SERVICE_NAME,
@ -43,6 +42,9 @@ export async function getExistingEnvironmentsForService({
};
const resp = await internalClient.search(params);
const buckets = idx(resp.aggregations, _ => _.environments.buckets) || [];
return buckets.map(bucket => bucket.key as string);
const existingEnvironments =
resp.aggregations?.environments.buckets.map(
bucket => bucket.key as string
) || [];
return existingEnvironments;
}

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import { Setup } from '../../helpers/setup_request';
import { PromiseReturnType } from '../../../../typings/common';
import {
@ -46,7 +45,9 @@ export async function getServiceNames({ setup }: { setup: Setup }) {
};
const resp = await client.search(params);
const buckets = idx(resp.aggregations, _ => _.services.buckets) || [];
const serviceNames = buckets.map(bucket => bucket.key as string).sort();
const serviceNames =
resp.aggregations?.services.buckets
.map(bucket => bucket.key as string)
.sort() || [];
return [ALL_OPTION_VALUE, ...serviceNames];
}

View file

@ -5,7 +5,6 @@
*/
import moment from 'moment';
import { idx } from '@kbn/elastic-idx';
import { ESResponse } from './fetcher';
function calculateRelativeImpacts(transactionGroups: ITransactionGroup[]) {
@ -54,7 +53,7 @@ export function transactionGroupsTransformer({
start: number;
end: number;
}): ITransactionGroup[] {
const buckets = idx(response, _ => _.aggregations.transactions.buckets) || [];
const buckets = response.aggregations?.transactions.buckets || [];
const duration = moment.duration(end - start);
const minutes = duration.asMinutes();
const transactionGroups = buckets.map(bucket =>

View file

@ -5,7 +5,6 @@
*/
import { flatten, sortByOrder, last } from 'lodash';
import { idx } from '@kbn/elastic-idx';
import {
SERVICE_NAME,
SPAN_SUBTYPE,
@ -149,7 +148,9 @@ export async function getTransactionBreakdown({
const kpiNames = kpis.map(kpi => kpi.name);
const bucketsByDate = idx(resp.aggregations, _ => _.by_date.buckets) || [];
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
const bucketsByDate = resp.aggregations?.by_date.buckets || [];
const timeseriesPerSubtype = bucketsByDate.reduce((prev, bucket) => {
const formattedValues = formatBucket(bucket);

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import { getMlIndex } from '../../../../../common/ml_job_constants';
import { Setup } from '../../../helpers/setup_request';
@ -50,7 +49,9 @@ export async function getMlBucketSize({
try {
const resp = await client.search<ESResponse, typeof params>(params);
return idx(resp, _ => _.hits.hits[0]._source.bucket_span) || 0;
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
return resp.hits.hits[0]?._source.bucket_span || 0;
} catch (err) {
const isHttpError = 'statusCode' in err;
if (isHttpError) {

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import { ESResponse } from './fetcher';
import { mlAnomalyResponse } from './mock-responses/mlAnomalyResponse';
import { anomalySeriesTransform, replaceFirstAndLastBucket } from './transform';
@ -291,10 +290,12 @@ function getESResponse(buckets: any): ESResponse {
buckets: buckets.map((bucket: any) => {
return {
...bucket,
lower: { value: idx(bucket, _ => _.lower.value) || null },
upper: { value: idx(bucket, _ => _.upper.value) || null },
lower: { value: bucket?.lower?.value || null },
upper: { value: bucket?.upper?.value || null },
anomaly_score: {
value: idx(bucket, _ => _.anomaly_score.value) || null
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
value: bucket?.anomaly_score?.value || null
}
};
})

View file

@ -5,7 +5,6 @@
*/
import { first, last } from 'lodash';
import { idx } from '@kbn/elastic-idx';
import { Coordinate, RectCoordinate } from '../../../../../typings/timeseries';
import { ESResponse } from './fetcher';
@ -32,9 +31,10 @@ export function anomalySeriesTransform(
bucketSize: number,
timeSeriesDates: number[]
) {
const buckets = (
idx(response, _ => _.aggregations.ml_avg_response_times.buckets) || []
).map(getBucket);
const buckets =
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
response.aggregations?.ml_avg_response_times.buckets.map(getBucket) || [];
const bucketSizeInMillis = Math.max(bucketSize, mlBucketSize) * 1000;

View file

@ -5,7 +5,6 @@
*/
import { isNumber, round, sortBy } from 'lodash';
import { idx } from '@kbn/elastic-idx';
import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n';
import { Coordinate } from '../../../../../typings/timeseries';
import { ESResponse } from './fetcher';
@ -20,14 +19,16 @@ export function timeseriesTransformer({
bucketSize: number;
}) {
const aggs = timeseriesResponse.aggregations;
const overallAvgDuration =
idx(aggs, _ => _.overall_avg_duration.value) || null;
const responseTimeBuckets = idx(aggs, _ => _.response_times.buckets);
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
const overallAvgDuration = aggs?.overall_avg_duration.value || null;
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
const responseTimeBuckets = aggs?.response_times.buckets || [];
const { avg, p95, p99 } = getResponseTime(responseTimeBuckets);
const transactionResultBuckets = idx(
aggs,
_ => _.transaction_results.buckets
);
// TODO(TS-3.7-ESLINT)
// eslint-disable-next-line @typescript-eslint/camelcase
const transactionResultBuckets = aggs?.transaction_results.buckets || [];
const tpmBuckets = getTpmBuckets(transactionResultBuckets, bucketSize);
return {

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import { PromiseReturnType } from '../../../../../typings/common';
import { Transaction } from '../../../../../typings/es_schemas/ui/Transaction';
import { bucketFetcher } from './fetcher';
@ -17,13 +16,14 @@ function getBucket(
DistributionBucketResponse
>['aggregations']['distribution']['buckets'][0]
) {
const sampleSource = idx(bucket, _ => _.sample.hits.hits[0]._source) as
const sampleSource = bucket.sample.hits.hits[0]?._source as
| Transaction
| undefined;
const isSampled = idx(sampleSource, _ => _.transaction.sampled);
const isSampled = sampleSource?.transaction.sampled;
const sample = {
traceId: idx(sampleSource, _ => _.trace.id),
transactionId: idx(sampleSource, _ => _.transaction.id)
traceId: sampleSource?.trace.id,
transactionId: sampleSource?.transaction.id
};
return {
@ -34,9 +34,8 @@ function getBucket(
}
export function bucketTransformer(response: DistributionBucketResponse) {
const buckets = (
idx(response.aggregations, _ => _.distribution.buckets) || []
).map(getBucket);
const buckets =
response.aggregations?.distribution.buckets.map(getBucket) || [];
return {
noHits: response.hits.total.value === 0,

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import {
PROCESSOR_EVENT,
TRACE_ID,
@ -40,5 +39,5 @@ export async function getTransaction(
};
const resp = await client.search<Transaction>(params);
return idx(resp, _ => _.hits.hits[0]._source);
return resp.hits.hits[0]?._source;
}

View file

@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { idx } from '@kbn/elastic-idx';
import {
PROCESSOR_EVENT,
SERVICE_ENVIRONMENT,
@ -55,7 +54,7 @@ export async function getEnvironments(setup: Setup, serviceName?: string) {
const resp = await client.search(params);
const aggs = resp.aggregations;
const environmentsBuckets = idx(aggs, _ => _.environments.buckets) || [];
const environmentsBuckets = aggs?.environments.buckets || [];
const environments = environmentsBuckets.map(
environmentBucket => environmentBucket.key as string