-
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] Dependencies table for backend inventory/detail views #106995
Conversation
Pinging @elastic/apm-ui (Team:apm) |
@@ -63,6 +54,15 @@ const apmRoutes = route([ | |||
}), | |||
]), | |||
}, | |||
{ |
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.
this puts the main UI routes after the redirect routes, to ensure those are matched first (they're more specific)
|
||
export type Node = ServiceNode | BackendNode; | ||
|
||
export interface ConnectionMetricItem { |
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.
Should we really call it Metric
? I remember there were a lot of discussions when I implemented the comparison feature that "metric" is already over-utilized.
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.
agree, will change to "stats"
metrics: { | ||
latency: { | ||
value: number | null; | ||
timeseries: Array<{ x: number; y: number | null }>; |
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.
Can you use Coordinate?
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.
sure thing
let to: Node = metricItem.to; | ||
|
||
to = destinationMap.get(to.backendName) ?? to; |
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.
let to: Node = metricItem.to; | |
to = destinationMap.get(to.backendName) ?? to; | |
const to: Node = destinationMap.get(to.backendName) ?? metricItem.to |
start, | ||
end, | ||
numBuckets, | ||
filter: [...environmentQuery(environment)], |
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.
filter: [...environmentQuery(environment)], | |
filter: environmentQuery(environment), |
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.
Actually, I don't mind this - I think it's more obviously an array this way, which I think it's a good thing.
return withApmSpan('get_destination_map', async () => { | ||
const { apmEventClient } = setup; | ||
|
||
const offsetInMs = getOffsetInMs(start, offset); |
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.
Have you considered returning startWithOffset
and endWithOffset
in getOffsetInMs
? I feel like everywhere we'll use it we'll have to subtract the offset from start and end.
const offsetInMs = getOffsetInMs(start, offset); | |
const {offsetInMs, startWithOffset, endWithOffset} = getOffsetInMs(start, offset); |
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.
👍 good idea
...filter, | ||
{ | ||
bool: { | ||
must_not: [{ term: { [AGENT_NAME]: 'rum-js' } }], |
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.
Maybe you could add a comment explaining why rum is being filtered out?
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.
good one, I'll probably extract it to some other file as it's used in multiple places.
let node: Node; | ||
if ('serviceName' in mergedDestination) { | ||
node = { | ||
serviceName: mergedDestination.serviceName, | ||
agentName: mergedDestination.agentName, | ||
environment: mergedDestination.environment, | ||
id: objectHash({ serviceName: mergedDestination.serviceName }), | ||
type: NodeType.service, | ||
}; | ||
} else { | ||
node = { | ||
backendName: mergedDestination.backendName, | ||
spanType: mergedDestination.spanType, | ||
spanSubtype: mergedDestination.spanSubtype, | ||
id: objectHash({ backendName: mergedDestination.backendName }), | ||
type: NodeType.backend, | ||
}; | ||
} |
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.
Can't you make node a const and use a ternary to set its value?
let node: Node; | |
if ('serviceName' in mergedDestination) { | |
node = { | |
serviceName: mergedDestination.serviceName, | |
agentName: mergedDestination.agentName, | |
environment: mergedDestination.environment, | |
id: objectHash({ serviceName: mergedDestination.serviceName }), | |
type: NodeType.service, | |
}; | |
} else { | |
node = { | |
backendName: mergedDestination.backendName, | |
spanType: mergedDestination.spanType, | |
spanSubtype: mergedDestination.spanSubtype, | |
id: objectHash({ backendName: mergedDestination.backendName }), | |
type: NodeType.backend, | |
}; | |
} | |
const node: Node = 'serviceName' in mergedDestination ? { | |
serviceName: mergedDestination.serviceName, | |
agentName: mergedDestination.agentName, | |
environment: mergedDestination.environment, | |
id: objectHash({ serviceName: mergedDestination.serviceName }), | |
type: NodeType.service, | |
} : | |
{ | |
backendName: mergedDestination.backendName, | |
spanType: mergedDestination.spanType, | |
spanSubtype: mergedDestination.spanSubtype, | |
id: objectHash({ backendName: mergedDestination.backendName }), | |
type: NodeType.backend, | |
} |
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.
I think the if/else is a little more readable here, due to the size of the object being created.
const offsetInMs = getOffsetInMs(start, offset); | ||
const startWithOffset = start - offsetInMs; | ||
const endWithOffset = end - offsetInMs; |
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.
This is what I meant.
...rangeQuery(startWithOffset, endWithOffset), | ||
{ | ||
bool: { | ||
must_not: [{ term: { [AGENT_NAME]: 'rum-js' } }], |
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.
a comment here too?
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.
Probably want to use RUM_AGENT_NAMES to include legacy and otel names.
connections: { | ||
composite: { | ||
size: 10000, | ||
sources: asMutableArray([ |
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.
Why do you need to use asMutableArray
here?
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.
We have to use as const
to create a tuple type, otherwise typescript will create a partial type of all element types, which is not recognised by the ES client's types, and the type of the response will be unknown. For the same reason we wrap it in asMutableArray
, as as const
will convert an Array
type to a ReadonlyArray
type.
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.
just some nits
export function BackendDetailDependenciesTable() { | ||
const { | ||
urlParams: { start, end, environment, comparisonEnabled, comparisonType }, | ||
} = useUrlParams(); |
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.
I know we still do magic with useUrlParams
and start/end, but can the rest fo them come out of the useApmParams
below?
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.
I think the others have slightly different types/defaults as well. I'm trying to err on the safe side here, and then hopefully we can refactor these separately.
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.
Do we have an issue to refactor this?
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.
We have #105914
text={name} | ||
content={ | ||
<EuiFlexGroup gutterSize="s" responsive={false}> | ||
<EuiFlexItem grow={false}>{icon}</EuiFlexItem> |
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.
We might have to resolve conflicts between this and my changes in https://github.com/elastic/kibana/pull/107089/files#diff-732775f9fc7d8281a24dd8fef294675022aec9fab6f68546ebf75088304c83ffR123-R142
💚 Build SucceededMetrics [docs]Module Count
Async chunks
History
To update your PR or re-run it, just comment with: |
import { AGENT_NAME } from '../../../common/elasticsearch_fieldnames'; | ||
import { RUM_AGENT_NAMES } from '../../../common/agent_name'; | ||
|
||
// exclude RUM exit spans, as they're high cardinality and don't usually |
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.
👍🏻
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.
LGTM. Nice work 👏🏻
💔 Backport failed
To backport manually run: |
Looks like this PR has a backport PR but it still hasn't been merged. Please merge it ASAP to keep the branches relatively in sync. |
Adds dependencies tables for backend inventory and detail views.
Still needs to happen, preferably in follow-up PRs: