Skip to content
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

[Actionable Observability] - Add alert annotation and threshold shade on the APM latency chart on the Alert Details page #147848

Merged

Conversation

fkanout
Copy link
Contributor

@fkanout fkanout commented Dec 20, 2022

Summary

Closes #147779 by adding the following elements to the latency chart for the Latency threshold alert:

  1. Alert annotation that indicates when the alert is triggered
  2. Alert threshold rect (shade)
  3. Alert threshold annotation (red line on Y axe)
  4. Alert active rect (dark red shade where the alert is active)

image

@fkanout fkanout self-assigned this Dec 20, 2022
@fkanout fkanout changed the title Add annotation and threshold rect [Actionable Observability] - Add alert annotation and threshold shade on the APM latency chart on the Alert Details page Dec 20, 2022
@fkanout fkanout added release_note:feature Makes this part of the condensed release notes Team: Actionable Observability - DEPRECATED For Observability Alerting and SLOs use "Team:obs-ux-management", for AIops "Team:obs-knowledge" v8.7.0 labels Dec 21, 2022
@fkanout fkanout marked this pull request as ready for review December 21, 2022 10:48
@fkanout fkanout requested a review from a team as a code owner December 21, 2022 10:48
@elasticmachine
Copy link
Contributor

Pinging @elastic/actionable-observability (Team: Actionable Observability)

@botelastic botelastic bot added the Team:APM - DEPRECATED Use Team:obs-ux-infra_services. label Dec 21, 2022
@elasticmachine
Copy link
Contributor

Pinging @elastic/apm-ui (Team:APM)

@fkanout fkanout requested a review from dgieselaar December 28, 2022 17:08
Copy link
Contributor

@MiriamAparicio MiriamAparicio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dgieselaar
Copy link
Member

dgieselaar commented Dec 29, 2022 via email

@fkanout
Copy link
Contributor Author

fkanout commented Jan 4, 2023

@elasticmachine merge upstream

/* Error Rate */

const getLatencyChartAdditionalData = () => {
Copy link
Member

@sorenlouv sorenlouv Jan 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since #143298 is merged so I'll add a comment about the following code in this PR:

  const transactionTypes = useServiceTransactionTypesFetcher({
    serviceName,
    start,
    end,
  });

  const transactionType = getTransactionType({
    transactionType: String(alert.fields[TRANSACTION_TYPE]),
    transactionTypes,
    agentName,
  });

I don't understand the above code in this context. We don't want to get a default transaction type. We want the actual transaction type that caused the alert. The transaction type is optional when creating a rule but required on alerts. This means that if the transaction type is not specified for a rule, the rule executor will do a terms agg on transaction.type to ensure an alert is always associated with the correct transaction type. See:

tldr: I think the above code is redundant. Get the transaction type from the alert. If the alert doesn't have a transaction type we cannot show the chart (I don't think that's likely to happen anymore but it may have happened to alerts in the past).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the same vain, why is this needed?

const latencyAggregationType = getAggsTypeFromRule(params.aggregationType);

params.aggregationType is of type LatencyAggregationType and the returned value is LatencyAggregationType.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also looks incorrect:

const environment = String(params.environment) || ENVIRONMENT_ALL.value;

environment (like transaction.type) is required on the alert (optional on the rule).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the same vain, why is this needed?
const latencyAggregationType = getAggsTypeFromRule(params.aggregationType);
params.aggregationType is of type LatencyAggregationType and the returned value is LatencyAggregationType.

@sqren. Good catch. However, we still need the function getAggsTypeFromRule.
The issue is in AlertDetailsAppSectionProps type. The aggregationType is not LatencyAggregationType because it returns 95th and 99th instead of p95 and p99.

export interface AlertDetailsAppSectionProps {
  rule: Rule<{
    environment: string;
    aggregationType: LatencyAggregationType;
    windowSize: number;
    windowUnit: TIME_UNITS;
  }>;
  alert: TopAlert<{ [SERVICE_NAME]: string; [TRANSACTION_TYPE]: string }>;
  timeZone: string;
}

It should beaggregationType: string;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sqren, regarding the transactionType in https://github.com/elastic/kibana/pull/147848/files#r1062460375
I don't know the workflow and how it should be implemented.
I followed the same steps in the APMServiceContext to get the tansactionType

const transactionTypes = useServiceTransactionTypesFetcher({
    serviceName,
    start,
    end,
  });

  const currentTransactionType = getOrRedirectToTransactionType({
    transactionType: query.transactionType,
    transactionTypes,
    agentName,
    history,
  });

The only difference is that I'm using getTransactionType instead of getOrRedirectToTransactionType as I don't need/have access to the history argument because it's part of APM context

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sqren, for the environment const environment = String(params.environment) || ENVIRONMENT_ALL.value; It's the rule environment, and it was addressed in this thread #143298 (comment)

We want to display the latency chart for an alert so the user can understand why an alert fired, right? In that case, we should get the environment from the alert - not the rule.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to display the latency chart for an alert so the user can understand why an alert fired, right? In that case, we should get the environment from the alert - not the rule.

@sqren, you are right. I updated it. Thanks!

Copy link
Contributor Author

@fkanout fkanout Jan 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, the alert env is fetched from the rule in the createLifecycleRuleType with some null-checks. But still getting the env from the alert is better.

Copy link
Member

@sorenlouv sorenlouv Jan 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still see

  const transactionType = getTransactionType({
    transactionType: String(alert.fields[TRANSACTION_TYPE]),
    transactionTypes,
    agentName,
  });

This should be changed to:

const transactionType = alert.fields[TRANSACTION_TYPE];

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Member

@sorenlouv sorenlouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The annotation stuff lgtm. But I have some concerns about some of the existing code.

Comment on lines -223 to -240
{showAnnotations && (
<LineAnnotation
id="annotations"
domainType={AnnotationDomainType.XDomain}
dataValues={annotations.map((annotation) => ({
dataValue: annotation['@timestamp'],
header: asAbsoluteDateTime(annotation['@timestamp']),
details: `${i18n.translate('xpack.apm.chart.annotation.version', {
defaultMessage: 'Version',
})} ${annotation.text}`,
}))}
style={{
line: { strokeWidth: 1, stroke: annotationColor, opacity: 1 },
}}
marker={<EuiIcon type="dot" color={annotationColor} />}
markerPosition={Position.Top}
/>
)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't quite wrap my head around whether moving this to the context works out. But it's probably fine.

@fkanout
Copy link
Contributor Author

fkanout commented Jan 9, 2023

@elasticmachine merge upstream

@fkanout fkanout enabled auto-merge (squash) January 9, 2023 12:51
@fkanout fkanout disabled auto-merge January 9, 2023 13:49
@fkanout fkanout enabled auto-merge (squash) January 9, 2023 14:40
@kibana-ci
Copy link
Collaborator

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #15 / dashboard sync colors should be possible to disable color sync
  • [job] [logs] FTR Configs #15 / dashboard sync colors should sync colors on dashboard by default

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
apm 1346 1352 +6

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
apm 3.2MB 3.2MB +1.8KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
apm 28.9KB 29.1KB +141.0B

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @fkanout

@fkanout fkanout merged commit 12ae75f into elastic:main Jan 9, 2023
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Jan 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting release_note:feature Makes this part of the condensed release notes Team: Actionable Observability - DEPRECATED For Observability Alerting and SLOs use "Team:obs-ux-management", for AIops "Team:obs-knowledge" Team:APM - DEPRECATED Use Team:obs-ux-infra_services. v8.7.0
Projects
None yet
7 participants