Skip to content

Commit

Permalink
[Monitoring] Update /api/stats to use core.metrics (#60974) (#61148)
Browse files Browse the repository at this point in the history
* Align api/stats with the monitoring logic for kibana ops metrics

* Align collectors

* Add in locale to kibana_settings

* More tweaks

* PR feedback

* PR feedback
  • Loading branch information
chrisronline authored Mar 24, 2020
1 parent ad57ddb commit e439836
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/legacy/server/status/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function statusMixin(kbnServer, server, config) {
// init routes
registerStatusPage(kbnServer, server, config);
registerStatusApi(kbnServer, server, config);
registerStatsApi(usageCollection, server, config);
registerStatsApi(usageCollection, server, config, kbnServer);

// expore shared functionality
server.decorate('server', 'getOSInfo', getOSInfo);
Expand Down
29 changes: 20 additions & 9 deletions src/legacy/server/status/routes/api/register_stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import Joi from 'joi';
import boom from 'boom';
import { i18n } from '@kbn/i18n';
import { wrapAuthConfig } from '../../wrap_auth_config';
import { KIBANA_STATS_TYPE } from '../../constants';
import { getKibanaInfoForStats } from '../../lib';

const STATS_NOT_READY_MESSAGE = i18n.translate('server.stats.notReadyMessage', {
defaultMessage: 'Stats are not ready yet. Please try again later.',
Expand All @@ -37,7 +37,7 @@ const STATS_NOT_READY_MESSAGE = i18n.translate('server.stats.notReadyMessage', {
* - Any other value causes a statusCode 400 response (Bad Request)
* Including ?exclude_usage in the query string excludes the usage stats from the response. Same value semantics as ?extended
*/
export function registerStatsApi(usageCollection, server, config) {
export function registerStatsApi(usageCollection, server, config, kbnServer) {
const wrapAuth = wrapAuthConfig(config.get('status.allowAnonymous'));

const getClusterUuid = async callCluster => {
Expand All @@ -50,6 +50,17 @@ export function registerStatsApi(usageCollection, server, config) {
return usageCollection.toObject(usage);
};

let lastMetrics = null;
/* kibana_stats gets singled out from the collector set as it is used
* for health-checking Kibana and fetch does not rely on fetching data
* from ES */
server.newPlatform.setup.core.metrics.getOpsMetrics$().subscribe(metrics => {
lastMetrics = {
...metrics,
timestamp: new Date().toISOString(),
};
});

server.route(
wrapAuth({
method: 'GET',
Expand Down Expand Up @@ -133,15 +144,15 @@ export function registerStatsApi(usageCollection, server, config) {
}
}

/* kibana_stats gets singled out from the collector set as it is used
* for health-checking Kibana and fetch does not rely on fetching data
* from ES */
const kibanaStatsCollector = usageCollection.getCollectorByType(KIBANA_STATS_TYPE);
if (!(await kibanaStatsCollector.isReady())) {
if (!lastMetrics) {
return boom.serverUnavailable(STATS_NOT_READY_MESSAGE);
}
let kibanaStats = await kibanaStatsCollector.fetch();
kibanaStats = usageCollection.toApiFieldNames(kibanaStats);
const kibanaStats = usageCollection.toApiFieldNames({
...lastMetrics,
kibana: getKibanaInfoForStats(server, kbnServer),
last_updated: new Date().toISOString(),
collection_interval_in_millis: config.get('ops.interval'),
});

return {
...kibanaStats,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@

import { defaultsDeep, uniq, compact, get } from 'lodash';

import { TELEMETRY_COLLECTION_INTERVAL } from '../../common/constants';
import {
TELEMETRY_COLLECTION_INTERVAL,
KIBANA_STATS_TYPE_MONITORING,
} from '../../common/constants';

import { sendBulkPayload, monitoringBulk } from './lib';
import { hasMonitoringCluster } from '../es_client/instantiate_client';
Expand Down Expand Up @@ -188,11 +191,18 @@ export class BulkUploader {
);
}

getKibanaStats() {
return {
getKibanaStats(type) {
const stats = {
...this.kibanaStats,
status: this.kibanaStatusGetter(),
};

if (type === KIBANA_STATS_TYPE_MONITORING) {
delete stats.port;
delete stats.locale;
}

return stats;
}

/*
Expand Down Expand Up @@ -252,7 +262,7 @@ export class BulkUploader {
...accum,
{ index: { _type: type } },
{
kibana: this.getKibanaStats(),
kibana: this.getKibanaStats(type),
...typesNested[type],
},
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import { Observable } from 'rxjs';
import { cloneDeep } from 'lodash';
import moment from 'moment';
import { OpsMetrics } from 'kibana/server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
Expand All @@ -22,7 +23,15 @@ export function getOpsStatsCollector(
metrics$: Observable<OpsMetrics>
) {
let lastMetrics: MonitoringOpsMetrics | null = null;
metrics$.subscribe(metrics => {
metrics$.subscribe(_metrics => {
const metrics: any = cloneDeep(_metrics);
// Ensure we only include the same data that Metricbeat collection would get
delete metrics.process.pid;
metrics.response_times = {
average: metrics.response_times.avg_in_millis,
max: metrics.response_times.max_in_millis,
};
delete metrics.requests.statusCodes;
lastMetrics = {
...metrics,
timestamp: moment.utc().toISOString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ import { MonitoringConfig } from '../../config';
* If so, use uiSettings API to fetch the X-Pack default admin email
*/
export async function getDefaultAdminEmail(config: MonitoringConfig) {
if (!config.cluster_alerts.email_notifications.enabled) {
return null;
}

return config.cluster_alerts.email_notifications.email_address || null;
}

Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/monitoring/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ import { InfraPluginSetup } from '../../infra/server';

export interface LegacyAPI {
getServerStatus: () => string;
infra: any;
}

interface PluginsSetup {
Expand Down Expand Up @@ -189,8 +188,9 @@ export class Plugin {
name: serverInfo.name,
index: get(legacyConfig, 'kibana.index'),
host: serverInfo.host,
transport_address: `${serverInfo.host}:${serverInfo.port}`,
locale: i18n.getLocale(),
port: serverInfo.port.toString(),
transport_address: `${serverInfo.host}:${serverInfo.port}`,
version: this.initializerContext.env.packageInfo.version,
snapshot: snapshotRegex.test(this.initializerContext.env.packageInfo.version),
},
Expand Down

0 comments on commit e439836

Please sign in to comment.