[Monitoring] Support Metricbeat format for shard activity (#151983)

Related issue: https://github.com/elastic/beats/issues/34427

Since Metricbeat now reports the right fields, I've updated the UI to
consume those.

<img width="2935" alt="Screenshot 2023-02-23 at 12 00 05"
src="https://user-images.githubusercontent.com/2564140/220893266-1d82bc16-6bca-4eca-a5a1-1a1573eb139d.png">

Related PRs:
https://github.com/elastic/beats/pull/34653
https://github.com/elastic/elasticsearch/pull/94062
https://github.com/elastic/integrations/pull/5367

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Milton Hultgren 2023-03-21 13:45:46 +01:00 committed by GitHub
parent a1f55d4eb4
commit 469c5a3761
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 12 deletions

View file

@ -413,6 +413,18 @@ export interface ElasticsearchIndexRecoveryShard {
};
}
export interface ElasticsearchMetricbeatIndexRecoveryShard {
start_time?: {
ms: number;
};
stop_time?: {
ms: number;
};
total_time?: {
ms: number;
};
}
export interface ElasticsearchMetricbeatNode {
name?: string;
stats?: ElasticsearchNodeStats;
@ -430,7 +442,7 @@ export interface ElasticsearchMetricbeatSource {
elasticsearch?: {
node?: ElasticsearchLegacySource['source_node'] & ElasticsearchMetricbeatNode;
index?: ElasticsearchIndexStats & {
recovery?: ElasticsearchIndexRecoveryShard;
recovery?: ElasticsearchMetricbeatIndexRecoveryShard;
};
version?: string;
shard?: ElasticsearchLegacySource['shard'] & {

View file

@ -33,6 +33,8 @@ export const parseProps = (props) => {
primary: isPrimary,
start_time_in_millis: startTimeInMillis,
total_time_in_millis: totalTimeInMillis,
start_time: mbStartTime,
total_time: mbTotalTime,
source,
target,
translog,
@ -47,8 +49,8 @@ export const parseProps = (props) => {
shard: `${id} / ${isPrimary ? 'Primary' : 'Replica'}`,
relocationType: type === 'PRIMARY_RELOCATION' ? 'Primary Relocation' : normalizeString(type),
stage: normalizeString(stage),
startTime: formatDateTimeLocal(startTimeInMillis, timezone),
totalTime: formatMetric(Math.floor(totalTimeInMillis / 1000), '00:00:00'),
startTime: formatDateTimeLocal(startTimeInMillis || mbStartTime?.ms, timezone),
totalTime: formatMetric(Math.floor((totalTimeInMillis || mbTotalTime?.ms) / 1000), '00:00:00'),
isCopiedFromPrimary: !isPrimary || type === 'PRIMARY_RELOCATION',
sourceName: source.name === undefined ? 'n/a' : source.name,
targetName: target.name,

View file

@ -12,6 +12,7 @@ import { ElasticsearchMetric } from '../metrics';
import {
ElasticsearchResponse,
ElasticsearchIndexRecoveryShard,
ElasticsearchMetricbeatIndexRecoveryShard,
ElasticsearchResponseHit,
} from '../../../common/types/es';
import { LegacyRequest } from '../../types';
@ -30,12 +31,22 @@ import { Globals } from '../../static_globals';
* @returns {boolean} true to keep
*/
export function filterOldShardActivity(startMs: number) {
return (activity?: ElasticsearchIndexRecoveryShard) => {
return (
activity?: ElasticsearchIndexRecoveryShard | ElasticsearchMetricbeatIndexRecoveryShard
) => {
if (!activity) {
return false;
}
let stopTime = null;
if ((activity as ElasticsearchMetricbeatIndexRecoveryShard).stop_time) {
stopTime = (activity as ElasticsearchMetricbeatIndexRecoveryShard).stop_time?.ms;
} else {
stopTime = (activity as ElasticsearchIndexRecoveryShard).stop_time_in_millis;
}
// either it's still going and there is no stop time, or the stop time happened after we started looking for one
return (
activity &&
(!_.isNumber(activity.stop_time_in_millis) || activity.stop_time_in_millis >= startMs)
);
return !_.isNumber(stopTime) || stopTime >= startMs;
};
}
@ -78,9 +89,16 @@ export function handleMbLastRecoveries(resp: ElasticsearchResponse, start: numbe
(hit) => hit._source.elasticsearch?.index?.recovery
);
const filtered = mapped.filter(filterOldShardActivity(moment.utc(start).valueOf()));
filtered.sort((a, b) =>
a && b ? (b.start_time_in_millis ?? 0) - (a.start_time_in_millis ?? 0) : 0
);
filtered.sort((a, b) => {
if (!a || !b) {
return 0;
}
const startTimeA = a.start_time?.ms || 0;
const startTimeB = b.start_time?.ms || 0;
return startTimeB - startTimeA;
});
return filtered;
}

File diff suppressed because one or more lines are too long