Osquery telemetry usage bug (#102762)

* guard for null metrics query

* added some tests for the beat usage metric extraction function
This commit is contained in:
Bryan Clement 2021-06-21 10:47:15 -07:00 committed by GitHub
parent ceaf9f6242
commit 4c700aba8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 147 additions and 33 deletions

View file

@ -0,0 +1,105 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { extractBeatUsageMetrics } from './fetchers';
describe('extractBeatUsageMetrics', () => {
it('should not blow when no values are supplied for the aggregations', () => {
expect(extractBeatUsageMetrics({})).toEqual({
memory: {
rss: {},
},
cpu: {},
});
});
it('should not blow when some values are missing from the aggregations', () => {
expect(
extractBeatUsageMetrics({
aggregations: {
lastDay: {
max_rss: {
value: 1,
},
},
},
})
).toEqual({
memory: {
rss: {
max: 1,
},
},
cpu: {},
});
});
it('should pick out all the max/avg/latest for memory/cpu', () => {
expect(
extractBeatUsageMetrics({
aggregations: {
lastDay: {
max_rss: {
value: 1,
},
avg_rss: {
value: 1,
},
max_cpu: {
value: 2,
},
avg_cpu: {
value: 2,
},
latest: {
hits: {
total: 1,
hits: [
{
_index: '',
_id: '',
_source: {
monitoring: {
metrics: {
beat: {
cpu: {
total: {
time: {
ms: 2,
},
},
},
memstats: {
rss: 1,
},
},
},
},
},
},
],
},
},
},
},
})
).toEqual({
memory: {
rss: {
max: 1,
avg: 1,
latest: 1,
},
},
cpu: {
max: 2,
avg: 2,
latest: 2,
},
});
});
});

View file

@ -9,6 +9,7 @@ import {
AggregationsSingleBucketAggregate,
AggregationsTopHitsAggregate,
AggregationsValueAggregate,
SearchResponse,
} from '@elastic/elasticsearch/api/types';
import { PackagePolicyServiceInterface } from '../../../fleet/server';
import { getRouteMetric } from '../routes/usage';
@ -133,6 +134,46 @@ export async function getLiveQueryUsage(
return result;
}
export function extractBeatUsageMetrics(
metricResponse: Pick<SearchResponse<unknown>, 'aggregations'>
) {
const lastDayAggs = metricResponse.aggregations?.lastDay as AggregationsSingleBucketAggregate;
const result: BeatMetricsUsage = {
memory: {
rss: {},
},
cpu: {},
};
if (lastDayAggs) {
if ('max_rss' in lastDayAggs) {
result.memory.rss.max = (lastDayAggs.max_rss as AggregationsValueAggregate).value;
}
if ('avg_rss' in lastDayAggs) {
result.memory.rss.avg = (lastDayAggs.max_rss as AggregationsValueAggregate).value;
}
if ('max_cpu' in lastDayAggs) {
result.cpu.max = (lastDayAggs.max_cpu as AggregationsValueAggregate).value;
}
if ('avg_cpu' in lastDayAggs) {
result.cpu.avg = (lastDayAggs.max_cpu as AggregationsValueAggregate).value;
}
if ('latest' in lastDayAggs) {
const latest = (lastDayAggs.latest as AggregationsTopHitsAggregate).hits.hits[0]?._source
?.monitoring.metrics.beat;
if (latest) {
result.cpu.latest = latest.cpu.total.time.ms;
result.memory.rss.latest = latest.memstats.rss;
}
}
}
return result;
}
export async function getBeatUsage(esClient: ElasticsearchClient) {
const { body: metricResponse } = await esClient.search({
body: {
@ -186,38 +227,6 @@ export async function getBeatUsage(esClient: ElasticsearchClient) {
},
index: METRICS_INDICES,
});
const lastDayAggs = metricResponse.aggregations?.lastDay as AggregationsSingleBucketAggregate;
const result: BeatMetricsUsage = {
memory: {
rss: {},
},
cpu: {},
};
if ('max_rss' in lastDayAggs) {
result.memory.rss.max = (lastDayAggs.max_rss as AggregationsValueAggregate).value;
}
if ('avg_rss' in lastDayAggs) {
result.memory.rss.avg = (lastDayAggs.max_rss as AggregationsValueAggregate).value;
}
if ('max_cpu' in lastDayAggs) {
result.cpu.max = (lastDayAggs.max_cpu as AggregationsValueAggregate).value;
}
if ('avg_cpu' in lastDayAggs) {
result.cpu.avg = (lastDayAggs.max_cpu as AggregationsValueAggregate).value;
}
if ('latest' in lastDayAggs) {
const latest = (lastDayAggs.latest as AggregationsTopHitsAggregate).hits.hits[0]?._source
?.monitoring.metrics.beat;
if (latest) {
result.cpu.latest = latest.cpu.total.time.ms;
result.memory.rss.latest = latest.memstats.rss;
}
}
return result;
return extractBeatUsageMetrics(metricResponse);
}