Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I don't think we need to use cloneDeep here (unless metrics is somehow a reference), and looks like _metrics is not used anywhere else. Don't know if Observables hold references though, in which case maybe shallow might be good enough?:
metrics$.subscribe(({ ...metrics }) => {

Only mentioning because I know cloneDeep can be pretty expensive

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea I tried it without it and any delete or re-setting the object caused issues with the other subscriber.

// 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,9 +12,6 @@ import { MonitoringConfig } from '../../config';
* If so, get email from kibana.yml
*/
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