Skip to content

Commit

Permalink
[APM] Optimize services overview (#69648) (#70931)
Browse files Browse the repository at this point in the history
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
dgieselaar and elasticmachine committed Jul 7, 2020
1 parent 9d96334 commit ccc3159
Show file tree
Hide file tree
Showing 9 changed files with 756 additions and 157 deletions.
28 changes: 20 additions & 8 deletions x-pack/plugins/apm/common/projections/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,37 @@ import { rangeFilter } from '../utils/range_filter';

export function getServicesProjection({
setup,
noEvents,
}: {
setup: Setup & SetupTimeRange & SetupUIFilters;
noEvents?: boolean;
}) {
const { start, end, uiFiltersES, indices } = setup;

return {
index: [
indices['apm_oss.metricsIndices'],
indices['apm_oss.errorIndices'],
indices['apm_oss.transactionIndices'],
],
...(noEvents
? {}
: {
index: [
indices['apm_oss.metricsIndices'],
indices['apm_oss.errorIndices'],
indices['apm_oss.transactionIndices'],
],
}),
body: {
size: 0,
query: {
bool: {
filter: [
{
terms: { [PROCESSOR_EVENT]: ['transaction', 'error', 'metric'] },
},
...(noEvents
? []
: [
{
terms: {
[PROCESSOR_EVENT]: ['transaction', 'error', 'metric'],
},
},
]),
{ range: rangeFilter(start, end) },
...uiFiltersES,
],
Expand Down
14 changes: 14 additions & 0 deletions x-pack/plugins/apm/common/utils/array_union_to_callable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { ValuesType } from 'utility-types';

// work around a TypeScript limitation described in https://stackoverflow.com/posts/49511416

export const arrayUnionToCallable = <T extends any[]>(
array: T
): Array<ValuesType<T>> => {
return array;
};
104 changes: 104 additions & 0 deletions x-pack/plugins/apm/common/utils/join_by_key/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { joinByKey } from './';

describe('joinByKey', () => {
it('joins by a string key', () => {
const joined = joinByKey(
[
{
serviceName: 'opbeans-node',
avg: 10,
},
{
serviceName: 'opbeans-node',
count: 12,
},
{
serviceName: 'opbeans-java',
avg: 11,
},
{
serviceName: 'opbeans-java',
p95: 18,
},
],
'serviceName'
);

expect(joined.length).toBe(2);

expect(joined).toEqual([
{
serviceName: 'opbeans-node',
avg: 10,
count: 12,
},
{
serviceName: 'opbeans-java',
avg: 11,
p95: 18,
},
]);
});

it('joins by a record key', () => {
const joined = joinByKey(
[
{
key: {
serviceName: 'opbeans-node',
transactionName: '/api/opbeans-node',
},
avg: 10,
},
{
key: {
serviceName: 'opbeans-node',
transactionName: '/api/opbeans-node',
},
count: 12,
},
{
key: {
serviceName: 'opbeans-java',
transactionName: '/api/opbeans-java',
},
avg: 11,
},
{
key: {
serviceName: 'opbeans-java',
transactionName: '/api/opbeans-java',
},
p95: 18,
},
],
'key'
);

expect(joined.length).toBe(2);

expect(joined).toEqual([
{
key: {
serviceName: 'opbeans-node',
transactionName: '/api/opbeans-node',
},
avg: 10,
count: 12,
},
{
key: {
serviceName: 'opbeans-java',
transactionName: '/api/opbeans-java',
},
avg: 11,
p95: 18,
},
]);
});
});
48 changes: 48 additions & 0 deletions x-pack/plugins/apm/common/utils/join_by_key/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { UnionToIntersection, ValuesType } from 'utility-types';
import { isEqual } from 'lodash';

/**
* Joins a list of records by a given key. Key can be any type of value, from
* strings to plain objects, as long as it is present in all records. `isEqual`
* is used for comparing keys.
*
* UnionToIntersection is needed to get all keys of union types, see below for
* example.
*
const agentNames = [{ serviceName: '', agentName: '' }];
const transactionRates = [{ serviceName: '', transactionsPerMinute: 1 }];
const flattened = joinByKey(
[...agentNames, ...transactionRates],
'serviceName'
);
*/

type JoinedReturnType<
T extends Record<string, any>,
U extends UnionToIntersection<T>,
V extends keyof T & keyof U
> = Array<Partial<U> & Record<V, U[V]>>;

export function joinByKey<
T extends Record<string, any>,
U extends UnionToIntersection<T>,
V extends keyof T & keyof U
>(items: T[], key: V): JoinedReturnType<T, U, V> {
return items.reduce<JoinedReturnType<T, U, V>>((prev, current) => {
let item = prev.find((prevItem) => isEqual(prevItem[key], current[key]));

if (!item) {
item = { ...current } as ValuesType<JoinedReturnType<T, U, V>>;
prev.push(item);
} else {
Object.assign(item, current);
}

return prev;
}, []);
}
21 changes: 0 additions & 21 deletions x-pack/plugins/apm/common/utils/left_join.ts

This file was deleted.

Loading

0 comments on commit ccc3159

Please sign in to comment.