From 007b16793dc170b5283e99d47d98aef379c41d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Mon, 4 May 2020 12:18:19 +0200 Subject: [PATCH 1/4] Bump backport to 5.4.1 (#65041) --- .backportrc.json | 29 +++++++++++++++++++++++++++-- package.json | 2 +- yarn.lock | 47 ++++++++++++++++++++++++++--------------------- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/.backportrc.json b/.backportrc.json index 2603eb2e2d444..731f49183dba5 100644 --- a/.backportrc.json +++ b/.backportrc.json @@ -1,5 +1,30 @@ { "upstream": "elastic/kibana", - "branches": [{ "name": "7.x", "checked": true }, "7.7", "7.6", "7.5", "7.4", "7.3", "7.2", "7.1", "7.0", "6.8", "6.7", "6.6", "6.5", "6.4", "6.3", "6.2", "6.1", "6.0", "5.6"], - "labels": ["backport"] + "targetBranchChoices": [ + { "name": "master", "checked": true }, + { "name": "7.x", "checked": true }, + "7.7", + "7.6", + "7.5", + "7.4", + "7.3", + "7.2", + "7.1", + "7.0", + "6.8", + "6.7", + "6.6", + "6.5", + "6.4", + "6.3", + "6.2", + "6.1", + "6.0", + "5.6" + ], + "targetPRLabels": ["backport"], + "branchLabelMapping": { + "^v7.8.0$": "7.x", + "^v(\\d+).(\\d+).\\d+$": "$1.$2" + } } diff --git a/package.json b/package.json index 0ad304fdf2f69..1e3ddc976aa67 100644 --- a/package.json +++ b/package.json @@ -400,7 +400,7 @@ "babel-eslint": "^10.0.3", "babel-jest": "^24.9.0", "babel-plugin-istanbul": "^6.0.0", - "backport": "5.1.3", + "backport": "5.4.1", "chai": "3.5.0", "chance": "1.0.18", "cheerio": "0.22.0", diff --git a/yarn.lock b/yarn.lock index 94e6a0a11aa99..346c4d76d24c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4778,11 +4778,6 @@ resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== -"@types/safe-json-stringify@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@types/safe-json-stringify/-/safe-json-stringify-1.1.0.tgz#4cd786442d7abc037f8e9026b22e3b401005c287" - integrity sha512-iIQqHp8fqDgxTlWor4DrTrKGVmjDeGDodQBipQkPSlRU1QeKIytv37U4aFN9N65VJcFJx67+zOnpbTNQzqHTOg== - "@types/seedrandom@>=2.0.0 <4.0.0": version "2.4.28" resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.28.tgz#9ce8fa048c1e8c85cb71d7fe4d704e000226036f" @@ -7409,24 +7404,24 @@ backo2@1.0.2: resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= -backport@5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/backport/-/backport-5.1.3.tgz#6fa788f48ee90e2b98b4e8d6d9385b0fb2e2f689" - integrity sha512-fTrXAyXvsg+lOuuWQosHzz/YnFfrkBsVkPcygjrDZVlWhbD+cA8mY3GrcJ8sIFwUg9Ja8qCeBFfLIRKlOwuzEg== +backport@5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/backport/-/backport-5.4.1.tgz#b066e8bbece91bc813187c13b7bea69ef5355471" + integrity sha512-vFR5Juss2pveS2OyyoE5n14j7ZDqeZXakzv4KngTEUTsb+5r/AVj2OG8LfJ14RJBMKBYSf1ojSKgDiWtUi0r+w== dependencies: - "@types/safe-json-stringify" "^1.1.0" axios "^0.19.2" dedent "^0.7.0" del "^5.1.0" find-up "^4.1.0" inquirer "^7.1.0" + lodash.flatmap "^4.5.0" lodash.isempty "^4.4.0" lodash.isstring "^4.0.1" lodash.uniq "^4.5.0" - make-dir "^3.0.2" - ora "^4.0.3" + make-dir "^3.1.0" + ora "^4.0.4" safe-json-stringify "^1.2.0" - strip-json-comments "^3.0.1" + strip-json-comments "^3.1.0" winston "^3.2.1" yargs "^15.3.1" @@ -19538,6 +19533,11 @@ lodash.filter@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4= +lodash.flatmap@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.flatmap/-/lodash.flatmap-4.5.0.tgz#ef8cbf408f6e48268663345305c6acc0b778702e" + integrity sha1-74y/QI9uSCaGYzRTBcaswLd4cC4= + lodash.flatten@^4.2.0, lodash.flatten@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" @@ -20026,10 +20026,10 @@ make-dir@^3.0.0: dependencies: semver "^6.0.0" -make-dir@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" - integrity sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w== +make-dir@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" @@ -22178,10 +22178,10 @@ ora@^3.0.0: strip-ansi "^5.2.0" wcwidth "^1.0.1" -ora@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/ora/-/ora-4.0.3.tgz#752a1b7b4be4825546a7a3d59256fa523b6b6d05" - integrity sha512-fnDebVFyz309A73cqCipVL1fBZewq4vwgSHfxh43vVy31mbyoQ8sCH3Oeaog/owYOs/lLlGVPCISQonTneg6Pg== +ora@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/ora/-/ora-4.0.4.tgz#e8da697cc5b6a47266655bf68e0fb588d29a545d" + integrity sha512-77iGeVU1cIdRhgFzCK8aw1fbtT1B/iZAvWjS+l/o1x0RShMgxHUZaD2yDpWsNCPwXg9z1ZA78Kbdvr8kBmG/Ww== dependencies: chalk "^3.0.0" cli-cursor "^3.1.0" @@ -28174,6 +28174,11 @@ strip-json-comments@^3.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== +strip-json-comments@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180" + integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w== + strip-json-comments@~1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" From ccede29e60a6406d5527dbfa21d87497c00b8ddf Mon Sep 17 00:00:00 2001 From: Maja Grubic Date: Mon, 4 May 2020 12:12:40 +0100 Subject: [PATCH 2/4] [TSVB] Fixing memory leak (#64918) --- .../server/lib/vis_data/helpers/index.js | 2 ++ .../server/lib/vis_data/helpers/overwrite.js | 31 +++++++++++++++++++ .../annotations/date_histogram.js | 4 +-- .../annotations/top_hits.js | 4 +-- .../series/date_histogram.js | 8 ++--- .../series/filter_ratios.js | 16 ++++++---- .../series/metric_buckets.js | 5 ++- .../series/normalize_query.js | 13 ++++---- .../series/positive_rate.js | 12 ++++--- .../series/sibling_buckets.js | 4 +-- .../series/split_by_everything.js | 4 +-- .../series/split_by_filter.js | 4 +-- .../series/split_by_filters.js | 4 +-- .../series/split_by_terms.js | 18 +++++------ .../table/date_histogram.js | 10 +++--- .../request_processors/table/filter_ratios.js | 12 +++---- .../table/metric_buckets.js | 4 +-- .../table/normalize_query.js | 24 +++++++------- .../request_processors/table/pivot.js | 17 +++++----- .../table/sibling_buckets.js | 4 +-- .../table/split_by_everything.js | 6 ++-- .../table/split_by_terms.js | 8 ++--- 22 files changed, 128 insertions(+), 86 deletions(-) create mode 100644 src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/overwrite.js diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/index.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/index.js index db6365f88d0ff..906730b394ae2 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/index.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/index.js @@ -29,6 +29,8 @@ import { getTimerange } from './get_timerange'; import { mapBucket } from './map_bucket'; import { parseSettings } from './parse_settings'; +export { overwrite } from './overwrite'; + export const helpers = { bucketTransform, getAggValue, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/overwrite.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/overwrite.js new file mode 100644 index 0000000000000..2eba5155a208d --- /dev/null +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/overwrite.js @@ -0,0 +1,31 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import set from 'set-value'; + +/** + * Set path in obj. Behaves like lodash `set` + * @param obj The object to mutate + * @param path The path of the sub-property to set + * @param val The value to set the sub-property to + */ +export function overwrite(obj, path, val) { + set(obj, path, undefined); + set(obj, path, val); +} diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/date_histogram.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/date_histogram.js index 283f2c115d4f5..f7b5cc9131ac4 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/date_histogram.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/date_histogram.js @@ -17,7 +17,7 @@ * under the License. */ -import _ from 'lodash'; +import { overwrite } from '../../helpers'; import { getBucketSize } from '../../helpers/get_bucket_size'; import { getTimerange } from '../../helpers/get_timerange'; import { search } from '../../../../../../../plugins/data/server'; @@ -37,7 +37,7 @@ export function dateHistogram( const { from, to } = getTimerange(req); const timezone = capabilities.searchTimezone; - _.set(doc, `aggs.${annotation.id}.date_histogram`, { + overwrite(doc, `aggs.${annotation.id}.date_histogram`, { field: timeField, min_doc_count: 0, time_zone: timezone, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/top_hits.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/top_hits.js index ae1e0bdc3884c..4cc3fd094cc13 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/top_hits.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/top_hits.js @@ -17,13 +17,13 @@ * under the License. */ -import _ from 'lodash'; +import { overwrite } from '../../helpers'; export function topHits(req, panel, annotation) { return next => doc => { const fields = (annotation.fields && annotation.fields.split(/[,\s]+/)) || []; const timeField = annotation.time_field; - _.set(doc, `aggs.${annotation.id}.aggs.hits.top_hits`, { + overwrite(doc, `aggs.${annotation.id}.aggs.hits.top_hits`, { sort: [ { [timeField]: { order: 'desc' }, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/date_histogram.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/date_histogram.js index df63a14ea5ee4..cc6466145dcdf 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/date_histogram.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/date_histogram.js @@ -17,7 +17,7 @@ * under the License. */ -import { set } from 'lodash'; +import { overwrite } from '../../helpers'; import { getBucketSize } from '../../helpers/get_bucket_size'; import { offsetTime } from '../../offset_time'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; @@ -34,7 +34,7 @@ export function dateHistogram(req, panel, series, esQueryConfig, indexPatternObj const { from, to } = offsetTime(req, series.offset_time); const timezone = capabilities.searchTimezone; - set(doc, `aggs.${series.id}.aggs.timeseries.date_histogram`, { + overwrite(doc, `aggs.${series.id}.aggs.timeseries.date_histogram`, { field: timeField, min_doc_count: 0, time_zone: timezone, @@ -47,7 +47,7 @@ export function dateHistogram(req, panel, series, esQueryConfig, indexPatternObj }; const getDateHistogramForEntireTimerangeMode = () => - set(doc, `aggs.${series.id}.aggs.timeseries.auto_date_histogram`, { + overwrite(doc, `aggs.${series.id}.aggs.timeseries.auto_date_histogram`, { field: timeField, buckets: 1, }); @@ -58,7 +58,7 @@ export function dateHistogram(req, panel, series, esQueryConfig, indexPatternObj // master - set(doc, `aggs.${series.id}.meta`, { + overwrite(doc, `aggs.${series.id}.meta`, { timeField, intervalString, bucketSize, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/filter_ratios.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/filter_ratios.js index 32a75b1268d06..0ca562c49b4c7 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/filter_ratios.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/filter_ratios.js @@ -19,16 +19,16 @@ const filter = metric => metric.type === 'filter_ratio'; import { bucketTransform } from '../../helpers/bucket_transform'; -import _ from 'lodash'; +import { overwrite } from '../../helpers'; export function ratios(req, panel, series) { return next => doc => { if (series.metrics.some(filter)) { series.metrics.filter(filter).forEach(metric => { - _.set(doc, `aggs.${series.id}.aggs.timeseries.aggs.${metric.id}-numerator.filter`, { + overwrite(doc, `aggs.${series.id}.aggs.timeseries.aggs.${metric.id}-numerator.filter`, { query_string: { query: metric.numerator || '*', analyze_wildcard: true }, }); - _.set(doc, `aggs.${series.id}.aggs.timeseries.aggs.${metric.id}-denominator.filter`, { + overwrite(doc, `aggs.${series.id}.aggs.timeseries.aggs.${metric.id}-denominator.filter`, { query_string: { query: metric.denominator || '*', analyze_wildcard: true }, }); @@ -46,8 +46,12 @@ export function ratios(req, panel, series) { metricAgg = {}; } const aggBody = { metric: metricAgg }; - _.set(doc, `aggs.${series.id}.aggs.timeseries.aggs.${metric.id}-numerator.aggs`, aggBody); - _.set( + overwrite( + doc, + `aggs.${series.id}.aggs.timeseries.aggs.${metric.id}-numerator.aggs`, + aggBody + ); + overwrite( doc, `aggs.${series.id}.aggs.timeseries.aggs.${metric.id}-denominator.aggs`, aggBody @@ -56,7 +60,7 @@ export function ratios(req, panel, series) { denominatorPath = `${metric.id}-denominator>metric`; } - _.set(doc, `aggs.${series.id}.aggs.timeseries.aggs.${metric.id}`, { + overwrite(doc, `aggs.${series.id}.aggs.timeseries.aggs.${metric.id}`, { bucket_script: { buckets_path: { numerator: numeratorPath, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/metric_buckets.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/metric_buckets.js index 857f2ab1d0485..d390821f9ad98 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/metric_buckets.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/metric_buckets.js @@ -16,8 +16,7 @@ * specific language governing permissions and limitations * under the License. */ - -import _ from 'lodash'; +import { overwrite } from '../../helpers'; import { getBucketSize } from '../../helpers/get_bucket_size'; import { bucketTransform } from '../../helpers/bucket_transform'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; @@ -33,7 +32,7 @@ export function metricBuckets(req, panel, series, esQueryConfig, indexPatternObj if (fn) { try { const bucket = fn(metric, series.metrics, intervalString); - _.set(doc, `aggs.${series.id}.aggs.timeseries.aggs.${metric.id}`, bucket); + overwrite(doc, `aggs.${series.id}.aggs.timeseries.aggs.${metric.id}`, bucket); } catch (e) { // meh } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/normalize_query.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/normalize_query.js index 0a701d1de577f..f76f3a531a37d 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/normalize_query.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/normalize_query.js @@ -16,9 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -const { set, get, isEmpty } = require('lodash'); +import { overwrite } from '../../helpers'; +import _ from 'lodash'; -const isEmptyFilter = (filter = {}) => Boolean(filter.match_all) && isEmpty(filter.match_all); +const isEmptyFilter = (filter = {}) => Boolean(filter.match_all) && _.isEmpty(filter.match_all); const hasSiblingPipelineAggregation = (aggs = {}) => Object.keys(aggs).length > 1; /* For grouping by the 'Everything', the splitByEverything request processor @@ -30,12 +31,12 @@ const hasSiblingPipelineAggregation = (aggs = {}) => Object.keys(aggs).length > * */ function removeEmptyTopLevelAggregation(doc, series) { - const filter = get(doc, `aggs.${series.id}.filter`); + const filter = _.get(doc, `aggs.${series.id}.filter`); if (isEmptyFilter(filter) && !hasSiblingPipelineAggregation(doc.aggs[series.id].aggs)) { - const meta = get(doc, `aggs.${series.id}.meta`); - set(doc, `aggs`, doc.aggs[series.id].aggs); - set(doc, `aggs.timeseries.meta`, meta); + const meta = _.get(doc, `aggs.${series.id}.meta`); + overwrite(doc, `aggs`, doc.aggs[series.id].aggs); + overwrite(doc, `aggs.timeseries.meta`, meta); } return doc; diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/positive_rate.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/positive_rate.js index 1ff548cc19e02..45db28fa98f5e 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/positive_rate.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/positive_rate.js @@ -20,7 +20,7 @@ import { getBucketSize } from '../../helpers/get_bucket_size'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; import { bucketTransform } from '../../helpers/bucket_transform'; -import { set } from 'lodash'; +import { overwrite } from '../../helpers'; export const filter = metric => metric.type === 'positive_rate'; @@ -48,9 +48,13 @@ export const createPositiveRate = (doc, intervalString, aggRoot) => metric => { const derivativeBucket = derivativeFn(derivativeMetric, fakeSeriesMetrics, intervalString); const positiveOnlyBucket = positiveOnlyFn(positiveOnlyMetric, fakeSeriesMetrics, intervalString); - set(doc, `${aggRoot}.timeseries.aggs.${metric.id}-positive-rate-max`, maxBucket); - set(doc, `${aggRoot}.timeseries.aggs.${metric.id}-positive-rate-derivative`, derivativeBucket); - set(doc, `${aggRoot}.timeseries.aggs.${metric.id}`, positiveOnlyBucket); + overwrite(doc, `${aggRoot}.timeseries.aggs.${metric.id}-positive-rate-max`, maxBucket); + overwrite( + doc, + `${aggRoot}.timeseries.aggs.${metric.id}-positive-rate-derivative`, + derivativeBucket + ); + overwrite(doc, `${aggRoot}.timeseries.aggs.${metric.id}`, positiveOnlyBucket); }; export function positiveRate(req, panel, series, esQueryConfig, indexPatternObject, capabilities) { diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/sibling_buckets.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/sibling_buckets.js index bbb7d60c8ef06..d677b2564c940 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/sibling_buckets.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/sibling_buckets.js @@ -17,7 +17,7 @@ * under the License. */ -import _ from 'lodash'; +import { overwrite } from '../../helpers'; import { getBucketSize } from '../../helpers/get_bucket_size'; import { bucketTransform } from '../../helpers/bucket_transform'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; @@ -40,7 +40,7 @@ export function siblingBuckets( if (fn) { try { const bucket = fn(metric, series.metrics, bucketSize); - _.set(doc, `aggs.${series.id}.aggs.${metric.id}`, bucket); + overwrite(doc, `aggs.${series.id}.aggs.${metric.id}`, bucket); } catch (e) { // meh } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_everything.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_everything.js index 54424bed0688b..c567e8ded0e61 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_everything.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_everything.js @@ -17,7 +17,7 @@ * under the License. */ -import _ from 'lodash'; +import { overwrite } from '../../helpers'; export function splitByEverything(req, panel, series) { return next => doc => { @@ -25,7 +25,7 @@ export function splitByEverything(req, panel, series) { series.split_mode === 'everything' || (series.split_mode === 'terms' && !series.terms_field) ) { - _.set(doc, `aggs.${series.id}.filter.match_all`, {}); + overwrite(doc, `aggs.${series.id}.filter.match_all`, {}); } return next(doc); }; diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filter.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filter.js index 80b4ef70a3f08..0822878aa9178 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filter.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filter.js @@ -17,7 +17,7 @@ * under the License. */ -import { set } from 'lodash'; +import { overwrite } from '../../helpers'; import { esQuery } from '../../../../../../data/server'; export function splitByFilter(req, panel, series, esQueryConfig, indexPattern) { @@ -26,7 +26,7 @@ export function splitByFilter(req, panel, series, esQueryConfig, indexPattern) { return next(doc); } - set( + overwrite( doc, `aggs.${series.id}.filter`, esQuery.buildEsQuery(indexPattern, [series.filter], [], esQueryConfig) diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filters.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filters.js index d023c28cdb25e..a3d2725ef58b5 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filters.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filters.js @@ -17,7 +17,7 @@ * under the License. */ -import { set } from 'lodash'; +import { overwrite } from '../../helpers'; import { esQuery } from '../../../../../../data/server'; export function splitByFilters(req, panel, series, esQueryConfig, indexPattern) { @@ -26,7 +26,7 @@ export function splitByFilters(req, panel, series, esQueryConfig, indexPattern) series.split_filters.forEach(filter => { const builtEsQuery = esQuery.buildEsQuery(indexPattern, [filter.filter], [], esQueryConfig); - set(doc, `aggs.${series.id}.filters.filters.${filter.id}`, builtEsQuery); + overwrite(doc, `aggs.${series.id}.filters.filters.${filter.id}`, builtEsQuery); }); } return next(doc); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_terms.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_terms.js index 3ad00272c66cb..db5a3f50f2e62 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_terms.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_terms.js @@ -17,7 +17,7 @@ * under the License. */ -import { set } from 'lodash'; +import { overwrite } from '../../helpers'; import { basicAggs } from '../../../../../common/basic_aggs'; import { getBucketsPath } from '../../helpers/get_buckets_path'; import { bucketTransform } from '../../helpers/bucket_transform'; @@ -27,13 +27,13 @@ export function splitByTerms(req, panel, series) { if (series.split_mode === 'terms' && series.terms_field) { const direction = series.terms_direction || 'desc'; const metric = series.metrics.find(item => item.id === series.terms_order_by); - set(doc, `aggs.${series.id}.terms.field`, series.terms_field); - set(doc, `aggs.${series.id}.terms.size`, series.terms_size); + overwrite(doc, `aggs.${series.id}.terms.field`, series.terms_field); + overwrite(doc, `aggs.${series.id}.terms.size`, series.terms_size); if (series.terms_include) { - set(doc, `aggs.${series.id}.terms.include`, series.terms_include); + overwrite(doc, `aggs.${series.id}.terms.include`, series.terms_include); } if (series.terms_exclude) { - set(doc, `aggs.${series.id}.terms.exclude`, series.terms_exclude); + overwrite(doc, `aggs.${series.id}.terms.exclude`, series.terms_exclude); } if (metric && metric.type !== 'count' && ~basicAggs.indexOf(metric.type)) { const sortAggKey = `${series.terms_order_by}-SORT`; @@ -42,12 +42,12 @@ export function splitByTerms(req, panel, series) { series.terms_order_by, sortAggKey ); - set(doc, `aggs.${series.id}.terms.order`, { [bucketPath]: direction }); - set(doc, `aggs.${series.id}.aggs`, { [sortAggKey]: fn(metric) }); + overwrite(doc, `aggs.${series.id}.terms.order`, { [bucketPath]: direction }); + overwrite(doc, `aggs.${series.id}.aggs`, { [sortAggKey]: fn(metric) }); } else if (['_key', '_count'].includes(series.terms_order_by)) { - set(doc, `aggs.${series.id}.terms.order`, { [series.terms_order_by]: direction }); + overwrite(doc, `aggs.${series.id}.terms.order`, { [series.terms_order_by]: direction }); } else { - set(doc, `aggs.${series.id}.terms.order`, { _count: direction }); + overwrite(doc, `aggs.${series.id}.terms.order`, { _count: direction }); } } return next(doc); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/date_histogram.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/date_histogram.js index 6afa434a55085..6b51415627fe9 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/date_histogram.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/date_histogram.js @@ -17,7 +17,7 @@ * under the License. */ -import { set } from 'lodash'; +import { overwrite } from '../../helpers'; import { getBucketSize } from '../../helpers/get_bucket_size'; import { isLastValueTimerangeMode } from '../../helpers/get_timerange_mode'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; @@ -41,7 +41,7 @@ export function dateHistogram(req, panel, esQueryConfig, indexPatternObject, cap panel.series.forEach(column => { const aggRoot = calculateAggRoot(doc, column); - set(doc, `${aggRoot}.timeseries.date_histogram`, { + overwrite(doc, `${aggRoot}.timeseries.date_histogram`, { field: timeField, min_doc_count: 0, time_zone: timezone, @@ -52,7 +52,7 @@ export function dateHistogram(req, panel, esQueryConfig, indexPatternObject, cap ...dateHistogramInterval(intervalString), }); - set(doc, aggRoot.replace(/\.aggs$/, '.meta'), { + overwrite(doc, aggRoot.replace(/\.aggs$/, '.meta'), { timeField, intervalString, bucketSize, @@ -64,12 +64,12 @@ export function dateHistogram(req, panel, esQueryConfig, indexPatternObject, cap panel.series.forEach(column => { const aggRoot = calculateAggRoot(doc, column); - set(doc, `${aggRoot}.timeseries.auto_date_histogram`, { + overwrite(doc, `${aggRoot}.timeseries.auto_date_histogram`, { field: timeField, buckets: 1, }); - set(doc, aggRoot.replace(/\.aggs$/, '.meta'), meta); + overwrite(doc, aggRoot.replace(/\.aggs$/, '.meta'), meta); }); }; diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/filter_ratios.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/filter_ratios.js index a05c414f1a311..8bce521e742d8 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/filter_ratios.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/filter_ratios.js @@ -19,7 +19,7 @@ const filter = metric => metric.type === 'filter_ratio'; import { bucketTransform } from '../../helpers/bucket_transform'; -import _ from 'lodash'; +import { overwrite } from '../../helpers'; import { calculateAggRoot } from './calculate_agg_root'; export function ratios(req, panel) { @@ -28,10 +28,10 @@ export function ratios(req, panel) { const aggRoot = calculateAggRoot(doc, column); if (column.metrics.some(filter)) { column.metrics.filter(filter).forEach(metric => { - _.set(doc, `${aggRoot}.timeseries.aggs.${metric.id}-numerator.filter`, { + overwrite(doc, `${aggRoot}.timeseries.aggs.${metric.id}-numerator.filter`, { query_string: { query: metric.numerator || '*', analyze_wildcard: true }, }); - _.set(doc, `${aggRoot}.timeseries.aggs.${metric.id}-denominator.filter`, { + overwrite(doc, `${aggRoot}.timeseries.aggs.${metric.id}-denominator.filter`, { query_string: { query: metric.denominator || '*', analyze_wildcard: true }, }); @@ -45,13 +45,13 @@ export function ratios(req, panel) { field: metric.field, }), }; - _.set(doc, `${aggRoot}.timeseries.aggs.${metric.id}-numerator.aggs`, aggBody); - _.set(doc, `${aggBody}.timeseries.aggs.${metric.id}-denominator.aggs`, aggBody); + overwrite(doc, `${aggRoot}.timeseries.aggs.${metric.id}-numerator.aggs`, aggBody); + overwrite(doc, `${aggBody}.timeseries.aggs.${metric.id}-denominator.aggs`, aggBody); numeratorPath = `${metric.id}-numerator>metric`; denominatorPath = `${metric.id}-denominator>metric`; } - _.set(doc, `${aggRoot}.timeseries.aggs.${metric.id}`, { + overwrite(doc, `${aggRoot}.timeseries.aggs.${metric.id}`, { bucket_script: { buckets_path: { numerator: numeratorPath, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/metric_buckets.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/metric_buckets.js index 44418efe42dbb..d38282ed3e9aa 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/metric_buckets.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/metric_buckets.js @@ -17,7 +17,7 @@ * under the License. */ -import _ from 'lodash'; +import { overwrite } from '../../helpers'; import { getBucketSize } from '../../helpers/get_bucket_size'; import { bucketTransform } from '../../helpers/bucket_transform'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; @@ -36,7 +36,7 @@ export function metricBuckets(req, panel, esQueryConfig, indexPatternObject) { if (fn) { try { const bucket = fn(metric, column.metrics, intervalString); - _.set(doc, `${aggRoot}.timeseries.aggs.${metric.id}`, bucket); + overwrite(doc, `${aggRoot}.timeseries.aggs.${metric.id}`, bucket); } catch (e) { // meh } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/normalize_query.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/normalize_query.js index 2b5014a2535dc..c38351e37dc31 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/normalize_query.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/normalize_query.js @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -const { set, get, isEmpty, forEach } = require('lodash'); - -const isEmptyFilter = (filter = {}) => Boolean(filter.match_all) && isEmpty(filter.match_all); +import _ from 'lodash'; +import { overwrite } from '../../helpers'; +const isEmptyFilter = (filter = {}) => Boolean(filter.match_all) && _.isEmpty(filter.match_all); const hasSiblingPipelineAggregation = (aggs = {}) => Object.keys(aggs).length > 1; /* Last query handler in the chain. You can use this handler @@ -29,26 +29,26 @@ const hasSiblingPipelineAggregation = (aggs = {}) => Object.keys(aggs).length > */ export function normalizeQuery() { return () => doc => { - const series = get(doc, 'aggs.pivot.aggs'); + const series = _.get(doc, 'aggs.pivot.aggs'); const normalizedSeries = {}; - forEach(series, (value, seriesId) => { - const filter = get(value, `filter`); + _.forEach(series, (value, seriesId) => { + const filter = _.get(value, `filter`); if (isEmptyFilter(filter) && !hasSiblingPipelineAggregation(value.aggs)) { - const agg = get(value, 'aggs.timeseries'); + const agg = _.get(value, 'aggs.timeseries'); const meta = { - ...get(value, 'meta'), + ..._.get(value, 'meta'), seriesId, }; - set(normalizedSeries, `${seriesId}`, agg); - set(normalizedSeries, `${seriesId}.meta`, meta); + overwrite(normalizedSeries, `${seriesId}`, agg); + overwrite(normalizedSeries, `${seriesId}.meta`, meta); } else { - set(normalizedSeries, `${seriesId}`, value); + overwrite(normalizedSeries, `${seriesId}`, value); } }); - set(doc, 'aggs.pivot.aggs', normalizedSeries); + overwrite(doc, 'aggs.pivot.aggs', normalizedSeries); return doc; }; diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/pivot.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/pivot.js index 972a8c71ed515..6597973c28cf0 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/pivot.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/pivot.js @@ -17,7 +17,8 @@ * under the License. */ -import { get, set, last } from 'lodash'; +import { get, last } from 'lodash'; +import { overwrite } from '../../helpers'; import { basicAggs } from '../../../../../common/basic_aggs'; import { getBucketsPath } from '../../helpers/get_buckets_path'; @@ -27,13 +28,13 @@ export function pivot(req, panel) { return next => doc => { const { sort } = req.payload.state; if (panel.pivot_id) { - set(doc, 'aggs.pivot.terms.field', panel.pivot_id); - set(doc, 'aggs.pivot.terms.size', panel.pivot_rows); + overwrite(doc, 'aggs.pivot.terms.field', panel.pivot_id); + overwrite(doc, 'aggs.pivot.terms.size', panel.pivot_rows); if (sort) { const series = panel.series.find(item => item.id === sort.column); const metric = series && last(series.metrics); if (metric && metric.type === 'count') { - set(doc, 'aggs.pivot.terms.order', { _count: sort.order }); + overwrite(doc, 'aggs.pivot.terms.order', { _count: sort.order }); } else if (metric && basicAggs.includes(metric.type)) { const sortAggKey = `${metric.id}-SORT`; const fn = bucketTransform[metric.type]; @@ -41,16 +42,16 @@ export function pivot(req, panel) { metric.id, sortAggKey ); - set(doc, `aggs.pivot.terms.order`, { [bucketPath]: sort.order }); - set(doc, `aggs.pivot.aggs`, { [sortAggKey]: fn(metric) }); + overwrite(doc, `aggs.pivot.terms.order`, { [bucketPath]: sort.order }); + overwrite(doc, `aggs.pivot.aggs`, { [sortAggKey]: fn(metric) }); } else { - set(doc, 'aggs.pivot.terms.order', { + overwrite(doc, 'aggs.pivot.terms.order', { _key: get(sort, 'order', 'asc'), }); } } } else { - set(doc, 'aggs.pivot.filter.match_all', {}); + overwrite(doc, 'aggs.pivot.filter.match_all', {}); } return next(doc); }; diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/sibling_buckets.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/sibling_buckets.js index 758da28e93232..b7ffbaa65619c 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/sibling_buckets.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/sibling_buckets.js @@ -17,7 +17,7 @@ * under the License. */ -import _ from 'lodash'; +import { overwrite } from '../../helpers'; import { getBucketSize } from '../../helpers/get_bucket_size'; import { bucketTransform } from '../../helpers/bucket_transform'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; @@ -36,7 +36,7 @@ export function siblingBuckets(req, panel, esQueryConfig, indexPatternObject) { if (fn) { try { const bucket = fn(metric, column.metrics, bucketSize); - _.set(doc, `${aggRoot}.${metric.id}`, bucket); + overwrite(doc, `${aggRoot}.${metric.id}`, bucket); } catch (e) { // meh } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_everything.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_everything.js index 35036abed320f..fd03921346fb8 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_everything.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_everything.js @@ -17,7 +17,7 @@ * under the License. */ -import { set } from 'lodash'; +import { overwrite } from '../../helpers'; import { esQuery } from '../../../../../../data/server'; export function splitByEverything(req, panel, esQueryConfig, indexPattern) { @@ -26,13 +26,13 @@ export function splitByEverything(req, panel, esQueryConfig, indexPattern) { .filter(c => !(c.aggregate_by && c.aggregate_function)) .forEach(column => { if (column.filter) { - set( + overwrite( doc, `aggs.pivot.aggs.${column.id}.filter`, esQuery.buildEsQuery(indexPattern, [column.filter], [], esQueryConfig) ); } else { - set(doc, `aggs.pivot.aggs.${column.id}.filter.match_all`, {}); + overwrite(doc, `aggs.pivot.aggs.${column.id}.filter.match_all`, {}); } }); return next(doc); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_terms.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_terms.js index 5b7ae735cd50f..a34d53a6bc975 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_terms.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_terms.js @@ -17,7 +17,7 @@ * under the License. */ -import { set } from 'lodash'; +import { overwrite } from '../../helpers'; import { esQuery } from '../../../../../../data/server'; export function splitByTerms(req, panel, esQueryConfig, indexPattern) { @@ -25,11 +25,11 @@ export function splitByTerms(req, panel, esQueryConfig, indexPattern) { panel.series .filter(c => c.aggregate_by && c.aggregate_function) .forEach(column => { - set(doc, `aggs.pivot.aggs.${column.id}.terms.field`, column.aggregate_by); - set(doc, `aggs.pivot.aggs.${column.id}.terms.size`, 100); + overwrite(doc, `aggs.pivot.aggs.${column.id}.terms.field`, column.aggregate_by); + overwrite(doc, `aggs.pivot.aggs.${column.id}.terms.size`, 100); if (column.filter) { - set( + overwrite( doc, `aggs.pivot.aggs.${column.id}.column_filter.filter`, esQuery.buildEsQuery(indexPattern, [column.filter], [], esQueryConfig) From 39e31d61239fea371ad2f97dc12da2302c3c9d10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20St=C3=BCrmer?= Date: Mon, 4 May 2020 13:29:28 +0200 Subject: [PATCH 3/4] [Logs UI] Add dataset filter to ML module setup screen (#64470) This adds the ability to filter the datasets to be processed by the ML jobs on the setup screen. --- .../log_analysis/validation/datasets.ts | 44 +++ .../http_api/log_analysis/validation/index.ts | 1 + .../common/log_analysis/job_parameters.ts | 60 +++- .../analysis_setup_indices_form.tsx | 113 ++------ .../index_setup_dataset_filter.tsx | 88 ++++++ .../index_setup_row.tsx | 110 ++++++++ .../initial_configuration_step.tsx | 6 +- .../initial_configuration_step/validation.tsx | 19 +- .../log_analysis/api/ml_setup_module_api.ts | 25 +- .../log_analysis/api/validate_datasets.ts | 36 +++ .../logs/log_analysis/log_analysis_module.tsx | 16 +- .../log_analysis/log_analysis_module_types.ts | 16 +- .../log_analysis/log_analysis_setup_state.ts | 264 ++++++++++++++++++ .../log_analysis/log_analysis_setup_state.tsx | 142 ---------- .../log_entry_categories/module_descriptor.ts | 43 ++- .../page_setup_content.tsx | 2 +- .../logs/log_entry_rate/module_descriptor.ts | 36 ++- .../log_entry_rate/page_setup_content.tsx | 2 +- x-pack/plugins/infra/server/infra_server.ts | 2 + .../infra/server/lib/compose/kibana.ts | 1 + .../log_entries_domain/log_entries_domain.ts | 54 +++- .../queries/log_entry_datasets.ts | 98 +++++++ x-pack/plugins/infra/server/plugin.ts | 1 + .../log_analysis/validation/datasets.ts | 69 +++++ .../routes/log_analysis/validation/index.ts | 1 + .../datafeed_log_entry_categories_count.json | 13 +- 26 files changed, 991 insertions(+), 271 deletions(-) create mode 100644 x-pack/plugins/infra/common/http_api/log_analysis/validation/datasets.ts create mode 100644 x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/index_setup_dataset_filter.tsx create mode 100644 x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/index_setup_row.tsx create mode 100644 x-pack/plugins/infra/public/containers/logs/log_analysis/api/validate_datasets.ts create mode 100644 x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_setup_state.ts delete mode 100644 x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_setup_state.tsx create mode 100644 x-pack/plugins/infra/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts create mode 100644 x-pack/plugins/infra/server/routes/log_analysis/validation/datasets.ts diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/validation/datasets.ts b/x-pack/plugins/infra/common/http_api/log_analysis/validation/datasets.ts new file mode 100644 index 0000000000000..c9f98ac5fcdea --- /dev/null +++ b/x-pack/plugins/infra/common/http_api/log_analysis/validation/datasets.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as rt from 'io-ts'; + +export const LOG_ANALYSIS_VALIDATE_DATASETS_PATH = + '/api/infra/log_analysis/validation/log_entry_datasets'; + +/** + * Request types + */ +export const validateLogEntryDatasetsRequestPayloadRT = rt.type({ + data: rt.type({ + indices: rt.array(rt.string), + timestampField: rt.string, + startTime: rt.number, + endTime: rt.number, + }), +}); + +export type ValidateLogEntryDatasetsRequestPayload = rt.TypeOf< + typeof validateLogEntryDatasetsRequestPayloadRT +>; + +/** + * Response types + * */ +const logEntryDatasetsEntryRT = rt.strict({ + indexName: rt.string, + datasets: rt.array(rt.string), +}); + +export const validateLogEntryDatasetsResponsePayloadRT = rt.type({ + data: rt.type({ + datasets: rt.array(logEntryDatasetsEntryRT), + }), +}); + +export type ValidateLogEntryDatasetsResponsePayload = rt.TypeOf< + typeof validateLogEntryDatasetsResponsePayloadRT +>; diff --git a/x-pack/plugins/infra/common/http_api/log_analysis/validation/index.ts b/x-pack/plugins/infra/common/http_api/log_analysis/validation/index.ts index f23ef7ee7c302..5f02f5598e6a4 100644 --- a/x-pack/plugins/infra/common/http_api/log_analysis/validation/index.ts +++ b/x-pack/plugins/infra/common/http_api/log_analysis/validation/index.ts @@ -4,4 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ +export * from './datasets'; export * from './log_entry_rate_indices'; diff --git a/x-pack/plugins/infra/common/log_analysis/job_parameters.ts b/x-pack/plugins/infra/common/log_analysis/job_parameters.ts index 94643e21f1ea6..7e10e45bbae4d 100644 --- a/x-pack/plugins/infra/common/log_analysis/job_parameters.ts +++ b/x-pack/plugins/infra/common/log_analysis/job_parameters.ts @@ -21,17 +21,73 @@ export const getJobId = (spaceId: string, sourceId: string, jobType: string) => export const getDatafeedId = (spaceId: string, sourceId: string, jobType: string) => `datafeed-${getJobId(spaceId, sourceId, jobType)}`; -export const jobSourceConfigurationRT = rt.type({ +export const datasetFilterRT = rt.union([ + rt.strict({ + type: rt.literal('includeAll'), + }), + rt.strict({ + type: rt.literal('includeSome'), + datasets: rt.array(rt.string), + }), +]); + +export type DatasetFilter = rt.TypeOf; + +export const jobSourceConfigurationRT = rt.partial({ indexPattern: rt.string, timestampField: rt.string, bucketSpan: rt.number, + datasetFilter: datasetFilterRT, }); export type JobSourceConfiguration = rt.TypeOf; export const jobCustomSettingsRT = rt.partial({ job_revision: rt.number, - logs_source_config: rt.partial(jobSourceConfigurationRT.props), + logs_source_config: jobSourceConfigurationRT, }); export type JobCustomSettings = rt.TypeOf; + +export const combineDatasetFilters = ( + firstFilter: DatasetFilter, + secondFilter: DatasetFilter +): DatasetFilter => { + if (firstFilter.type === 'includeAll' && secondFilter.type === 'includeAll') { + return { + type: 'includeAll', + }; + } + + const includedDatasets = new Set([ + ...(firstFilter.type === 'includeSome' ? firstFilter.datasets : []), + ...(secondFilter.type === 'includeSome' ? secondFilter.datasets : []), + ]); + + return { + type: 'includeSome', + datasets: [...includedDatasets], + }; +}; + +export const filterDatasetFilter = ( + datasetFilter: DatasetFilter, + predicate: (dataset: string) => boolean +): DatasetFilter => { + if (datasetFilter.type === 'includeAll') { + return datasetFilter; + } else { + const newDatasets = datasetFilter.datasets.filter(predicate); + + if (newDatasets.length > 0) { + return { + type: 'includeSome', + datasets: newDatasets, + }; + } else { + return { + type: 'includeAll', + }; + } + } +}; diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/analysis_setup_indices_form.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/analysis_setup_indices_form.tsx index 649858f657bfe..06dbf5315b83a 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/analysis_setup_indices_form.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/analysis_setup_indices_form.tsx @@ -4,56 +4,41 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EuiCode, EuiDescribedFormGroup, EuiFormRow, EuiCheckbox, EuiToolTip } from '@elastic/eui'; +import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import React, { useCallback, useMemo } from 'react'; - +import React, { useCallback } from 'react'; import { LoadingOverlayWrapper } from '../../../loading_overlay_wrapper'; -import { ValidatedIndex, ValidationIndicesUIError } from './validation'; +import { IndexSetupRow } from './index_setup_row'; +import { AvailableIndex } from './validation'; export const AnalysisSetupIndicesForm: React.FunctionComponent<{ disabled?: boolean; - indices: ValidatedIndex[]; + indices: AvailableIndex[]; isValidating: boolean; - onChangeSelectedIndices: (selectedIndices: ValidatedIndex[]) => void; + onChangeSelectedIndices: (selectedIndices: AvailableIndex[]) => void; valid: boolean; }> = ({ disabled = false, indices, isValidating, onChangeSelectedIndices, valid }) => { - const handleCheckboxChange = useCallback( - (event: React.ChangeEvent) => { + const changeIsIndexSelected = useCallback( + (indexName: string, isSelected: boolean) => { onChangeSelectedIndices( indices.map(index => { - const checkbox = event.currentTarget; - return index.name === checkbox.id ? { ...index, isSelected: checkbox.checked } : index; + return index.name === indexName ? { ...index, isSelected } : index; }) ); }, [indices, onChangeSelectedIndices] ); - const choices = useMemo( - () => - indices.map(index => { - const checkbox = ( - {index.name}} - onChange={handleCheckboxChange} - checked={index.validity === 'valid' && index.isSelected} - disabled={disabled || index.validity === 'invalid'} - /> - ); - - return index.validity === 'valid' ? ( - checkbox - ) : ( -
- {checkbox} -
- ); - }), - [disabled, handleCheckboxChange, indices] + const changeDatasetFilter = useCallback( + (indexName: string, datasetFilter) => { + onChangeSelectedIndices( + indices.map(index => { + return index.name === indexName ? { ...index, datasetFilter } : index; + }) + ); + }, + [indices, onChangeSelectedIndices] ); return ( @@ -69,13 +54,23 @@ export const AnalysisSetupIndicesForm: React.FunctionComponent<{ description={ } > - <>{choices} + <> + {indices.map(index => ( + + ))} + @@ -85,51 +80,3 @@ export const AnalysisSetupIndicesForm: React.FunctionComponent<{ const indicesSelectionLabel = i18n.translate('xpack.infra.analysisSetup.indicesSelectionLabel', { defaultMessage: 'Indices', }); - -const formatValidationError = (errors: ValidationIndicesUIError[]): React.ReactNode => { - return errors.map(error => { - switch (error.error) { - case 'INDEX_NOT_FOUND': - return ( -

- {error.index} }} - /> -

- ); - - case 'FIELD_NOT_FOUND': - return ( -

- {error.index}, - field: {error.field}, - }} - /> -

- ); - - case 'FIELD_NOT_VALID': - return ( -

- {error.index}, - field: {error.field}, - }} - /> -

- ); - - default: - return ''; - } - }); -}; diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/index_setup_dataset_filter.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/index_setup_dataset_filter.tsx new file mode 100644 index 0000000000000..b37c68f837876 --- /dev/null +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/index_setup_dataset_filter.tsx @@ -0,0 +1,88 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiFilterButton, + EuiFilterGroup, + EuiPopover, + EuiPopoverTitle, + EuiSelectable, + EuiSelectableOption, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import React, { useCallback, useMemo } from 'react'; +import { DatasetFilter } from '../../../../../common/log_analysis'; +import { useVisibilityState } from '../../../../utils/use_visibility_state'; + +export const IndexSetupDatasetFilter: React.FC<{ + availableDatasets: string[]; + datasetFilter: DatasetFilter; + isDisabled?: boolean; + onChangeDatasetFilter: (datasetFilter: DatasetFilter) => void; +}> = ({ availableDatasets, datasetFilter, isDisabled, onChangeDatasetFilter }) => { + const { isVisible, hide, show } = useVisibilityState(false); + + const changeDatasetFilter = useCallback( + (options: EuiSelectableOption[]) => { + const selectedDatasets = options + .filter(({ checked }) => checked === 'on') + .map(({ label }) => label); + + onChangeDatasetFilter( + selectedDatasets.length === 0 + ? { type: 'includeAll' } + : { type: 'includeSome', datasets: selectedDatasets } + ); + }, + [onChangeDatasetFilter] + ); + + const selectableOptions: EuiSelectableOption[] = useMemo( + () => + availableDatasets.map(datasetName => ({ + label: datasetName, + checked: + datasetFilter.type === 'includeSome' && datasetFilter.datasets.includes(datasetName) + ? 'on' + : undefined, + })), + [availableDatasets, datasetFilter] + ); + + const datasetFilterButton = ( + + + + ); + + return ( + + + + {(list, search) => ( +
+ {search} + {list} +
+ )} +
+
+
+ ); +}; diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/index_setup_row.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/index_setup_row.tsx new file mode 100644 index 0000000000000..18dc2e5aa9bd1 --- /dev/null +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/index_setup_row.tsx @@ -0,0 +1,110 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EuiCheckbox, EuiCode, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiToolTip } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import React, { useCallback } from 'react'; +import { DatasetFilter } from '../../../../../common/log_analysis'; +import { IndexSetupDatasetFilter } from './index_setup_dataset_filter'; +import { AvailableIndex, ValidationIndicesUIError } from './validation'; + +export const IndexSetupRow: React.FC<{ + index: AvailableIndex; + isDisabled: boolean; + onChangeDatasetFilter: (indexName: string, datasetFilter: DatasetFilter) => void; + onChangeIsSelected: (indexName: string, isSelected: boolean) => void; +}> = ({ index, isDisabled, onChangeDatasetFilter, onChangeIsSelected }) => { + const changeIsSelected = useCallback( + (event: React.ChangeEvent) => { + onChangeIsSelected(index.name, event.currentTarget.checked); + }, + [index.name, onChangeIsSelected] + ); + + const changeDatasetFilter = useCallback( + (datasetFilter: DatasetFilter) => onChangeDatasetFilter(index.name, datasetFilter), + [index.name, onChangeDatasetFilter] + ); + + const isSelected = index.validity === 'valid' && index.isSelected; + + return ( + + + {index.name}} + onChange={changeIsSelected} + checked={isSelected} + disabled={isDisabled || index.validity === 'invalid'} + /> + + + {index.validity === 'invalid' ? ( + + + + ) : index.validity === 'valid' ? ( + + ) : null} + + + ); +}; + +const formatValidationError = (errors: ValidationIndicesUIError[]): React.ReactNode => { + return errors.map(error => { + switch (error.error) { + case 'INDEX_NOT_FOUND': + return ( +

+ {error.index} }} + /> +

+ ); + + case 'FIELD_NOT_FOUND': + return ( +

+ {error.index}, + field: {error.field}, + }} + /> +

+ ); + + case 'FIELD_NOT_VALID': + return ( +

+ {error.index}, + field: {error.field}, + }} + /> +

