-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[APM] Optimize services overview #69648
Changes from all commits
43f55a5
da21e45
f774b47
068c170
0546489
03e40a7
5e14e42
b180c1b
83326f2
1c1d526
a645758
daa5abb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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; | ||
}; |
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, | ||
}, | ||
]); | ||
}); | ||
}); |
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' | ||||||
); | ||||||
*/ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the description and tests ❤️ |
||||||
|
||||||
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) => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I find it useful to distinguish between the accumulator and the items that are being iterated.
Suggested change
|
||||||
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; | ||||||
}, []); | ||||||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will this be changed by your PR for new client?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep! there will no longer be a need for
noEvents
.