Skip to content

Commit

Permalink
[APM] Remove rate aggregations (#114187) (#115084)
Browse files Browse the repository at this point in the history
* fixing throughput chart api

* change backends

* adding intervalString to the observability callback functions

* fixing transaction group detailed stats

* fixing tests

* fixing test

* fixing obs tests

* fixing tests

* adding tests

* fixing ci

* using data generator

* changing name

* fixing i18n

* updating opbs test to use data generator

* fixing api tests

* fixing tests

* using data generator to run the tests

* fixing tests

* fixing test

Co-authored-by: Cauê Marcondes <[email protected]>
  • Loading branch information
kibanamachine and cauemarcondes authored Oct 14, 2021
1 parent 328b69d commit 2d28371
Show file tree
Hide file tree
Showing 53 changed files with 2,675 additions and 2,342 deletions.
9 changes: 3 additions & 6 deletions x-pack/plugins/apm/common/utils/formatters/duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import { asDecimalOrInteger, asInteger, asDecimal } from './formatters';
import { TimeUnit } from './datetime';
import { Maybe } from '../../../typings/common';
import { isFiniteNumber } from '../is_finite_number';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import type { ThroughputUnit } from '../../../server/lib/helpers/calculate_throughput';

interface FormatterOptions {
defaultValue?: string;
Expand Down Expand Up @@ -182,13 +180,12 @@ export function asTransactionRate(value: Maybe<number>) {
});
}