+ ); + + default: + return ''; + } + }); +}; diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/initial_configuration_step.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/initial_configuration_step.tsx index 4ec895dfed4bc..85aa7ce513248 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/initial_configuration_step.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/initial_configuration_step.tsx @@ -13,7 +13,7 @@ import React, { useMemo } from 'react'; import { SetupStatus } from '../../../../../common/log_analysis'; import { AnalysisSetupIndicesForm } from './analysis_setup_indices_form'; import { AnalysisSetupTimerangeForm } from './analysis_setup_timerange_form'; -import { ValidatedIndex, ValidationIndicesUIError } from './validation'; +import { AvailableIndex, ValidationIndicesUIError } from './validation'; interface InitialConfigurationStepProps { setStartTime: (startTime: number | undefined) => void; @@ -21,9 +21,9 @@ interface InitialConfigurationStepProps { startTime: number | undefined; endTime: number | undefined; isValidating: boolean; - validatedIndices: ValidatedIndex[]; + validatedIndices: AvailableIndex[]; setupStatus: SetupStatus; - setValidatedIndices: (selectedIndices: ValidatedIndex[]) => void; + setValidatedIndices: (selectedIndices: AvailableIndex[]) => void; validationErrors?: ValidationIndicesUIError[]; } diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/validation.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/validation.tsx index 8b733f66ef4a8..d69e544aeab18 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/validation.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_setup/initial_configuration_step/validation.tsx @@ -5,22 +5,35 @@ */ import { ValidationIndicesError } from '../../../../../common/http_api'; +import { DatasetFilter } from '../../../../../common/log_analysis'; + +export { ValidationIndicesError }; export type ValidationIndicesUIError = | ValidationIndicesError | { error: 'NETWORK_ERROR' } | { error: 'TOO_FEW_SELECTED_INDICES' }; -interface ValidIndex { +interface ValidAvailableIndex { validity: 'valid'; name: string; isSelected: boolean; + availableDatasets: string[]; + datasetFilter: DatasetFilter; } -interface InvalidIndex { +interface InvalidAvailableIndex { validity: 'invalid'; name: string; errors: ValidationIndicesError[]; } -export type ValidatedIndex = ValidIndex | InvalidIndex; +interface UnvalidatedAvailableIndex { + validity: 'unknown'; + name: string; +} + +export type AvailableIndex = + | ValidAvailableIndex + | InvalidAvailableIndex + | UnvalidatedAvailableIndex; diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_setup_module_api.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_setup_module_api.ts index b1265b389917e..7c8d63374924c 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_setup_module_api.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_setup_module_api.ts @@ -21,7 +21,8 @@ export const callSetupMlModuleAPI = async ( sourceId: string, indexPattern: string, jobOverrides: SetupMlModuleJobOverrides[] = [], - datafeedOverrides: SetupMlModuleDatafeedOverrides[] = [] + datafeedOverrides: SetupMlModuleDatafeedOverrides[] = [], + query?: object ) => { const response = await npStart.http.fetch(`/api/ml/modules/setup/${moduleId}`, { method: 'POST', @@ -34,6 +35,7 @@ export const callSetupMlModuleAPI = async ( startDatafeed: true, jobOverrides, datafeedOverrides, + query, }) ), }); @@ -60,13 +62,20 @@ const setupMlModuleDatafeedOverridesRT = rt.object; export type SetupMlModuleDatafeedOverrides = rt.TypeOf; -const setupMlModuleRequestParamsRT = rt.type({ - indexPatternName: rt.string, - prefix: rt.string, - startDatafeed: rt.boolean, - jobOverrides: rt.array(setupMlModuleJobOverridesRT), - datafeedOverrides: rt.array(setupMlModuleDatafeedOverridesRT), -}); +const setupMlModuleRequestParamsRT = rt.intersection([ + rt.strict({ + indexPatternName: rt.string, + prefix: rt.string, + startDatafeed: rt.boolean, + jobOverrides: rt.array(setupMlModuleJobOverridesRT), + datafeedOverrides: rt.array(setupMlModuleDatafeedOverridesRT), + }), + rt.exact( + rt.partial({ + query: rt.object, + }) + ), +]); const setupMlModuleRequestPayloadRT = rt.intersection([ setupMlModuleTimeParamsRT, diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/validate_datasets.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/validate_datasets.ts new file mode 100644 index 0000000000000..6c9d5e439d359 --- /dev/null +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/validate_datasets.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + LOG_ANALYSIS_VALIDATE_DATASETS_PATH, + validateLogEntryDatasetsRequestPayloadRT, + validateLogEntryDatasetsResponsePayloadRT, +} from '../../../../../common/http_api'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; +import { npStart } from '../../../../legacy_singletons'; + +export const callValidateDatasetsAPI = async ( + indices: string[], + timestampField: string, + startTime: number, + endTime: number +) => { + const response = await npStart.http.fetch(LOG_ANALYSIS_VALIDATE_DATASETS_PATH, { + method: 'POST', + body: JSON.stringify( + validateLogEntryDatasetsRequestPayloadRT.encode({ + data: { + endTime, + indices, + startTime, + timestampField, + }, + }) + ), + }); + + return decodeOrThrow(validateLogEntryDatasetsResponsePayloadRT)(response); +}; diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module.tsx b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module.tsx index 99c5a3df7c9b1..cecfea28100ad 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module.tsx @@ -5,7 +5,7 @@ */ import { useCallback, useMemo } from 'react'; - +import { DatasetFilter } from '../../../../common/log_analysis'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { useModuleStatus } from './log_analysis_module_status'; import { ModuleDescriptor, ModuleSourceConfiguration } from './log_analysis_module_types'; @@ -48,10 +48,11 @@ export const useLogAnalysisModule = ({ createPromise: async ( selectedIndices: string[], start: number | undefined, - end: number | undefined + end: number | undefined, + datasetFilter: DatasetFilter ) => { dispatchModuleStatus({ type: 'startedSetup' }); - const setupResult = await moduleDescriptor.setUpModule(start, end, { + const setupResult = await moduleDescriptor.setUpModule(start, end, datasetFilter, { indices: selectedIndices, sourceId, spaceId, @@ -92,11 +93,16 @@ export const useLogAnalysisModule = ({ ]); const cleanUpAndSetUpModule = useCallback( - (selectedIndices: string[], start: number | undefined, end: number | undefined) => { + ( + selectedIndices: string[], + start: number | undefined, + end: number | undefined, + datasetFilter: DatasetFilter + ) => { dispatchModuleStatus({ type: 'startedSetup' }); cleanUpModule() .then(() => { - setUpModule(selectedIndices, start, end); + setUpModule(selectedIndices, start, end, datasetFilter); }) .catch(() => { dispatchModuleStatus({ type: 'failedSetup' }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_types.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_types.ts index dc9f25b492635..cc9ef73019844 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_types.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_types.ts @@ -8,7 +8,11 @@ import { DeleteJobsResponsePayload } from './api/ml_cleanup'; import { FetchJobStatusResponsePayload } from './api/ml_get_jobs_summary_api'; import { GetMlModuleResponsePayload } from './api/ml_get_module'; import { SetupMlModuleResponsePayload } from './api/ml_setup_module_api'; -import { ValidationIndicesResponsePayload } from '../../../../common/http_api/log_analysis'; +import { + ValidationIndicesResponsePayload, + ValidateLogEntryDatasetsResponsePayload, +} from '../../../../common/http_api/log_analysis'; +import { DatasetFilter } from '../../../../common/log_analysis'; export interface ModuleDescriptor { moduleId: string; @@ -20,12 +24,20 @@ export interface ModuleDescriptor { setUpModule: ( start: number | undefined, end: number | undefined, + datasetFilter: DatasetFilter, sourceConfiguration: ModuleSourceConfiguration ) => Promise; cleanUpModule: (spaceId: string, sourceId: string) => Promise; validateSetupIndices: ( - sourceConfiguration: ModuleSourceConfiguration + indices: string[], + timestampField: string ) => Promise; + validateSetupDatasets: ( + indices: string[], + timestampField: string, + startTime: number, + endTime: number + ) => Promise; } export interface ModuleSourceConfiguration { diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_setup_state.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_setup_state.ts new file mode 100644 index 0000000000000..d46e8bc2485f6 --- /dev/null +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_setup_state.ts @@ -0,0 +1,264 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { isEqual } from 'lodash'; +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { usePrevious } from 'react-use'; +import { + combineDatasetFilters, + DatasetFilter, + filterDatasetFilter, + isExampleDataIndex, +} from '../../../../common/log_analysis'; +import { + AvailableIndex, + ValidationIndicesError, + ValidationIndicesUIError, +} from '../../../components/logging/log_analysis_setup/initial_configuration_step'; +import { useTrackedPromise } from '../../../utils/use_tracked_promise'; +import { ModuleDescriptor, ModuleSourceConfiguration } from './log_analysis_module_types'; + +type SetupHandler = ( + indices: string[], + startTime: number | undefined, + endTime: number | undefined, + datasetFilter: DatasetFilter +) => void; + +interface AnalysisSetupStateArguments { + cleanUpAndSetUpModule: SetupHandler; + moduleDescriptor: ModuleDescriptor; + setUpModule: SetupHandler; + sourceConfiguration: ModuleSourceConfiguration; +} + +const fourWeeksInMs = 86400000 * 7 * 4; + +export const useAnalysisSetupState = ({ + cleanUpAndSetUpModule, + moduleDescriptor: { validateSetupDatasets, validateSetupIndices }, + setUpModule, + sourceConfiguration, +}: AnalysisSetupStateArguments) => { + const [startTime, setStartTime] = useState(Date.now() - fourWeeksInMs); + const [endTime, setEndTime] = useState(undefined); + + const [validatedIndices, setValidatedIndices] = useState( + sourceConfiguration.indices.map(indexName => ({ + name: indexName, + validity: 'unknown' as const, + })) + ); + + const updateIndicesWithValidationErrors = useCallback( + (validationErrors: ValidationIndicesError[]) => + setValidatedIndices(availableIndices => + availableIndices.map(previousAvailableIndex => { + const indexValiationErrors = validationErrors.filter( + ({ index }) => index === previousAvailableIndex.name + ); + + if (indexValiationErrors.length > 0) { + return { + validity: 'invalid', + name: previousAvailableIndex.name, + errors: indexValiationErrors, + }; + } else if (previousAvailableIndex.validity === 'valid') { + return { + ...previousAvailableIndex, + validity: 'valid', + errors: [], + }; + } else { + return { + validity: 'valid', + name: previousAvailableIndex.name, + isSelected: !isExampleDataIndex(previousAvailableIndex.name), + availableDatasets: [], + datasetFilter: { + type: 'includeAll' as const, + }, + }; + } + }) + ), + [] + ); + + const updateIndicesWithAvailableDatasets = useCallback( + (availableDatasets: Array<{ indexName: string; datasets: string[] }>) => + setValidatedIndices(availableIndices => + availableIndices.map(previousAvailableIndex => { + if (previousAvailableIndex.validity !== 'valid') { + return previousAvailableIndex; + } + + const availableDatasetsForIndex = availableDatasets.filter( + ({ indexName }) => indexName === previousAvailableIndex.name + ); + const newAvailableDatasets = availableDatasetsForIndex.flatMap( + ({ datasets }) => datasets + ); + + // filter out datasets that have disappeared if this index' datasets were updated + const newDatasetFilter: DatasetFilter = + availableDatasetsForIndex.length > 0 + ? filterDatasetFilter(previousAvailableIndex.datasetFilter, dataset => + newAvailableDatasets.includes(dataset) + ) + : previousAvailableIndex.datasetFilter; + + return { + ...previousAvailableIndex, + availableDatasets: newAvailableDatasets, + datasetFilter: newDatasetFilter, + }; + }) + ), + [] + ); + + const validIndexNames = useMemo( + () => validatedIndices.filter(index => index.validity === 'valid').map(index => index.name), + [validatedIndices] + ); + + const selectedIndexNames = useMemo( + () => + validatedIndices + .filter(index => index.validity === 'valid' && index.isSelected) + .map(i => i.name), + [validatedIndices] + ); + + const datasetFilter = useMemo( + () => + validatedIndices + .flatMap(validatedIndex => + validatedIndex.validity === 'valid' + ? validatedIndex.datasetFilter + : { type: 'includeAll' as const } + ) + .reduce(combineDatasetFilters, { type: 'includeAll' as const }), + [validatedIndices] + ); + + const [validateIndicesRequest, validateIndices] = useTrackedPromise( + { + cancelPreviousOn: 'resolution', + createPromise: async () => { + return await validateSetupIndices( + sourceConfiguration.indices, + sourceConfiguration.timestampField + ); + }, + onResolve: ({ data: { errors } }) => { + updateIndicesWithValidationErrors(errors); + }, + onReject: () => { + setValidatedIndices([]); + }, + }, + [sourceConfiguration.indices, sourceConfiguration.timestampField] + ); + + const [validateDatasetsRequest, validateDatasets] = useTrackedPromise( + { + cancelPreviousOn: 'resolution', + createPromise: async () => { + if (validIndexNames.length === 0) { + return { data: { datasets: [] } }; + } + + return await validateSetupDatasets( + validIndexNames, + sourceConfiguration.timestampField, + startTime ?? 0, + endTime ?? Date.now() + ); + }, + onResolve: ({ data: { datasets } }) => { + updateIndicesWithAvailableDatasets(datasets); + }, + }, + [validIndexNames, sourceConfiguration.timestampField, startTime, endTime] + ); + + const setUp = useCallback(() => { + return setUpModule(selectedIndexNames, startTime, endTime, datasetFilter); + }, [setUpModule, selectedIndexNames, startTime, endTime, datasetFilter]); + + const cleanUpAndSetUp = useCallback(() => { + return cleanUpAndSetUpModule(selectedIndexNames, startTime, endTime, datasetFilter); + }, [cleanUpAndSetUpModule, selectedIndexNames, startTime, endTime, datasetFilter]); + + const isValidating = useMemo( + () => validateIndicesRequest.state === 'pending' || validateDatasetsRequest.state === 'pending', + [validateDatasetsRequest.state, validateIndicesRequest.state] + ); + + const validationErrors = useMemo(() => { + if (isValidating) { + return []; + } + + if (validateIndicesRequest.state === 'rejected') { + return [{ error: 'NETWORK_ERROR' }]; + } + + if (selectedIndexNames.length === 0) { + return [{ error: 'TOO_FEW_SELECTED_INDICES' }]; + } + + return validatedIndices.reduce((errors, index) => { + return index.validity === 'invalid' && selectedIndexNames.includes(index.name) + ? [...errors, ...index.errors] + : errors; + }, []); + }, [isValidating, validateIndicesRequest.state, selectedIndexNames, validatedIndices]); + + const prevStartTime = usePrevious(startTime); + const prevEndTime = usePrevious(endTime); + const prevValidIndexNames = usePrevious(validIndexNames); + + useEffect(() => { + validateIndices(); + }, [validateIndices]); + + useEffect(() => { + if ( + startTime !== prevStartTime || + endTime !== prevEndTime || + !isEqual(validIndexNames, prevValidIndexNames) + ) { + validateDatasets(); + } + }, [ + endTime, + prevEndTime, + prevStartTime, + prevValidIndexNames, + startTime, + validIndexNames, + validateDatasets, + ]); + + return { + cleanUpAndSetUp, + datasetFilter, + endTime, + isValidating, + selectedIndexNames, + setEndTime, + setStartTime, + setUp, + startTime, + validatedIndices, + setValidatedIndices, + validationErrors, + }; +}; diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_setup_state.tsx b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_setup_state.tsx deleted file mode 100644 index 9f966ed3342e6..0000000000000 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_setup_state.tsx +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { useCallback, useEffect, useMemo, useState } from 'react'; - -import { isExampleDataIndex } from '../../../../common/log_analysis'; -import { - ValidatedIndex, - ValidationIndicesUIError, -} from '../../../components/logging/log_analysis_setup/initial_configuration_step'; -import { useTrackedPromise } from '../../../utils/use_tracked_promise'; -import { ModuleDescriptor, ModuleSourceConfiguration } from './log_analysis_module_types'; - -type SetupHandler = ( - indices: string[], - startTime: number | undefined, - endTime: number | undefined -) => void; - -interface AnalysisSetupStateArguments { - cleanUpAndSetUpModule: SetupHandler; - moduleDescriptor: ModuleDescriptor; - setUpModule: SetupHandler; - sourceConfiguration: ModuleSourceConfiguration; -} - -const fourWeeksInMs = 86400000 * 7 * 4; - -export const useAnalysisSetupState = ({ - cleanUpAndSetUpModule, - moduleDescriptor: { validateSetupIndices }, - setUpModule, - sourceConfiguration, -}: AnalysisSetupStateArguments) => { - const [startTime, setStartTime] = useState(Date.now() - fourWeeksInMs); - const [endTime, setEndTime] = useState(undefined); - - const [validatedIndices, setValidatedIndices] = useState([]); - - const [validateIndicesRequest, validateIndices] = useTrackedPromise( - { - cancelPreviousOn: 'resolution', - createPromise: async () => { - return await validateSetupIndices(sourceConfiguration); - }, - onResolve: ({ data: { errors } }) => { - setValidatedIndices(previousValidatedIndices => - sourceConfiguration.indices.map(indexName => { - const previousValidatedIndex = previousValidatedIndices.filter( - ({ name }) => name === indexName - )[0]; - const indexValiationErrors = errors.filter(({ index }) => index === indexName); - if (indexValiationErrors.length > 0) { - return { - validity: 'invalid', - name: indexName, - errors: indexValiationErrors, - }; - } else { - return { - validity: 'valid', - name: indexName, - isSelected: - previousValidatedIndex?.validity === 'valid' - ? previousValidatedIndex?.isSelected - : !isExampleDataIndex(indexName), - }; - } - }) - ); - }, - onReject: () => { - setValidatedIndices([]); - }, - }, - [sourceConfiguration.indices] - ); - - useEffect(() => { - validateIndices(); - }, [validateIndices]); - - const selectedIndexNames = useMemo( - () => - validatedIndices - .filter(index => index.validity === 'valid' && index.isSelected) - .map(i => i.name), - [validatedIndices] - ); - - const setUp = useCallback(() => { - return setUpModule(selectedIndexNames, startTime, endTime); - }, [setUpModule, selectedIndexNames, startTime, endTime]); - - const cleanUpAndSetUp = useCallback(() => { - return cleanUpAndSetUpModule(selectedIndexNames, startTime, endTime); - }, [cleanUpAndSetUpModule, selectedIndexNames, startTime, endTime]); - - const isValidating = useMemo( - () => - validateIndicesRequest.state === 'pending' || - validateIndicesRequest.state === 'uninitialized', - [validateIndicesRequest.state] - ); - - const validationErrors = useMemo(() => { - if (isValidating) { - return []; - } - - if (validateIndicesRequest.state === 'rejected') { - return [{ error: 'NETWORK_ERROR' }]; - } - - if (selectedIndexNames.length === 0) { - return [{ error: 'TOO_FEW_SELECTED_INDICES' }]; - } - - return validatedIndices.reduce((errors, index) => { - return index.validity === 'invalid' && selectedIndexNames.includes(index.name) - ? [...errors, ...index.errors] - : errors; - }, []); - }, [isValidating, validateIndicesRequest.state, selectedIndexNames, validatedIndices]); - - return { - cleanUpAndSetUp, - endTime, - isValidating, - selectedIndexNames, - setEndTime, - setStartTime, - setUp, - startTime, - validatedIndices, - setValidatedIndices, - validationErrors, - }; -}; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/module_descriptor.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/module_descriptor.ts index be7547f2e74cb..45cdd28bd943b 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/module_descriptor.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/module_descriptor.ts @@ -7,20 +7,21 @@ import { bucketSpan, categoriesMessageField, + DatasetFilter, getJobId, LogEntryCategoriesJobType, logEntryCategoriesJobTypes, partitionField, } from '../../../../common/log_analysis'; - import { + cleanUpJobsAndDatafeeds, ModuleDescriptor, ModuleSourceConfiguration, - cleanUpJobsAndDatafeeds, } from '../../../containers/logs/log_analysis'; import { callJobsSummaryAPI } from '../../../containers/logs/log_analysis/api/ml_get_jobs_summary_api'; import { callGetMlModuleAPI } from '../../../containers/logs/log_analysis/api/ml_get_module'; import { callSetupMlModuleAPI } from '../../../containers/logs/log_analysis/api/ml_setup_module_api'; +import { callValidateDatasetsAPI } from '../../../containers/logs/log_analysis/api/validate_datasets'; import { callValidateIndicesAPI } from '../../../containers/logs/log_analysis/api/validate_indices'; const moduleId = 'logs_ui_categories'; @@ -48,6 +49,7 @@ const getModuleDefinition = async () => { const setUpModule = async ( start: number | undefined, end: number | undefined, + datasetFilter: DatasetFilter, { spaceId, sourceId, indices, timestampField }: ModuleSourceConfiguration ) => { const indexNamePattern = indices.join(','); @@ -65,10 +67,31 @@ const setUpModule = async ( indexPattern: indexNamePattern, timestampField, bucketSpan, + datasetFilter, }, }, }, ]; + const query = { + bool: { + filter: [ + ...(datasetFilter.type === 'includeSome' + ? [ + { + terms: { + 'event.dataset': datasetFilter.datasets, + }, + }, + ] + : []), + { + exists: { + field: 'message', + }, + }, + ], + }, + }; return callSetupMlModuleAPI( moduleId, @@ -77,7 +100,9 @@ const setUpModule = async ( spaceId, sourceId, indexNamePattern, - jobOverrides + jobOverrides, + [], + query ); }; @@ -85,7 +110,7 @@ const cleanUpModule = async (spaceId: string, sourceId: string) => { return await cleanUpJobsAndDatafeeds(spaceId, sourceId, logEntryCategoriesJobTypes); }; -const validateSetupIndices = async ({ indices, timestampField }: ModuleSourceConfiguration) => { +const validateSetupIndices = async (indices: string[], timestampField: string) => { return await callValidateIndicesAPI(indices, [ { name: timestampField, @@ -102,6 +127,15 @@ const validateSetupIndices = async ({ indices, timestampField }: ModuleSourceCon ]); }; +const validateSetupDatasets = async ( + indices: string[], + timestampField: string, + startTime: number, + endTime: number +) => { + return await callValidateDatasetsAPI(indices, timestampField, startTime, endTime); +}; + export const logEntryCategoriesModule: ModuleDescriptor = { moduleId, jobTypes: logEntryCategoriesJobTypes, @@ -111,5 +145,6 @@ export const logEntryCategoriesModule: ModuleDescriptor { createProcessStep({ cleanUpAndSetUp, errorMessages: lastSetupErrorMessages, - isConfigurationValid: validationErrors.length <= 0, + isConfigurationValid: validationErrors.length <= 0 && !isValidating, setUp, setupStatus, viewResults, diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/module_descriptor.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/module_descriptor.ts index 52ba3101dbc38..dfd427138aaa6 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/module_descriptor.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/module_descriptor.ts @@ -6,20 +6,21 @@ import { bucketSpan, + DatasetFilter, getJobId, LogEntryRateJobType, logEntryRateJobTypes, partitionField, } from '../../../../common/log_analysis'; - import { + cleanUpJobsAndDatafeeds, ModuleDescriptor, ModuleSourceConfiguration, - cleanUpJobsAndDatafeeds, } from '../../../containers/logs/log_analysis'; import { callJobsSummaryAPI } from '../../../containers/logs/log_analysis/api/ml_get_jobs_summary_api'; import { callGetMlModuleAPI } from '../../../containers/logs/log_analysis/api/ml_get_module'; import { callSetupMlModuleAPI } from '../../../containers/logs/log_analysis/api/ml_setup_module_api'; +import { callValidateDatasetsAPI } from '../../../containers/logs/log_analysis/api/validate_datasets'; import { callValidateIndicesAPI } from '../../../containers/logs/log_analysis/api/validate_indices'; const moduleId = 'logs_ui_analysis'; @@ -47,6 +48,7 @@ const getModuleDefinition = async () => { const setUpModule = async ( start: number | undefined, end: number | undefined, + datasetFilter: DatasetFilter, { spaceId, sourceId, indices, timestampField }: ModuleSourceConfiguration ) => { const indexNamePattern = indices.join(','); @@ -68,6 +70,20 @@ const setUpModule = async ( }, }, ]; + const query = + datasetFilter.type === 'includeSome' + ? { + bool: { + filter: [ + { + terms: { + 'event.dataset': datasetFilter.datasets, + }, + }, + ], + }, + } + : undefined; return callSetupMlModuleAPI( moduleId, @@ -76,7 +92,9 @@ const setUpModule = async ( spaceId, sourceId, indexNamePattern, - jobOverrides + jobOverrides, + [], + query ); }; @@ -84,7 +102,7 @@ const cleanUpModule = async (spaceId: string, sourceId: string) => { return await cleanUpJobsAndDatafeeds(spaceId, sourceId, logEntryRateJobTypes); }; -const validateSetupIndices = async ({ indices, timestampField }: ModuleSourceConfiguration) => { +const validateSetupIndices = async (indices: string[], timestampField: string) => { return await callValidateIndicesAPI(indices, [ { name: timestampField, @@ -97,6 +115,15 @@ const validateSetupIndices = async ({ indices, timestampField }: ModuleSourceCon ]); }; +const validateSetupDatasets = async ( + indices: string[], + timestampField: string, + startTime: number, + endTime: number +) => { + return await callValidateDatasetsAPI(indices, timestampField, startTime, endTime); +}; + export const logEntryRateModule: ModuleDescriptor = { moduleId, jobTypes: logEntryRateJobTypes, @@ -106,5 +133,6 @@ export const logEntryRateModule: ModuleDescriptor = { getModuleDefinition, setUpModule, cleanUpModule, + validateSetupDatasets, validateSetupIndices, }; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_setup_content.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_setup_content.tsx index a02dbfa941588..e5c439808115d 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_setup_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/page_setup_content.tsx @@ -55,7 +55,7 @@ export const LogEntryRateSetupContent: React.FunctionComponent = () => { createProcessStep({ cleanUpAndSetUp, errorMessages: lastSetupErrorMessages, - isConfigurationValid: validationErrors.length <= 0, + isConfigurationValid: validationErrors.length <= 0 && !isValidating, setUp, setupStatus, viewResults, diff --git a/x-pack/plugins/infra/server/infra_server.ts b/x-pack/plugins/infra/server/infra_server.ts index 4ed30380dc164..06135c6532d77 100644 --- a/x-pack/plugins/infra/server/infra_server.ts +++ b/x-pack/plugins/infra/server/infra_server.ts @@ -15,6 +15,7 @@ import { initGetLogEntryCategoryDatasetsRoute, initGetLogEntryCategoryExamplesRoute, initGetLogEntryRateRoute, + initValidateLogAnalysisDatasetsRoute, initValidateLogAnalysisIndicesRoute, } from './routes/log_analysis'; import { initMetricExplorerRoute } from './routes/metrics_explorer'; @@ -51,6 +52,7 @@ export const initInfraServer = (libs: InfraBackendLibs) => { initSnapshotRoute(libs); initNodeDetailsRoute(libs); initSourceRoute(libs); + initValidateLogAnalysisDatasetsRoute(libs); initValidateLogAnalysisIndicesRoute(libs); initLogEntriesRoute(libs); initLogEntriesHighlightsRoute(libs); diff --git a/x-pack/plugins/infra/server/lib/compose/kibana.ts b/x-pack/plugins/infra/server/lib/compose/kibana.ts index d22ca2961cfa5..626b9d46bbde3 100644 --- a/x-pack/plugins/infra/server/lib/compose/kibana.ts +++ b/x-pack/plugins/infra/server/lib/compose/kibana.ts @@ -38,6 +38,7 @@ export function compose(core: CoreSetup, config: InfraConfig, plugins: InfraServ sources, }), logEntries: new InfraLogEntriesDomain(new InfraKibanaLogEntriesAdapter(framework), { + framework, sources, }), metrics: new InfraMetricsDomain(new KibanaMetricsAdapter(framework)), diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts index 07bc965dda77a..15bfbce6d512e 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts @@ -29,6 +29,14 @@ import { Highlights, compileFormattingRules, } from './message'; +import { KibanaFramework } from '../../adapters/framework/kibana_framework_adapter'; +import { decodeOrThrow } from '../../../../common/runtime_types'; +import { + logEntryDatasetsResponseRT, + LogEntryDatasetBucket, + CompositeDatasetKey, + createLogEntryDatasetsQuery, +} from './queries/log_entry_datasets'; export interface LogEntriesParams { startTimestamp: number; @@ -51,10 +59,15 @@ export const LOG_ENTRIES_PAGE_SIZE = 200; const FIELDS_FROM_CONTEXT = ['log.file.path', 'host.name', 'container.id'] as const; +const COMPOSITE_AGGREGATION_BATCH_SIZE = 1000; + export class InfraLogEntriesDomain { constructor( private readonly adapter: LogEntriesAdapter, - private readonly libs: { sources: InfraSources } + private readonly libs: { + framework: KibanaFramework; + sources: InfraSources; + } ) {} public async getLogEntriesAround( @@ -256,6 +269,45 @@ export class InfraLogEntriesDomain { ), }; } + + public async getLogEntryDatasets( + requestContext: RequestHandlerContext, + timestampField: string, + indexName: string, + startTime: number, + endTime: number + ) { + let datasetBuckets: LogEntryDatasetBucket[] = []; + let afterLatestBatchKey: CompositeDatasetKey | undefined; + + while (true) { + const datasetsReponse = await this.libs.framework.callWithRequest( + requestContext, + 'search', + createLogEntryDatasetsQuery( + indexName, + timestampField, + startTime, + endTime, + COMPOSITE_AGGREGATION_BATCH_SIZE, + afterLatestBatchKey + ) + ); + + const { after_key: afterKey, buckets: latestBatchBuckets } = decodeOrThrow( + logEntryDatasetsResponseRT + )(datasetsReponse).aggregations.dataset_buckets; + + datasetBuckets = [...datasetBuckets, ...latestBatchBuckets]; + afterLatestBatchKey = afterKey; + + if (latestBatchBuckets.length < COMPOSITE_AGGREGATION_BATCH_SIZE) { + break; + } + } + + return datasetBuckets.map(({ key: { dataset } }) => dataset); + } } interface LogItemHit { diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts new file mode 100644 index 0000000000000..1df7072904f68 --- /dev/null +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/queries/log_entry_datasets.ts @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as rt from 'io-ts'; + +import { commonSearchSuccessResponseFieldsRT } from '../../../../utils/elasticsearch_runtime_types'; + +export const createLogEntryDatasetsQuery = ( + indexName: string, + timestampField: string, + startTime: number, + endTime: number, + size: number, + afterKey?: CompositeDatasetKey +) => ({ + ...defaultRequestParameters, + body: { + query: { + bool: { + filter: [ + { + range: { + [timestampField]: { + gte: startTime, + lte: endTime, + }, + }, + }, + { + exists: { + field: 'event.dataset', + }, + }, + ], + }, + }, + aggs: { + dataset_buckets: { + composite: { + after: afterKey, + size, + sources: [ + { + dataset: { + terms: { + field: 'event.dataset', + order: 'asc', + }, + }, + }, + ], + }, + }, + }, + }, + index: indexName, + size: 0, +}); + +const defaultRequestParameters = { + allowNoIndices: true, + ignoreUnavailable: true, + trackScores: false, + trackTotalHits: false, +}; + +const compositeDatasetKeyRT = rt.type({ + dataset: rt.string, +}); + +export type CompositeDatasetKey = rt.TypeOf; + +const logEntryDatasetBucketRT = rt.type({ + key: compositeDatasetKeyRT, +}); + +export type LogEntryDatasetBucket = rt.TypeOf; + +export const logEntryDatasetsResponseRT = rt.intersection([ + commonSearchSuccessResponseFieldsRT, + rt.type({ + aggregations: rt.type({ + dataset_buckets: rt.intersection([ + rt.type({ + buckets: rt.array(logEntryDatasetBucketRT), + }), + rt.partial({ + after_key: compositeDatasetKeyRT, + }), + ]), + }), + }), +]); + +export type LogEntryDatasetsResponse = rt.TypeOf; diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts index db34033c1d4f8..13446594ab114 100644 --- a/x-pack/plugins/infra/server/plugin.ts +++ b/x-pack/plugins/infra/server/plugin.ts @@ -119,6 +119,7 @@ export class InfraServerPlugin { sources, }), logEntries: new InfraLogEntriesDomain(new InfraKibanaLogEntriesAdapter(framework), { + framework, sources, }), metrics: new InfraMetricsDomain(new KibanaMetricsAdapter(framework)), diff --git a/x-pack/plugins/infra/server/routes/log_analysis/validation/datasets.ts b/x-pack/plugins/infra/server/routes/log_analysis/validation/datasets.ts new file mode 100644 index 0000000000000..d772c000986fc --- /dev/null +++ b/x-pack/plugins/infra/server/routes/log_analysis/validation/datasets.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import Boom from 'boom'; + +import { InfraBackendLibs } from '../../../lib/infra_types'; +import { + LOG_ANALYSIS_VALIDATE_DATASETS_PATH, + validateLogEntryDatasetsRequestPayloadRT, + validateLogEntryDatasetsResponsePayloadRT, +} from '../../../../common/http_api'; + +import { createValidationFunction } from '../../../../common/runtime_types'; + +export const initValidateLogAnalysisDatasetsRoute = ({ + framework, + logEntries, +}: InfraBackendLibs) => { + framework.registerRoute( + { + method: 'post', + path: LOG_ANALYSIS_VALIDATE_DATASETS_PATH, + validate: { + body: createValidationFunction(validateLogEntryDatasetsRequestPayloadRT), + }, + }, + framework.router.handleLegacyErrors(async (requestContext, request, response) => { + try { + const { + data: { indices, timestampField, startTime, endTime }, + } = request.body; + + const datasets = await Promise.all( + indices.map(async indexName => { + const indexDatasets = await logEntries.getLogEntryDatasets( + requestContext, + timestampField, + indexName, + startTime, + endTime + ); + + return { + indexName, + datasets: indexDatasets, + }; + }) + ); + + return response.ok({ + body: validateLogEntryDatasetsResponsePayloadRT.encode({ data: { datasets } }), + }); + } catch (error) { + if (Boom.isBoom(error)) { + throw error; + } + + return response.customError({ + statusCode: error.statusCode ?? 500, + body: { + message: error.message ?? 'An unexpected error occurred', + }, + }); + } + }) + ); +}; diff --git a/x-pack/plugins/infra/server/routes/log_analysis/validation/index.ts b/x-pack/plugins/infra/server/routes/log_analysis/validation/index.ts index 727faca69298e..10c39f9552a3a 100644 --- a/x-pack/plugins/infra/server/routes/log_analysis/validation/index.ts +++ b/x-pack/plugins/infra/server/routes/log_analysis/validation/index.ts @@ -4,4 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ +export * from './datasets'; export * from './indices'; diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/logs_ui_categories/ml/datafeed_log_entry_categories_count.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/logs_ui_categories/ml/datafeed_log_entry_categories_count.json index 6e117b4de87ea..2ece259e2bb45 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/logs_ui_categories/ml/datafeed_log_entry_categories_count.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/logs_ui_categories/ml/datafeed_log_entry_categories_count.json @@ -1,15 +1,4 @@ { "job_id": "JOB_ID", - "indices": ["INDEX_PATTERN_NAME"], - "query": { - "bool": { - "filter": [ - { - "exists": { - "field": "message" - } - } - ] - } - } + "indices": ["INDEX_PATTERN_NAME"] } From 34cccedc8e99d39308b534036df02e15d919fd73 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Mon, 4 May 2020 12:30:31 +0100 Subject: [PATCH 4/4] [Logs UI] [Alerting] Documentation (#64886) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Docs for logs alerts Co-authored-by: Felix Stürmer --- docs/logs/images/alert-actions-menu.png | Bin 0 -> 32575 bytes docs/logs/images/alert-flyout.png | Bin 0 -> 171358 bytes docs/logs/index.asciidoc | 3 +++ docs/logs/logs-alerting.asciidoc | 27 ++++++++++++++++++++++++ 4 files changed, 30 insertions(+) create mode 100644 docs/logs/images/alert-actions-menu.png create mode 100644 docs/logs/images/alert-flyout.png create mode 100644 docs/logs/logs-alerting.asciidoc diff --git a/docs/logs/images/alert-actions-menu.png b/docs/logs/images/alert-actions-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..3f96a700a0ac129d60f1bd3548ddb4b554e2f5b2 GIT binary patch literal 32575 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 Au>b%7 literal 0 HcmV?d00001 diff --git a/docs/logs/images/alert-flyout.png b/docs/logs/images/alert-flyout.png new file mode 100644 index 0000000000000000000000000000000000000000..30c8857758a8b4d39b448e5f4fd892b02270cfc2 GIT binary patch literal 171358 zcmbSzby!u~);A#Ch=8Po2nZVlq&uZSK)R$G>23k(E=fs|?hXSs-CbMh-qH=<;+%8O z<-B*Fe?FgwaIZDz9CP#-^EU}qQh0@hPJ#{x2ZtpsC9Vtyhd2!fha!cF41Ds7+a(7M z4pYiPOiW2yOpH>=!Oqme+5`?xDl}0YMMI^BFjHGu+T0&i3avGiS}OUWXgDS1n+m)* zVbM@lst?n6ufNuYqfQUM!IPLm=+>%CmZ&@pK}t+?t~3x^l}F#$I$gY6Ja20}9ZGe) zQDHk>B!+YP;;w9g{RKm~?5QFl5k)^qT3j!+06Z!s{PV{Mm~LK;3FM@tNZCh_TL!4D zuob=6eQ)pN|NNG!Z*RhY}ne%+C%Y0OV4)| zpI70}klbifQ`KkP+I*s?(#&9&93Y~T5G%oARmmiOQdIZV8eJlN!-q7LS|PO^>qncY zv|Gi;Cuu2E7~x~neGaSF$A%aZhPE}x>T977sbBK*o%6rBk;LUfquu%8L-EPWTGbbX z@K)+`lgmz(QrzbvBCF&zB(Q~-zO17m#|ihF6#TMrZ4v9|L(x-bOYrXRM82Hwn_K8v z2k;G#MFvIF8p}%m~4*GpxOtrDfGJAu`FD2ng+g<7 zC+`d2bAF@w<}Awh>*T3@>`sV>hQUko5WH_MISPIC*=vw_`*2e5>h-7y0*23?sveK z<0Iet_DdTM>fsfa?ua+smCD7%1-AE?#MgDFTSvIhx)7%mXSm^LxOXms`c!@D+wWF` z;Mx^JfkX0U_1DU#vHVK#H~stw_R044WDp>nKI)KA^T= ztysvXMS9Xmar|L4^JlzBAo1`KT5}|=z&&x&;pGjaBi`AlHet^feim=#`X4%eZDGYG z49qtqPQgqIN;F*6z*39m_L{CIzjqfI zqcwieQCJia6m1jrk=)DQP_|}hOL!dS#}-+YP!%*P*C@W3eWZN+`9#&%5`iO}H(5)h zv@kPgF}H1GbhK*pV1y)>cJgEHn@_c`wo4|(N~2$Tf5eXzBUMxxP8zNoi5jsTTO8hW z;`6{2NX&etFIt|Tl`WL*J8Wu>GqGlgQDbJMZoy@)KjKp)Hc~n9c3Wkw&eT}v5g#s%t<_F{xWSu~!K(;_#);%wkL&(mHn50`mC2 z{EK(_{23 z7B8kQUQjzNEt*`MB%UlT(JpDWVX~H->#r!PZZwjuJgy^{DXSDPx?CJwWS+70*UepU z^rZ1D^Zw+WaV>z-B$oaCQ3y$hRh0NEJFqp_IVw3ri4KP@RwZ$a)@*!cOmnAYu+awf z?S~=Uo|unRT)O7W*2!MUyvZSAsbaaogjhCY7Y-={72|LFLNbU?CMLdffStp)7k*uQ ze}%+i?Al^waA%i)E|h5glw z)nk2Kj0459+XeOht|h02&}u=%EQ72W!4NOO3y+Jn^S$HixuH&$IlB>_6LeYUPg)#kjn8KX68>0lx>ya_}Q`A|Kqln$^K|`oYiB7{#8v*9V(rUIfpAzq#glPyE7yKit zh~)64t=oJ=1N(l≠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∈*P`=OiFq!S}$wF0)W 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 * <> * <> +* <> [role="screenshot"] image::logs/images/logs-console.png[Log Console in Kibana] @@ -30,3 +31,5 @@ include::using.asciidoc[] include::configuring.asciidoc[] include::log-rate.asciidoc[] + +include::logs-alerting.asciidoc[] diff --git a/docs/logs/logs-alerting.asciidoc b/docs/logs/logs-alerting.asciidoc new file mode 100644 index 0000000000000..f08a09187a0c8 --- /dev/null +++ b/docs/logs/logs-alerting.asciidoc @@ -0,0 +1,27 @@ +[role="xpack"] +[[xpack-logs-alerting]] +== Logs alerting + +[float] +=== Overview + +To use the alerting functionality you need to {kibana-ref}/alerting-getting-started.html#alerting-setup-prerequisites[set up alerting]. + +You can then select the *Create alert* option, from the *Alerts* actions dropdown. + +[role="screenshot"] +image::logs/images/alert-actions-menu.png[Screenshot showing alerts menu] + +Within the alert flyout you can configure your logs alert: + +[role="screenshot"] +image::logs/images/alert-flyout.png[Screenshot showing alerts flyout] + +[float] +=== Fields and comparators + +The comparators available for conditions depend on the chosen field. The combinations available are: + +- Numeric fields: *more than*, *more than or equals*, *less than*, *less than or equals*, *equals*, and *does not equal*. +- Aggregatable fields: *is* and *is not*. +- Non-aggregatable fields: *matches*, *does not match*, *matches phrase*, *does not match phrase*.