Skip to content

Commit

Permalink
[APM] Adding comparison data to the dependencies table (elastic#97843)
Browse files Browse the repository at this point in the history
* adding comparison to dependencies api

* fixing client

* fixing client

* changing client
  • Loading branch information
cauemarcondes committed Apr 21, 2021
1 parent 654548f commit 9544ad0
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import {
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { keyBy } from 'lodash';
import React from 'react';
import { offsetPreviousPeriodCoordinates } from '../../../../../common/utils/offset_previous_period_coordinate';
import { Coordinate } from '../../../../../typings/timeseries';
import { getNextEnvironmentUrlParam } from '../../../../../common/environment_filter_values';
import {
asMillisecondDuration,
Expand All @@ -32,19 +35,76 @@ import { ServiceMapLink } from '../../../shared/Links/apm/ServiceMapLink';
import { ServiceOverviewLink } from '../../../shared/Links/apm/service_overview_link';
import { SpanIcon } from '../../../shared/span_icon';
import { TableFetchWrapper } from '../../../shared/table_fetch_wrapper';
import { getTimeRangeComparison } from '../../../shared/time_comparison/get_time_range_comparison';
import { TruncateWithTooltip } from '../../../shared/truncate_with_tooltip';
import { ServiceOverviewTableContainer } from '../service_overview_table_container';

interface Props {
serviceName: string;
}

type ServiceDependencyPeriods = ServiceDependencyItem & {
latency: { previousPeriodTimeseries?: Coordinate[] };
throughput: { previousPeriodTimeseries?: Coordinate[] };
errorRate: { previousPeriodTimeseries?: Coordinate[] };
previousPeriodImpact?: number;
};

function mergeCurrentAndPreviousPeriods({
currentPeriod = [],
previousPeriod = [],
}: {
currentPeriod?: ServiceDependencyItem[];
previousPeriod?: ServiceDependencyItem[];
}): ServiceDependencyPeriods[] {
const previousPeriodMap = keyBy(previousPeriod, 'name');

return currentPeriod.map((currentDependency) => {
const previousDependency = previousPeriodMap[currentDependency.name];
if (!previousDependency) {
return currentDependency;
}
return {
...currentDependency,
latency: {
...currentDependency.latency,
previousPeriodTimeseries: offsetPreviousPeriodCoordinates({
currentPeriodTimeseries: currentDependency.latency.timeseries,
previousPeriodTimeseries: previousDependency.latency?.timeseries,
}),
},
throughput: {
...currentDependency.throughput,
previousPeriodTimeseries: offsetPreviousPeriodCoordinates({
currentPeriodTimeseries: currentDependency.throughput.timeseries,
previousPeriodTimeseries: previousDependency.throughput?.timeseries,
}),
},
errorRate: {
...currentDependency.errorRate,
previousPeriodTimeseries: offsetPreviousPeriodCoordinates({
currentPeriodTimeseries: currentDependency.errorRate.timeseries,
previousPeriodTimeseries: previousDependency.errorRate?.timeseries,
}),
},
previousPeriodImpact: previousDependency.impact,
};
});
}

export function ServiceOverviewDependenciesTable({ serviceName }: Props) {
const {
urlParams: { start, end, environment },
urlParams: { start, end, environment, comparisonEnabled, comparisonType },
} = useUrlParams();

const columns: Array<EuiBasicTableColumn<ServiceDependencyItem>> = [
const { comparisonStart, comparisonEnd } = getTimeRangeComparison({
start,
end,
comparisonEnabled,
comparisonType,
});

const columns: Array<EuiBasicTableColumn<ServiceDependencyPeriods>> = [
{
field: 'name',
name: i18n.translate(
Expand Down Expand Up @@ -102,6 +162,9 @@ export function ServiceOverviewDependenciesTable({ serviceName }: Props) {
<SparkPlot
color="euiColorVis1"
series={latency.timeseries}
comparisonSeries={
comparisonEnabled ? latency.previousPeriodTimeseries : undefined
}
valueLabel={asMillisecondDuration(latency.value)}
/>
);
Expand All @@ -121,6 +184,11 @@ export function ServiceOverviewDependenciesTable({ serviceName }: Props) {
compact
color="euiColorVis0"
series={throughput.timeseries}
comparisonSeries={
comparisonEnabled
? throughput.previousPeriodTimeseries
: undefined
}
valueLabel={asTransactionRate(throughput.value)}
/>
);
Expand All @@ -142,6 +210,9 @@ export function ServiceOverviewDependenciesTable({ serviceName }: Props) {
compact
color="euiColorVis7"
series={errorRate.timeseries}
comparisonSeries={
comparisonEnabled ? errorRate.previousPeriodTimeseries : undefined
}
valueLabel={asPercent(errorRate.value, 1)}
/>
);
Expand All @@ -157,13 +228,28 @@ export function ServiceOverviewDependenciesTable({ serviceName }: Props) {
}
),
width: px(unit * 5),
render: (_, { impact }) => {
return <ImpactBar size="m" value={impact} />;
render: (_, { impact, previousPeriodImpact }) => {
return (
<EuiFlexGroup gutterSize="xs" direction="column">
<EuiFlexItem>
<ImpactBar value={impact} size="m" />
</EuiFlexItem>
{comparisonEnabled && previousPeriodImpact !== undefined && (
<EuiFlexItem>
<ImpactBar
value={previousPeriodImpact}
size="s"
color="subdued"
/>
</EuiFlexItem>
)}
</EuiFlexGroup>
);
},
sortable: true,
},
];

// Fetches current period dependencies
const { data, status } = useFetcher(
(callApmApi) => {
if (!start || !end) {
Expand All @@ -173,22 +259,41 @@ export function ServiceOverviewDependenciesTable({ serviceName }: Props) {
return callApmApi({
endpoint: 'GET /api/apm/services/{serviceName}/dependencies',
params: {
path: {
serviceName,
},
path: { serviceName },
query: { start, end, environment, numBuckets: 20 },
},
});
},
[start, end, serviceName, environment]
);

// Fetches previous period dependencies
const { data: previousPeriodData, status: previousPeriodStatus } = useFetcher(
(callApmApi) => {
if (!comparisonStart || !comparisonEnd) {
return;
}

return callApmApi({
endpoint: 'GET /api/apm/services/{serviceName}/dependencies',
params: {
path: { serviceName },
query: {
start,
end,
start: comparisonStart,
end: comparisonEnd,
environment,
numBuckets: 20,
},
},
});
},
[start, end, serviceName, environment]
[comparisonStart, comparisonEnd, serviceName, environment]
);

const serviceDependencies = data?.serviceDependencies ?? [];
const serviceDependencies = mergeCurrentAndPreviousPeriods({
currentPeriod: data?.serviceDependencies,
previousPeriod: previousPeriodData?.serviceDependencies,
});

// need top-level sortable fields for the managed table
const items = serviceDependencies.map((item) => ({
Expand Down Expand Up @@ -238,7 +343,10 @@ export function ServiceOverviewDependenciesTable({ serviceName }: Props) {
columns={columns}
items={items}
allowNeutralSort={false}
loading={status === FETCH_STATUS.LOADING}
loading={
status === FETCH_STATUS.LOADING ||
previousPeriodStatus === FETCH_STATUS.LOADING
}
pagination={{
initialPageSize: 5,
pageSizeOptions: [5],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export function getColumns({
<EuiFlexItem>
<ImpactBar value={currentImpact} size="m" />
</EuiFlexItem>
{comparisonEnabled && previousImpact && (
{comparisonEnabled && previousImpact !== undefined && (
<EuiFlexItem>
<ImpactBar value={previousImpact} size="s" color="subdued" />
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/
import { keyBy } from 'lodash';
import { offsetPreviousPeriodCoordinates } from '../../../../common/utils/offset_previous_period_coordinate';
import { Coordinate } from '../../../../typings/timeseries';
import {
ERROR_GROUP_ID,
Expand All @@ -17,7 +18,6 @@ import {
rangeQuery,
kqlQuery,
} from '../../../../server/utils/queries';
import { offsetPreviousPeriodCoordinates } from '../../../utils/offset_previous_period_coordinate';
import { withApmSpan } from '../../../utils/with_apm_span';
import { getBucketSize } from '../../helpers/get_bucket_size';
import { Setup, SetupTimeRange } from '../../helpers/setup_request';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
*/

import { keyBy } from 'lodash';
import { offsetPreviousPeriodCoordinates } from '../../../../common/utils/offset_previous_period_coordinate';
import { Coordinate } from '../../../../typings/timeseries';
import { LatencyAggregationType } from '../../../../common/latency_aggregation_types';
import { joinByKey } from '../../../../common/utils/join_by_key';
import { offsetPreviousPeriodCoordinates } from '../../../utils/offset_previous_period_coordinate';
import { withApmSpan } from '../../../utils/with_apm_span';
import { Setup, SetupTimeRange } from '../../helpers/setup_request';
import { getServiceInstancesSystemMetricStatistics } from './get_service_instances_system_metric_statistics';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import { keyBy } from 'lodash';
import { offsetPreviousPeriodCoordinates } from '../../../common/utils/offset_previous_period_coordinate';
import {
EVENT_OUTCOME,
SERVICE_NAME,
Expand All @@ -20,7 +21,6 @@ import {
kqlQuery,
} from '../../../server/utils/queries';
import { Coordinate } from '../../../typings/timeseries';
import { offsetPreviousPeriodCoordinates } from '../../utils/offset_previous_period_coordinate';
import { withApmSpan } from '../../utils/with_apm_span';
import {
getDocumentTypeFilterForAggregatedTransactions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/

import { offsetPreviousPeriodCoordinates } from '../../../common/utils/offset_previous_period_coordinate';
import { Coordinate } from '../../../typings/timeseries';

import {
Expand All @@ -31,7 +32,6 @@ import {
getTransactionErrorRateTimeSeries,
} from '../helpers/transaction_error_rate';
import { withApmSpan } from '../../utils/with_apm_span';
import { offsetPreviousPeriodCoordinates } from '../../utils/offset_previous_period_coordinate';

export async function getErrorRate({
environment,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/

import { offsetPreviousPeriodCoordinates } from '../../../../common/utils/offset_previous_period_coordinate';
import { ESFilter } from '../../../../../../../typings/elasticsearch';
import { PromiseReturnType } from '../../../../../observability/typings/common';
import {
Expand All @@ -25,7 +26,6 @@ import {
} from '../../../lib/helpers/aggregated_transactions';
import { getBucketSize } from '../../../lib/helpers/get_bucket_size';
import { Setup, SetupTimeRange } from '../../../lib/helpers/setup_request';
import { offsetPreviousPeriodCoordinates } from '../../../utils/offset_previous_period_coordinate';
import { withApmSpan } from '../../../utils/with_apm_span';
import {
getLatencyAggregation,
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/apm/server/routes/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import { getServiceTransactionTypes } from '../lib/services/get_service_transact
import { getThroughput } from '../lib/services/get_throughput';
import { getServiceProfilingStatistics } from '../lib/services/profiling/get_service_profiling_statistics';
import { getServiceProfilingTimeline } from '../lib/services/profiling/get_service_profiling_timeline';
import { offsetPreviousPeriodCoordinates } from '../utils/offset_previous_period_coordinate';
import { withApmSpan } from '../utils/with_apm_span';
import { createApmServerRoute } from './create_apm_server_route';
import { createApmServerRouteRepository } from './create_apm_server_route_repository';
Expand All @@ -40,6 +39,7 @@ import {
kueryRt,
rangeRt,
} from './default_api_types';
import { offsetPreviousPeriodCoordinates } from '../../common/utils/offset_previous_period_coordinate';

const servicesRoute = createApmServerRoute({
endpoint: 'GET /api/apm/services',
Expand Down

0 comments on commit 9544ad0

Please sign in to comment.