export function asExactTransactionRate(value: number, unit: ThroughputUnit) {
export function asExactTransactionRate(value: number) {
return i18n.translate('xpack.apm.exactTransactionRateLabel', {
defaultMessage: `{value} { unit, select, minute {tpm} other {tps} }`,
values: { value: asDecimalOrInteger(value), unit },
defaultMessage: `{value} tpm`,
values: { value: asDecimalOrInteger(value) },
});
}

/**
* Converts value and returns it formatted - 00 unit
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,29 +135,16 @@ export function ServiceOverviewThroughputChart({
'xpack.apm.serviceOverview.throughtputChartTitle',
{ defaultMessage: 'Throughput' }
)}
{data.throughputUnit === 'second'
? i18n.translate(
'xpack.apm.serviceOverview.throughtputPerSecondChartTitle',
{ defaultMessage: ' (per second)' }
)
: ''}
</h2>
</EuiTitle>
</EuiFlexItem>

<EuiFlexItem grow={false}>
<EuiIconTip
content={
data.throughputUnit === 'minute'
? i18n.translate('xpack.apm.serviceOverview.tpmHelp', {
defaultMessage:
'Throughput is measured in transactions per minute (tpm)',
})
: i18n.translate('xpack.apm.serviceOverview.tpsHelp', {
defaultMessage:
'Throughput is measured in transactions per second (tps)',
})
}
content={i18n.translate('xpack.apm.serviceOverview.tpmHelp', {
defaultMessage:
'Throughput is measured in transactions per minute (tpm)',
})}
position="right"
/>
</EuiFlexItem>
Expand All @@ -169,7 +156,7 @@ export function ServiceOverviewThroughputChart({
showAnnotations={false}
fetchStatus={status}
timeseries={timeseries}
yLabelFormat={(y) => asExactTransactionRate(y, data.throughputUnit)}
yLabelFormat={asExactTransactionRate}
customTheme={comparisonChartTheme}
/>
</EuiPanel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ describe('Observability dashboard data', () => {
start: 'now-15m',
end: 'now',
},
bucketSize: '600s',
intervalString: '600s',
bucketSize: 600,
};
afterEach(() => {
callApmApiMock.mockClear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const fetchObservabilityOverviewPageData = async ({
absoluteTime,
relativeTime,
bucketSize,
intervalString,
}: FetchDataParams): Promise<ApmFetchDataResponse> => {
const data = await callApmApi({
endpoint: 'GET /internal/apm/observability_overview',
Expand All @@ -24,6 +25,7 @@ export const fetchObservabilityOverviewPageData = async ({
start: new Date(absoluteTime.start).toISOString(),
end: new Date(absoluteTime.end).toISOString(),
bucketSize,
intervalString,
},
},
});
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/apm/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const configSchema = schema.object({
schema.literal(SearchAggregatedTransactionSetting.always),
schema.literal(SearchAggregatedTransactionSetting.never),
],
{ defaultValue: SearchAggregatedTransactionSetting.auto }
{ defaultValue: SearchAggregatedTransactionSetting.never }
),
telemetryCollectionEnabled: schema.boolean({ defaultValue: true }),
metricsInterval: schema.number({ defaultValue: 30 }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import { environmentQuery } from '../../../common/utils/environment_query';
import { kqlQuery, rangeQuery } from '../../../../observability/server';
import { ProcessorEvent } from '../../../common/processor_event';
import { Setup } from '../helpers/setup_request';
import { getMetricsDateHistogramParams } from '../helpers/metrics';
import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms';
import { getBucketSize } from '../helpers/get_bucket_size';
import { calculateThroughputWithInterval } from '../helpers/calculate_throughput';

export async function getThroughputChartsForBackend({
backendName,
Expand All @@ -41,6 +42,12 @@ export async function getThroughputChartsForBackend({
offset,
});

const { intervalString, bucketSize } = getBucketSize({
start: startWithOffset,
end: endWithOffset,
minBucketSize: 60,
});

const response = await apmEventClient.search('get_throughput_for_backend', {
apm: {
events: [ProcessorEvent.metric],
Expand All @@ -59,16 +66,16 @@ export async function getThroughputChartsForBackend({
},
aggs: {
timeseries: {
date_histogram: getMetricsDateHistogramParams({
start: startWithOffset,
end: endWithOffset,
metricsInterval: 60,
}),
date_histogram: {
field: '@timestamp',
fixed_interval: intervalString,
min_doc_count: 0,
extended_bounds: { min: startWithOffset, max: endWithOffset },
},
aggs: {
throughput: {
rate: {
spanDestinationLatencySum: {
sum: {
field: SPAN_DESTINATION_SERVICE_RESPONSE_TIME_COUNT,
unit: 'minute',
},
},
},
Expand All @@ -81,7 +88,10 @@ export async function getThroughputChartsForBackend({
response.aggregations?.timeseries.buckets.map((bucket) => {
return {
x: bucket.key + offsetInMs,
y: bucket.throughput.value,
y: calculateThroughputWithInterval({
bucketSize,
value: bucket.spanDestinationLatencySum.value || 0,
}),
};
}) ?? []
);
Expand Down
27 changes: 27 additions & 0 deletions x-pack/plugins/apm/server/lib/helpers/calculate_throughput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
* 2.0.
*/

/**
* @deprecated use calculateThroughputWithRange instead
*/
export function calculateThroughput({
start,
end,
Expand All @@ -18,6 +21,30 @@ export function calculateThroughput({
return value / durationAsMinutes;
}

export function calculateThroughputWithRange({
start,
end,
value,
}: {
start: number;
end: number;
value: number;
}) {
const durationAsMinutes = (end - start) / 1000 / 60;
return value / durationAsMinutes;
}

export function calculateThroughputWithInterval({
bucketSize,
value,
}: {
bucketSize: number;
value: number;
}) {
const durationAsMinutes = bucketSize / 60;
return value / durationAsMinutes;
}

export type ThroughputUnit = 'minute' | 'second';
export function getThroughputUnit(bucketSize: number): ThroughputUnit {
return bucketSize >= 60 ? 'minute' : 'second';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,22 @@ import {
getDocumentTypeFilterForAggregatedTransactions,
getProcessorEventForAggregatedTransactions,
} from '../helpers/aggregated_transactions';
import { calculateThroughput } from '../helpers/calculate_throughput';
import {
calculateThroughputWithInterval,
calculateThroughputWithRange,
} from '../helpers/calculate_throughput';

export async function getTransactionsPerMinute({
setup,
bucketSize,
searchAggregatedTransactions,
start,
end,
intervalString,
}: {
setup: Setup;
bucketSize: string;
bucketSize: number;
intervalString: string;
searchAggregatedTransactions: boolean;
start: number;
end: number;
Expand Down Expand Up @@ -64,12 +69,9 @@ export async function getTransactionsPerMinute({
timeseries: {
date_histogram: {
field: '@timestamp',
fixed_interval: bucketSize,
fixed_interval: intervalString,
min_doc_count: 0,
},
aggs: {
throughput: { rate: { unit: 'minute' as const } },
},
},
},
},
Expand All @@ -90,15 +92,18 @@ export async function getTransactionsPerMinute({
) || aggregations.transactionType.buckets[0];

return {
value: calculateThroughput({
value: calculateThroughputWithRange({
start,
end,
value: topTransactionTypeBucket?.doc_count || 0,
}),
timeseries:
topTransactionTypeBucket?.timeseries.buckets.map((bucket) => ({
x: bucket.key,
y: bucket.throughput.value,
y: calculateThroughputWithInterval({
bucketSize,
value: bucket.doc_count,
}),
})) || [],
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,6 @@ export async function getServiceTransactionGroupDetailedStatistics({
},
},
aggs: {
throughput_rate: {
rate: {
unit: 'minute',
},
},
...getLatencyAggregation(latencyAggregationType, field),
[EVENT_OUTCOME]: {
terms: {
Expand Down Expand Up @@ -160,7 +155,7 @@ export async function getServiceTransactionGroupDetailedStatistics({
}));
const throughput = bucket.timeseries.buckets.map((timeseriesBucket) => ({
x: timeseriesBucket.key,
y: timeseriesBucket.throughput_rate.value,
y: timeseriesBucket.doc_count, // sparklines only shows trend (no axis)
}));
const errorRate = bucket.timeseries.buckets.map((timeseriesBucket) => ({
x: timeseriesBucket.key,
Expand Down
17 changes: 7 additions & 10 deletions x-pack/plugins/apm/server/lib/services/get_throughput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
getProcessorEventForAggregatedTransactions,
} from '../helpers/aggregated_transactions';
import { Setup } from '../helpers/setup_request';
import { calculateThroughputWithInterval } from '../helpers/calculate_throughput';

interface Options {
environment: string;
Expand All @@ -30,7 +31,7 @@ interface Options {
start: number;
end: number;
intervalString: string;
throughputUnit: 'minute' | 'second';
bucketSize: number;
}

export async function getThroughput({
Expand All @@ -44,7 +45,7 @@ export async function getThroughput({
start,
end,
intervalString,
throughputUnit,
bucketSize,
}: Options) {
const { apmEventClient } = setup;

Expand Down Expand Up @@ -86,13 +87,6 @@ export async function getThroughput({
min_doc_count: 0,
extended_bounds: { min: start, max: end },
},
aggs: {
throughput: {
rate: {
unit: throughputUnit,
},
},
},
},
},
},
Expand All @@ -107,7 +101,10 @@ export async function getThroughput({
response.aggregations?.timeseries.buckets.map((bucket) => {
return {
x: bucket.key,
y: bucket.throughput.value,
y: calculateThroughputWithInterval({
bucketSize,
value: bucket.doc_count,
}),
};
}) ?? []
);
Expand Down
9 changes: 7 additions & 2 deletions x-pack/plugins/apm/server/routes/observability_overview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import * as t from 'io-ts';
import { toNumberRt } from '@kbn/io-ts-utils';
import { setupRequest } from '../lib/helpers/setup_request';
import { getServiceCount } from '../lib/observability_overview/get_service_count';
import { getTransactionsPerMinute } from '../lib/observability_overview/get_transactions_per_minute';
Expand All @@ -28,12 +29,15 @@ const observabilityOverviewHasDataRoute = createApmServerRoute({
const observabilityOverviewRoute = createApmServerRoute({
endpoint: 'GET /internal/apm/observability_overview',
params: t.type({
query: t.intersection([rangeRt, t.type({ bucketSize: t.string })]),
query: t.intersection([
rangeRt,
t.type({ bucketSize: toNumberRt, intervalString: t.string }),
]),
}),
options: { tags: ['access:apm'] },
handler: async (resources) => {
const setup = await setupRequest(resources);
const { bucketSize, start, end } = resources.params.query;
const { bucketSize, intervalString, start, end } = resources.params.query;

const searchAggregatedTransactions = await getSearchAggregatedTransactions({
apmEventClient: setup.apmEventClient,
Expand All @@ -57,6 +61,7 @@ const observabilityOverviewRoute = createApmServerRoute({
searchAggregatedTransactions,
start,
end,
intervalString,
}),
]);
return { serviceCount, transactionPerMinute };
Expand Down
Loading

0 comments on commit 2d28371

Please sign in to comment.