+
Number(value).toFixed(0)}
+ tickFormat={value => numeral(value.toPrecision(3)).format('0[.][00]a')} // https://github.com/adamwdraper/Numeral-js/issues/194
/>
-
diff --git a/x-pack/legacy/plugins/infra/public/pages/logs/analysis/sections/log_rate/index.tsx b/x-pack/legacy/plugins/infra/public/pages/logs/analysis/sections/log_rate/index.tsx
index 1f01af33e33c4..d4ddd14bfaa28 100644
--- a/x-pack/legacy/plugins/infra/public/pages/logs/analysis/sections/log_rate/index.tsx
+++ b/x-pack/legacy/plugins/infra/public/pages/logs/analysis/sections/log_rate/index.tsx
@@ -11,13 +11,15 @@ import {
EuiLoadingChart,
EuiSpacer,
EuiTitle,
+ EuiText,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import React from 'react';
+import React, { useMemo } from 'react';
import { GetLogEntryRateSuccessResponsePayload } from '../../../../../../common/http_api/log_analysis/results/log_entry_rate';
import { TimeRange } from '../../../../../../common/http_api/shared/time_range';
import { LogEntryRateBarChart } from './bar_chart';
+import { getLogEntryRatePartitionedSeries } from '../helpers/data_formatters';
export const LogRateResults = ({
isLoading,
@@ -31,7 +33,7 @@ export const LogRateResults = ({
timeRange: TimeRange;
}) => {
const title = i18n.translate('xpack.infra.logs.analysis.logRateSectionTitle', {
- defaultMessage: 'Log rate',
+ defaultMessage: 'Log entries',
});
const loadingAriaLabel = i18n.translate(
@@ -39,43 +41,66 @@ export const LogRateResults = ({
{ defaultMessage: 'Loading log rate results' }
);
+ const logEntryRateSeries = useMemo(
+ () => (results && results.histogramBuckets ? getLogEntryRatePartitionedSeries(results) : []),
+ [results]
+ );
+
return (
<>
{title}
-
{isLoading ? (
-
-
-
-
-
+ <>
+
+
+
+
+
+
+ >
) : !results || (results && results.histogramBuckets && !results.histogramBuckets.length) ? (
-
- {i18n.translate('xpack.infra.logs.analysis.logRateSectionNoDataTitle', {
- defaultMessage: 'There is no data to display.',
- })}
-
- }
- titleSize="m"
- body={
+ <>
+
+
+ {i18n.translate('xpack.infra.logs.analysis.logRateSectionNoDataTitle', {
+ defaultMessage: 'There is no data to display.',
+ })}
+
+ }
+ titleSize="m"
+ body={
+
+ {i18n.translate('xpack.infra.logs.analysis.logRateSectionNoDataBody', {
+ defaultMessage: 'You may want to adjust your time range.',
+ })}
+
+ }
+ />
+ >
+ ) : (
+ <>
+
- {i18n.translate('xpack.infra.logs.analysis.logRateSectionNoDataBody', {
- defaultMessage: 'You may want to adjust your time range.',
+
+ {i18n.translate('xpack.infra.logs.analysis.logRateSectionBucketSpanLabel', {
+ defaultMessage: 'Bucket span: ',
+ })}
+
+ {i18n.translate('xpack.infra.logs.analysis.logRateSectionBucketSpanValue', {
+ defaultMessage: '15 minutes',
})}
- }
- />
- ) : (
-
+
+
+ >
)}
>
);
diff --git a/x-pack/legacy/plugins/infra/server/lib/log_analysis/log_analysis.ts b/x-pack/legacy/plugins/infra/server/lib/log_analysis/log_analysis.ts
index 31d9c5403e2d2..d970a142c5c23 100644
--- a/x-pack/legacy/plugins/infra/server/lib/log_analysis/log_analysis.ts
+++ b/x-pack/legacy/plugins/infra/server/lib/log_analysis/log_analysis.ts
@@ -15,7 +15,7 @@ import {
logRateModelPlotResponseRT,
createLogEntryRateQuery,
LogRateModelPlotBucket,
- CompositeTimestampDataSetKey,
+ CompositeTimestampPartitionKey,
} from './queries';
const COMPOSITE_AGGREGATION_BATCH_SIZE = 1000;
@@ -43,7 +43,7 @@ export class InfraLogAnalysis {
const logRateJobId = this.getJobIds(request, sourceId).logEntryRate;
let mlModelPlotBuckets: LogRateModelPlotBucket[] = [];
- let afterLatestBatchKey: CompositeTimestampDataSetKey | undefined;
+ let afterLatestBatchKey: CompositeTimestampPartitionKey | undefined;
while (true) {
const mlModelPlotResponse = await this.libs.framework.callWithRequest(
@@ -67,7 +67,7 @@ export class InfraLogAnalysis {
const { after_key: afterKey, buckets: latestBatchBuckets } = pipe(
logRateModelPlotResponseRT.decode(mlModelPlotResponse),
- map(response => response.aggregations.timestamp_data_set_buckets),
+ map(response => response.aggregations.timestamp_partition_buckets),
fold(throwErrors(createPlainError), identity)
);
@@ -81,7 +81,7 @@ export class InfraLogAnalysis {
return mlModelPlotBuckets.reduce<
Array<{
- dataSets: Array<{
+ partitions: Array<{
analysisBucketCount: number;
anomalies: Array<{
actualLogEntryRate: number;
@@ -91,15 +91,17 @@ export class InfraLogAnalysis {
typicalLogEntryRate: number;
}>;
averageActualLogEntryRate: number;
- dataSetId: string;
+ maximumAnomalyScore: number;
+ numberOfLogEntries: number;
+ partitionId: string;
}>;
startTime: number;
}>
- >((histogramBuckets, timestampDataSetBucket) => {
+ >((histogramBuckets, timestampPartitionBucket) => {
const previousHistogramBucket = histogramBuckets[histogramBuckets.length - 1];
- const dataSet = {
- analysisBucketCount: timestampDataSetBucket.filter_model_plot.doc_count,
- anomalies: timestampDataSetBucket.filter_records.top_hits_record.hits.hits.map(
+ const partition = {
+ analysisBucketCount: timestampPartitionBucket.filter_model_plot.doc_count,
+ anomalies: timestampPartitionBucket.filter_records.top_hits_record.hits.hits.map(
({ _source: record }) => ({
actualLogEntryRate: record.actual[0],
anomalyScore: record.record_score,
@@ -108,26 +110,30 @@ export class InfraLogAnalysis {
typicalLogEntryRate: record.typical[0],
})
),
- averageActualLogEntryRate: timestampDataSetBucket.filter_model_plot.average_actual.value,
- dataSetId: timestampDataSetBucket.key.data_set,
+ averageActualLogEntryRate:
+ timestampPartitionBucket.filter_model_plot.average_actual.value || 0,
+ maximumAnomalyScore:
+ timestampPartitionBucket.filter_records.maximum_record_score.value || 0,
+ numberOfLogEntries: timestampPartitionBucket.filter_model_plot.sum_actual.value || 0,
+ partitionId: timestampPartitionBucket.key.partition,
};
if (
previousHistogramBucket &&
- previousHistogramBucket.startTime === timestampDataSetBucket.key.timestamp
+ previousHistogramBucket.startTime === timestampPartitionBucket.key.timestamp
) {
return [
...histogramBuckets.slice(0, -1),
{
...previousHistogramBucket,
- dataSets: [...previousHistogramBucket.dataSets, dataSet],
+ partitions: [...previousHistogramBucket.partitions, partition],
},
];
} else {
return [
...histogramBuckets,
{
- dataSets: [dataSet],
- startTime: timestampDataSetBucket.key.timestamp,
+ partitions: [partition],
+ startTime: timestampPartitionBucket.key.timestamp,
},
];
}
diff --git a/x-pack/legacy/plugins/infra/server/lib/log_analysis/queries/log_entry_rate.ts b/x-pack/legacy/plugins/infra/server/lib/log_analysis/queries/log_entry_rate.ts
index b10b1fe04db24..2dd0880cbf8cb 100644
--- a/x-pack/legacy/plugins/infra/server/lib/log_analysis/queries/log_entry_rate.ts
+++ b/x-pack/legacy/plugins/infra/server/lib/log_analysis/queries/log_entry_rate.ts
@@ -14,7 +14,7 @@ export const createLogEntryRateQuery = (
endTime: number,
bucketDuration: number,
size: number,
- afterKey?: CompositeTimestampDataSetKey
+ afterKey?: CompositeTimestampPartitionKey
) => ({
allowNoIndices: true,
body: {
@@ -45,7 +45,7 @@ export const createLogEntryRateQuery = (
},
},
aggs: {
- timestamp_data_set_buckets: {
+ timestamp_partition_buckets: {
composite: {
after: afterKey,
size,
@@ -60,7 +60,7 @@ export const createLogEntryRateQuery = (
},
},
{
- data_set: {
+ partition: {
terms: {
field: 'partition_field_value',
order: 'asc',
@@ -82,6 +82,11 @@ export const createLogEntryRateQuery = (
field: 'actual',
},
},
+ sum_actual: {
+ sum: {
+ field: 'actual',
+ },
+ },
},
},
filter_records: {
@@ -91,6 +96,11 @@ export const createLogEntryRateQuery = (
},
},
aggs: {
+ maximum_record_score: {
+ max: {
+ field: 'record_score',
+ },
+ },
top_hits_record: {
top_hits: {
_source: Object.keys(logRateMlRecordRT.props),
@@ -124,20 +134,21 @@ const logRateMlRecordRT = rt.type({
});
const metricAggregationRT = rt.type({
- value: rt.number,
+ value: rt.union([rt.number, rt.null]),
});
-const compositeTimestampDataSetKeyRT = rt.type({
- data_set: rt.string,
+const compositeTimestampPartitionKeyRT = rt.type({
+ partition: rt.string,
timestamp: rt.number,
});
-export type CompositeTimestampDataSetKey = rt.TypeOf;
+export type CompositeTimestampPartitionKey = rt.TypeOf;
export const logRateModelPlotBucketRT = rt.type({
- key: compositeTimestampDataSetKeyRT,
+ key: compositeTimestampPartitionKeyRT,
filter_records: rt.type({
doc_count: rt.number,
+ maximum_record_score: metricAggregationRT,
top_hits_record: rt.type({
hits: rt.type({
hits: rt.array(
@@ -151,6 +162,7 @@ export const logRateModelPlotBucketRT = rt.type({
filter_model_plot: rt.type({
doc_count: rt.number,
average_actual: metricAggregationRT,
+ sum_actual: metricAggregationRT,
}),
});
@@ -158,12 +170,12 @@ export type LogRateModelPlotBucket = rt.TypeOf;
export const logRateModelPlotResponseRT = rt.type({
aggregations: rt.type({
- timestamp_data_set_buckets: rt.intersection([
+ timestamp_partition_buckets: rt.intersection([
rt.type({
buckets: rt.array(logRateModelPlotBucketRT),
}),
rt.partial({
- after_key: compositeTimestampDataSetKeyRT,
+ after_key: compositeTimestampPartitionKeyRT,
}),
]),
}),
diff --git a/x-pack/legacy/plugins/infra/server/routes/log_analysis/results/log_entry_rate.ts b/x-pack/legacy/plugins/infra/server/routes/log_analysis/results/log_entry_rate.ts
index 3212ecaf65e88..fc06ea48f4353 100644
--- a/x-pack/legacy/plugins/infra/server/routes/log_analysis/results/log_entry_rate.ts
+++ b/x-pack/legacy/plugins/infra/server/routes/log_analysis/results/log_entry_rate.ts
@@ -14,6 +14,7 @@ import {
LOG_ANALYSIS_GET_LOG_ENTRY_RATE_PATH,
getLogEntryRateRequestPayloadRT,
getLogEntryRateSuccessReponsePayloadRT,
+ GetLogEntryRateSuccessResponsePayload,
} from '../../../../common/http_api/log_analysis';
import { throwErrors } from '../../../../common/runtime_types';
import { NoLogRateResultsIndexError } from '../../../lib/log_analysis';
@@ -52,9 +53,21 @@ export const initLogAnalysisGetLogEntryRateRoute = ({
data: {
bucketDuration: payload.data.bucketDuration,
histogramBuckets: logEntryRateBuckets,
+ totalNumberOfLogEntries: getTotalNumberOfLogEntries(logEntryRateBuckets),
},
})
);
},
});
};
+
+const getTotalNumberOfLogEntries = (
+ logEntryRateBuckets: GetLogEntryRateSuccessResponsePayload['data']['histogramBuckets']
+) => {
+ return logEntryRateBuckets.reduce((sumNumberOfLogEntries, bucket) => {
+ const sumPartitions = bucket.partitions.reduce((partitionsTotal, partition) => {
+ return (partitionsTotal += partition.numberOfLogEntries);
+ }, 0);
+ return (sumNumberOfLogEntries += sumPartitions);
+ }, 0);
+};
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 56d7afa11ef13..3c18edddb4009 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -5246,8 +5246,6 @@
"xpack.infra.logs.analysis.logRateSectionNoDataBody": "時間範囲を調整する必要があるかもしれません。",
"xpack.infra.logs.analysis.logRateSectionNoDataTitle": "表示するデータがありません。",
"xpack.infra.logs.analysis.logRateSectionTitle": "ログレート",
- "xpack.infra.logs.analysis.logRateSectionXaxisTitle": "時間",
- "xpack.infra.logs.analysis.logRateSectionYaxisTitle": "15 分ごとのログエントリー",
"xpack.infra.logs.analysisPage.loadingMessage": "分析ジョブのステータスを確認中…",
"xpack.infra.logs.analysisPage.unavailable.mlAppButton": "機械学習を開く",
"xpack.infra.logs.analysisPage.unavailable.mlAppLink": "機械学習アプリ",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 75e8079c509c9..91be0568224dc 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -5248,8 +5248,6 @@
"xpack.infra.logs.analysis.logRateSectionNoDataBody": "您可能想调整时间范围。",
"xpack.infra.logs.analysis.logRateSectionNoDataTitle": "没有可显示的数据。",
"xpack.infra.logs.analysis.logRateSectionTitle": "日志速率",
- "xpack.infra.logs.analysis.logRateSectionXaxisTitle": "时间",
- "xpack.infra.logs.analysis.logRateSectionYaxisTitle": "每 15 分钟日志条目数",
"xpack.infra.logs.analysisPage.loadingMessage": "正在检查分析作业的状态......",
"xpack.infra.logs.analysisPage.unavailable.mlAppButton": "打开 Machine Learning",
"xpack.infra.logs.analysisPage.unavailable.mlAppLink": "Machine Learning 应用",
diff --git a/x-pack/test/api_integration/apis/infra/log_analysis.ts b/x-pack/test/api_integration/apis/infra/log_analysis.ts
index fe7d55649d1d6..2e57678d1d4c2 100644
--- a/x-pack/test/api_integration/apis/infra/log_analysis.ts
+++ b/x-pack/test/api_integration/apis/infra/log_analysis.ts
@@ -66,7 +66,7 @@ export default ({ getService }: FtrProviderContext) => {
expect(logEntryRateBuckets.data.histogramBuckets).to.not.be.empty();
expect(
logEntryRateBuckets.data.histogramBuckets.some(bucket => {
- return bucket.dataSets.some(dataSet => dataSet.anomalies.length > 0);
+ return bucket.partitions.some(partition => partition.anomalies.length > 0);
})
).to.be(true);
});