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

[ML] Add runtime support for anomaly charts & add composite validations #96348

Merged
merged 12 commits into from
Apr 12, 2021

Conversation

qn895
Copy link
Member

@qn895 qn895 commented Apr 6, 2021

Summary

Part of #77462. This PR adds runtime support for anomaly charts without model plot enabled.

Screen Shot 2021-04-06 at 14 15 40

Screen Shot 2021-04-06 at 14 15 54

It also adds extra validations for datafeed with composite aggregations to require only terms and date_histogram fields in the composite sources.
Screen Shot 2021-04-06 at 14 15 25

Checklist

Delete any items that are not applicable to this PR.

@qn895 qn895 mentioned this pull request Apr 6, 2021
12 tasks
@qn895 qn895 marked this pull request as ready for review April 6, 2021 20:29
@qn895 qn895 requested a review from a team as a code owner April 6, 2021 20:29
@elasticmachine
Copy link
Contributor

Pinging @elastic/ml-ui (:ml)

Comment on lines 78 to 79
isPopulatedObject(buckets, ['composite']) &&
isPopulatedObject(buckets.composite, ['sources'])
Copy link
Contributor

Choose a reason for hiding this comment

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

what do you think about extending isPopulatedObject guard to support nested props?

Suggested change
isPopulatedObject(buckets, ['composite']) &&
isPopulatedObject(buckets.composite, ['sources'])
isPopulatedObject(buckets, ['composite.sources'])

Copy link
Member Author

Choose a reason for hiding this comment

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

I think this is a good idea although I think we probably should have a different API for handling that type of nested cases as it is possible for an object to have keys with dots in the name.
const myObj = {"composite.sources": "value1", "composite": { "source": "value2" }}

if (
isPopulatedObject(buckets, ['composite']) &&
isPopulatedObject(buckets.composite, ['sources']) &&
buckets.composite.sources !== undefined
Copy link
Contributor

Choose a reason for hiding this comment

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

shall we check for an array instead?

Suggested change
buckets.composite.sources !== undefined
Array.isArray(buckets.composite.sources)

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated here 4987fc2 (#96348)

@peteharverson
Copy link
Contributor

peteharverson commented Apr 8, 2021

The charts in the Anomaly Explorer are showing up empty for me for a population job using runtime fields:
image

Job config is:

  "analysis_config": {
    "bucket_span": "15m",
    "detectors": [
      {
        "detector_description": "mean(responsetime_big) over airline_lower",
        "function": "mean",
        "field_name": "responsetime_big",
        "over_field_name": "airline_lower",
        "detector_index": 0
      }
    ],
    "influencers": [
      "airline_lower"
    ]
  },

The chart in the Single Metric Viewer is plotting correctly.

Update: confirmed fixed by 9b8746b

Copy link
Contributor

@peteharverson peteharverson left a comment

Choose a reason for hiding this comment

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

Tested latest edits and LGTM

});
// if job has at least one composite source that is not terms or date_histogram
const aggs = getDatafeedAggregations(job.datafeed_config);
if (aggs !== undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Suggest to use isPopulatedObject() here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated here 058c5dd (#96348)

if (aggs !== undefined) {
const aggBucketsName = getFirstKeyInObject(aggs);
if (aggBucketsName !== undefined && aggs[aggBucketsName] !== undefined) {
// if fieldName is a aggregated field under nested terms using bucket_script
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Missing n for an aggregated field.

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated here 058c5dd (#96348)

return i18n.translate(
'xpack.ml.timeSeriesJob.jobWithUnsupportedCompositeAggregationMessage',
{
defaultMessage: 'the datafeed contains unsupported composite sources',
Copy link
Contributor

Choose a reason for hiding this comment

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

Where does this show up? Should the first char be capitalized and the sentence end with a dot?

Copy link
Member Author

Choose a reason for hiding this comment

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

Originally, the full message will show up like this. But I realized the extra message is redundant so I removed it here 058c5dd (#96348).

Screen Shot 2021-04-12 at 10 26 50

*/
export const getFirstKeyInObject = (arg: unknown): string | undefined => {
if (isPopulatedObject(arg)) {
const keys = Object.keys(arg);
Copy link
Contributor

Choose a reason for hiding this comment

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

Since JS doesn't guarantee the order of keys, should we sort the keys alphabetically to make sure the function returns 100% consistent results?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a good point. However, I don't think we should sort it alphabetically by default. We can have an extra argument like sorted or have another getFirstSortedKeyInObject function if that's needed. In this case where this function is used, for example if the aggregation config is like below, my_buckets should be used instead of buckets. Also in this specific case where we are accessing the datafeed config, it's already been validated and should be guaranteed to have only one definition in the object - we just don't know what the key is called.

"aggregations": {
      "my_buckets": {
		....
      },
      "buckets": {
		....
      }
    },

Copy link
Contributor

@walterra walterra left a comment

Choose a reason for hiding this comment

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

Latest changes LGTM.

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Async chunks

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

id before after diff
ml 6.0MB 6.0MB +91.0B

Page load bundle

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

id before after diff
ml 66.9KB 67.1KB +207.0B

History

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

cc @qn895

@qn895 qn895 added the auto-backport Deprecated - use backport:version if exact versions are needed label Apr 12, 2021
@qn895 qn895 merged commit e7f5d07 into elastic:master Apr 12, 2021
@qn895 qn895 deleted the ml-anomaly-charts-runtime branch April 12, 2021 17:59
@kibanamachine
Copy link
Contributor

💔 Backport failed

Status Branch Result
7.x Commit could not be cherrypicked due to conflicts

To backport manually run:
node scripts/backport --pr 96348

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Deprecated - use backport:version if exact versions are needed Feature:Anomaly Detection ML anomaly detection :ml release_note:feature Makes this part of the condensed release notes v7.13.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants