Skip to content

Comments

[Incident Management] [Suggested dashboards] Deduplicated linked dashboards from list of linked dashboards#221972

Merged
dominiqueclarke merged 13 commits intoelastic:mainfrom
dominiqueclarke:feat/alerts-related-dashboards-deduplicate-suggested
Jun 12, 2025
Merged

[Incident Management] [Suggested dashboards] Deduplicated linked dashboards from list of linked dashboards#221972
dominiqueclarke merged 13 commits intoelastic:mainfrom
dominiqueclarke:feat/alerts-related-dashboards-deduplicate-suggested

Conversation

@dominiqueclarke
Copy link
Contributor

@dominiqueclarke dominiqueclarke commented May 29, 2025

Summary

Resolves #212801

Removes already linked dashboards from the list of suggested dashboards

Also has the side effect of returning the linked dashboards from the related dashboards api, which can be used to render the linked dashboards list along with the suggested dashboards, rather than calling a separate API from the client.

@github-actions github-actions bot added the author:obs-ux-management PRs authored by the obs ux management team label May 29, 2025
@dominiqueclarke
Copy link
Contributor Author

/ci

@dominiqueclarke
Copy link
Contributor Author

/ci

@dominiqueclarke dominiqueclarke changed the title return linked dashboards from related dashboards api [Incident Management] [Suggested dashboards] Deduplicated linked dashboards from list of linked dashboards Jun 9, 2025
@dominiqueclarke dominiqueclarke added release_note:skip Skip the PR/issue when compiling release notes Team:actionable-obs Formerly "obs-ux-management", responsible for SLO, o11y alerting, significant events, & synthetics. v9.1.0 v8.19.0 backport:version Backport to applied version labels labels Jun 9, 2025
@dominiqueclarke dominiqueclarke marked this pull request as ready for review June 9, 2025 13:55
@dominiqueclarke dominiqueclarke requested a review from a team as a code owner June 9, 2025 13:55
@elasticmachine
Copy link
Contributor

Pinging @elastic/obs-ux-management-team (Team:obs-ux-management)

Copy link
Contributor

@justinkambic justinkambic left a comment

Choose a reason for hiding this comment

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

A few comments regarding ways we could possibly improve error handling/logging.

Code looks good, I tested this locally with a few dashboards I made to ensure they're deduped.

const relevantDashboardsById = new Map<string, SuggestedDashboard>();
const index = await this.getRuleQueryIndex();
if (!this.alert) {
throw new Error('Alert not found. Could not fetch suggested dashboards.');
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm noticing repetition of this throw pattern a few times throughout this class, and an inconsistent error message where sometimes the alert ID is included and other times it's not. Since alertId is a required var for this class, perhaps we can extract this throw procedure into the private function and avoid ad-hoc throw Error calls for the same purpose repeated throughout the class. It will make the error messages more standardized when researching issues if they come up as well.

Something like:

private checkAlert(): AlertData {
  if (!this.alert) throw new Error(`Alert with id ${this.alertId} not found. Could not fetch related dashboards.`);
  return this.alert;
}

const allSuggestedDashboards = new Set<SuggestedDashboard>();
const relevantDashboardsById = new Map<string, SuggestedDashboard>();
const index = await this.getRuleQueryIndex();
if (!this.alert) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Put this condition at the top of the function since it's a no-op? Also, kind of related to my comment below but also different, this exact check happens within getRuleQueryIndex, so the error thrown inside this block will never execute. This is probably fine, because the implementation of getRuleQueryIndex could change in the future. In any case, doing the throw here at the top instead of in the nested function call will make reading the stack trace easier, too.

if (allRelevantFields.length > 0) {
const { dashboards } = this.getDashboardsByField(allRelevantFields);
dashboards.forEach((dashboard) => allRelatedDashboards.add(dashboard));
const { dashboards } = this.getDashboardsByField(Array.from(allRelevantFields));
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const { dashboards } = this.getDashboardsByField(Array.from(allRelevantFields));
const { dashboards } = this.getDashboardsByField(allRelevantFields);

I think we can cut this as allRelevantFields is already typed as 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.

Interesting. Wondering if you're looking at an old commit. I don't have this on my branch.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

JK I was on my backport repo looking at this.

this.getLinkedDashboards(),
]);
const filteredSuggestedDashboards = suggestedDashboards.filter(
(suggested) => !linkedDashboards.some((linked) => linked.id === suggested.id)
Copy link
Contributor

Choose a reason for hiding this comment

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

My initial impression was "why not use the set method we have below to get O(1) lookup" but I am thinking we are only going to have a handful of linked dashboards in most cases, where N=10 or less, so probably not needed. Agree? Just a thought.

};
}

