-
Notifications
You must be signed in to change notification settings - Fork 8.6k
[APM] Alert counts in Service groups #144484
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
Changes from all commits
31cf82d
4afd7dd
63a2e88
a5c5799
96fd200
d539d87
d9bb604
a88c08b
d190927
c849a3d
31b728b
a1f559e
ea5742b
2dbee54
87a810e
1c59715
f77850b
c3ed19d
59301eb
7405cfc
d5ce90e
6e774c4
c7f64ff
011d8c6
71a92da
17ec246
0085041
ac36646
9a525f5
2de8ac1
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 |
|---|---|---|
|
|
@@ -6,42 +6,67 @@ | |
| */ | ||
| import { | ||
| EuiAvatar, | ||
| EuiBadge, | ||
| EuiCard, | ||
| EuiCardProps, | ||
| EuiFlexGroup, | ||
| EuiFlexItem, | ||
| EuiText, | ||
| EuiSpacer, | ||
| } from '@elastic/eui'; | ||
| import { i18n } from '@kbn/i18n'; | ||
| import React from 'react'; | ||
| import { | ||
| ServiceGroup, | ||
| SERVICE_GROUP_COLOR_DEFAULT, | ||
| } from '../../../../../common/service_groups'; | ||
| import { useObservabilityActiveAlertsHref } from '../../../shared/links/kibana'; | ||
|
|
||
| interface Props { | ||
| serviceGroup: ServiceGroup; | ||
| hideServiceCount?: boolean; | ||
| onClick?: () => void; | ||
| href?: string; | ||
| servicesCount?: number; | ||
| serviceGroupCounts?: { services: number; alerts: number }; | ||
| } | ||
|
|
||
| export function ServiceGroupsCard({ | ||
| serviceGroup, | ||
| hideServiceCount = false, | ||
| onClick, | ||
| href, | ||
| servicesCount, | ||
| serviceGroupCounts, | ||
| }: Props) { | ||
| const activeAlertsHref = useObservabilityActiveAlertsHref(serviceGroup.kuery); | ||
| const cardProps: EuiCardProps = { | ||
| style: { width: 286 }, | ||
| icon: ( | ||
| <EuiAvatar | ||
| name={serviceGroup.groupName} | ||
| color={serviceGroup.color || SERVICE_GROUP_COLOR_DEFAULT} | ||
| size="l" | ||
| /> | ||
| <> | ||
| {serviceGroupCounts?.alerts && ( | ||
| <div> | ||
| <EuiBadge | ||
| iconType="alert" | ||
| color="danger" | ||
| href={activeAlertsHref} | ||
| {...({ | ||
| onClick(e: React.SyntheticEvent) { | ||
| e.stopPropagation(); // prevents extra click thru to EuiCard's href destination | ||
| }, | ||
| } as object)} // workaround for type check that prevents href + onclick | ||
| > | ||
| {i18n.translate('xpack.apm.serviceGroups.cardsList.alertCount', { | ||
| defaultMessage: | ||
| '{alertsCount} {alertsCount, plural, one {alert} other {alerts}}', | ||
| values: { alertsCount: serviceGroupCounts.alerts }, | ||
| })} | ||
| </EuiBadge> | ||
| <EuiSpacer size="s" /> | ||
| </div> | ||
| )} | ||
| <EuiAvatar | ||
| name={serviceGroup.groupName} | ||
| color={serviceGroup.color || SERVICE_GROUP_COLOR_DEFAULT} | ||
| size="l" | ||
| /> | ||
| </> | ||
| ), | ||
| title: serviceGroup.groupName, | ||
| description: ( | ||
|
|
@@ -58,15 +83,15 @@ export function ServiceGroupsCard({ | |
| {!hideServiceCount && ( | ||
| <EuiFlexItem> | ||
| <EuiText size="s"> | ||
| {servicesCount === undefined ? ( | ||
| {serviceGroupCounts === undefined ? ( | ||
| <> </> | ||
|
Contributor
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. Is it really needed? Can we just render the translation if
Contributor
Author
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. This was in place for 8.5 in order to avoid a jump in height after service counts were loaded. But we may want to re-think the loading state for these cards of service groups. |
||
| ) : ( | ||
| i18n.translate( | ||
| 'xpack.apm.serviceGroups.cardsList.serviceCount', | ||
| { | ||
| defaultMessage: | ||
| '{servicesCount} {servicesCount, plural, one {service} other {services}}', | ||
| values: { servicesCount }, | ||
| values: { servicesCount: serviceGroupCounts.services }, | ||
| } | ||
| ) | ||
| )} | ||
|
|
@@ -75,7 +100,6 @@ export function ServiceGroupsCard({ | |
| )} | ||
| </EuiFlexGroup> | ||
| ), | ||
| onClick, | ||
| href, | ||
| }; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License | ||
| * 2.0; you may not use this file except in compliance with the Elastic License | ||
| * 2.0. | ||
| */ | ||
|
|
||
| import { isEmpty } from 'lodash'; | ||
| import { APMRouteHandlerResources } from '../typings'; | ||
|
|
||
| export type ApmAlertsClient = Awaited<ReturnType<typeof getApmAlertsClient>>; | ||
|
|
||
| export async function getApmAlertsClient({ | ||
| plugins, | ||
| request, | ||
| }: APMRouteHandlerResources) { | ||
| const ruleRegistryPluginStart = await plugins.ruleRegistry.start(); | ||
| const alertsClient = await ruleRegistryPluginStart.getRacClientWithRequest( | ||
| request | ||
| ); | ||
| const apmAlertsIndices = await alertsClient.getAuthorizedAlertsIndices([ | ||
| 'apm', | ||
| ]); | ||
|
|
||
| if (!apmAlertsIndices || isEmpty(apmAlertsIndices)) { | ||
|
sorenlouv marked this conversation as resolved.
|
||
| throw Error('No alert indices exist for "apm"'); | ||
| } | ||
|
|
||
| type ApmAlertsClientSearchParams = Omit< | ||
| Parameters<typeof alertsClient.find>[0], | ||
| 'index' | ||
| >; | ||
|
|
||
| return { | ||
| search(searchParams: ApmAlertsClientSearchParams) { | ||
| return alertsClient.find({ | ||
| ...searchParams, | ||
| index: apmAlertsIndices.join(','), | ||
| }); | ||
| }, | ||
| }; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.