async fetchSuggestedDashboards(): Promise<SuggestedDashboard[]> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
async fetchSuggestedDashboards(): Promise<SuggestedDashboard[]> {
private async fetchSuggestedDashboards(): Promise<SuggestedDashboard[]> {

We could optionally encapsulate this function as we only call it internally in RelatedDashboardsClient. I do see it's referenced in the test file so if you'd rather keep it public for that purpose to avoid complicating testing I'm ok with that.

getRuleQueryIndex(): string | null {
if (!this.alert) {
throw new Error('Alert not found. Could not get the rule query index.');
throw new Error('Alert not found. Could not get rule query index.');
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to above comment about standardizing some/all of the alert-related throws. It looks like in this case there might be some difference in the information the error needs to convey, but the condition is the same.

Comment on lines 312 to 319
if (!this.alert) {
throw new Error('Alert not found. Could not get linked dashboards.');
}
const ruleId = this.alert.getRuleId();
if (!ruleId) {
this.logger.warn(`Rule id not found. No linked dashboards available.`);
return [];
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I've been wondering about this; is there a reason we can simply log a warning and return an empty set here while we need to throw if the alert is null?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The rule is only necessary for linked dashboards, but technically we could still return suggested dashboards if linked dashboards fail. I don't know if that's the right UX though. We can keep it consistent by throwing the error here as well.

dominiqueclarke and others added 2 commits June 9, 2025 14:03
…rvices/investigate_alerts_client.ts

Co-authored-by: Justin Kambic <jk@elastic.co>
Copy link
Contributor

@justinkambic justinkambic left a comment

Choose a reason for hiding this comment

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

LGTM, can implement any other suggestions if you think they're worthwhile but the error throwing aspect was the only part I was truly concerned with.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/observability-schema 7 9 +2
Unknown metric groups

API count

id before after diff
@kbn/observability-schema 7 9 +2

History

@dominiqueclarke dominiqueclarke merged commit 3382566 into elastic:main Jun 12, 2025
10 checks passed
@kibanamachine
Copy link
Contributor

Starting backport for target branches: 8.19

https://github.com/elastic/kibana/actions/runs/15599303794

kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Jun 12, 2025
…boards from list of linked dashboards (elastic#221972)

## Summary

Resolves elastic#212801

Removes already linked dashboards from the list of suggested dashboards

Also has the side effect of returning the linked dashboards from the
related dashboards api, which can be used to render the linked
dashboards list along with the suggested dashboards, rather than calling
a separate API from the client.

---------

Co-authored-by: Justin Kambic <jk@elastic.co>
(cherry picked from commit 3382566)
@kibanamachine
Copy link
Contributor

💚 All backports created successfully

Status Branch Result
8.19

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

@kibanamachine
Copy link
Contributor

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.
cc: @dominiqueclarke

iblancof pushed a commit to iblancof/kibana that referenced this pull request Jun 16, 2025
…boards from list of linked dashboards (elastic#221972)

## Summary

Resolves elastic#212801

Removes already linked dashboards from the list of suggested dashboards

Also has the side effect of returning the linked dashboards from the
related dashboards api, which can be used to render the linked
dashboards list along with the suggested dashboards, rather than calling
a separate API from the client.

---------

Co-authored-by: Justin Kambic <jk@elastic.co>
@kibanamachine
Copy link
Contributor

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.
cc: @dominiqueclarke

kibanamachine added a commit that referenced this pull request Jun 17, 2025
…ed dashboards from list of linked dashboards (#221972) (#223488)

# Backport

This will backport the following commits from `main` to `8.19`:
- [[Incident Management] [Suggested dashboards] Deduplicated linked
dashboards from list of linked dashboards
(#221972)](#221972)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Dominique
Clarke","email":"dominique.clarke@elastic.co"},"sourceCommit":{"committedDate":"2025-06-12T01:18:22Z","message":"[Incident
Management] [Suggested dashboards] Deduplicated linked dashboards from
list of linked dashboards (#221972)\n\n## Summary\n\nResolves
https://github.com/elastic/kibana/issues/212801\n\nRemoves already
linked dashboards from the list of suggested dashboards\n\nAlso has the
side effect of returning the linked dashboards from the\nrelated
dashboards api, which can be used to render the linked\ndashboards list
along with the suggested dashboards, rather than calling\na separate API
from the client.\n\n---------\n\nCo-authored-by: Justin Kambic
<jk@elastic.co>","sha":"33825663e9118940eebc9fb6a16ec40cb9342cc7","branchLabelMapping":{"^v9.1.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:obs-ux-management","backport:version","v9.1.0","v8.19.0","author:obs-ux-management"],"title":"[Incident
Management] [Suggested dashboards] Deduplicated linked dashboards from
list of linked
dashboards","number":221972,"url":"https://github.com/elastic/kibana/pull/221972","mergeCommit":{"message":"[Incident
Management] [Suggested dashboards] Deduplicated linked dashboards from
list of linked dashboards (#221972)\n\n## Summary\n\nResolves
https://github.com/elastic/kibana/issues/212801\n\nRemoves already
linked dashboards from the list of suggested dashboards\n\nAlso has the
side effect of returning the linked dashboards from the\nrelated
dashboards api, which can be used to render the linked\ndashboards list
along with the suggested dashboards, rather than calling\na separate API
from the client.\n\n---------\n\nCo-authored-by: Justin Kambic
<jk@elastic.co>","sha":"33825663e9118940eebc9fb6a16ec40cb9342cc7"}},"sourceBranch":"main","suggestedTargetBranches":["8.19"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/221972","number":221972,"mergeCommit":{"message":"[Incident
Management] [Suggested dashboards] Deduplicated linked dashboards from
list of linked dashboards (#221972)\n\n## Summary\n\nResolves
https://github.com/elastic/kibana/issues/212801\n\nRemoves already
linked dashboards from the list of suggested dashboards\n\nAlso has the
side effect of returning the linked dashboards from the\nrelated
dashboards api, which can be used to render the linked\ndashboards list
along with the suggested dashboards, rather than calling\na separate API
from the client.\n\n---------\n\nCo-authored-by: Justin Kambic
<jk@elastic.co>","sha":"33825663e9118940eebc9fb6a16ec40cb9342cc7"}},{"branch":"8.19","label":"v8.19.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

---------

Co-authored-by: Dominique Clarke <dominique.clarke@elastic.co>
Co-authored-by: Justin Kambic <jk@elastic.co>
@kibanamachine kibanamachine removed the backport missing Added to PRs automatically when the are determined to be missing a backport. label Jun 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author:obs-ux-management PRs authored by the obs ux management team backport:version Backport to applied version labels release_note:skip Skip the PR/issue when compiling release notes Team:actionable-obs Formerly "obs-ux-management", responsible for SLO, o11y alerting, significant events, & synthetics. v8.19.0 v9.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Incident Management] [Alert details] [Suggested Dashboards] Deduplicate related dashboards between linked and suggested

4 participants