Skip to content

Commit

Permalink
Shim oss telemetry (elastic#51168)
Browse files Browse the repository at this point in the history
  • Loading branch information
flash1293 authored and timductive committed Dec 16, 2019
1 parent 94703cf commit 21cd68f
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 201 deletions.
61 changes: 0 additions & 61 deletions x-pack/legacy/plugins/oss_telemetry/index.d.ts

This file was deleted.

24 changes: 0 additions & 24 deletions x-pack/legacy/plugins/oss_telemetry/index.js

This file was deleted.

41 changes: 41 additions & 0 deletions x-pack/legacy/plugins/oss_telemetry/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { Logger, PluginInitializerContext } from 'kibana/server';
import { PLUGIN_ID } from './constants';
import { OssTelemetryPlugin } from './server/plugin';
import { LegacyPluginInitializer } from '../../../../src/legacy/plugin_discovery/types';

export const ossTelemetry: LegacyPluginInitializer = kibana => {
return new kibana.Plugin({
id: PLUGIN_ID,
require: ['elasticsearch', 'xpack_main'],
configPrefix: 'xpack.oss_telemetry',

init(server) {
const plugin = new OssTelemetryPlugin({
logger: {
get: () =>
({
info: (message: string) => server.log(['info', 'task_manager'], message),
debug: (message: string) => server.log(['debug', 'task_manager'], message),
warn: (message: string) => server.log(['warn', 'task_manager'], message),
error: (message: string) => server.log(['error', 'task_manager'], message),
} as Logger),
},
} as PluginInitializerContext);
plugin.setup(server.newPlatform.setup.core, {
usageCollection: server.newPlatform.setup.plugins.usageCollection,
taskManager: server.plugins.task_manager,
__LEGACY: {
config: server.config(),
xpackMainStatus: ((server.plugins.xpack_main as unknown) as { status: any }).status
.plugin,
},
});
},
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { HapiServer } from '../../../';
import { registerVisualizationsCollector } from './visualizations/register_usage_collector';
import { OssTelemetrySetupDependencies } from '../../plugin';

export function registerCollectors(usageCollection: UsageCollectionSetup, server: HapiServer) {
registerVisualizationsCollector(usageCollection, server);
export function registerCollectors(deps: OssTelemetrySetupDependencies) {
registerVisualizationsCollector(deps.usageCollection, deps.taskManager);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/

import sinon from 'sinon';
import { HapiServer } from '../../../../';
import {
getMockCallWithInternal,
getMockKbnServer,
getMockTaskFetch,
} from '../../../../test_utils';
import { getMockTaskFetch, getMockTaskManager } from '../../../../test_utils';
import { getUsageCollector } from './get_usage_collector';

describe('getVisualizationsCollector#fetch', () => {
let mockKbnServer: HapiServer;

beforeEach(() => {
mockKbnServer = getMockKbnServer(getMockCallWithInternal(), getMockTaskFetch());
});

test('can return empty stats', async () => {
const { type, fetch } = getUsageCollector(mockKbnServer);
const { type, fetch } = getUsageCollector(getMockTaskManager());
expect(type).toBe('visualization_types');
const fetchResult = await fetch();
expect(fetchResult).toEqual({});
Expand All @@ -34,35 +22,33 @@ describe('getVisualizationsCollector#fetch', () => {
runs: 1,
stats: { comic_books: { total: 16, max: 12, min: 2, avg: 6 } },
},
taskType: 'test',
params: {},
},
]);
mockKbnServer = getMockKbnServer(getMockCallWithInternal(), mockTaskFetch);

const { type, fetch } = getUsageCollector(mockKbnServer);
const { type, fetch } = getUsageCollector(getMockTaskManager(mockTaskFetch));
expect(type).toBe('visualization_types');
const fetchResult = await fetch();
expect(fetchResult).toEqual({ comic_books: { avg: 6, max: 12, min: 2, total: 16 } });
});

describe('Error handling', () => {
test('Silently handles Task Manager NotInitialized', async () => {
const mockTaskFetch = sinon.stub();
mockTaskFetch.rejects(
new Error('NotInitialized taskManager is still waiting for plugins to load')
);
mockKbnServer = getMockKbnServer(getMockCallWithInternal(), mockTaskFetch);

const { fetch } = getUsageCollector(mockKbnServer);
await expect(fetch()).resolves.toBe(undefined);
const mockTaskFetch = jest.fn(() => {
throw new Error('NotInitialized taskManager is still waiting for plugins to load');
});
const { fetch } = getUsageCollector(getMockTaskManager(mockTaskFetch));
const result = await fetch();
expect(result).toBe(undefined);
});
// In real life, the CollectorSet calls fetch and handles errors
test('defers the errors', async () => {
const mockTaskFetch = sinon.stub();
mockTaskFetch.rejects(new Error('BOOM'));
mockKbnServer = getMockKbnServer(getMockCallWithInternal(), mockTaskFetch);
const mockTaskFetch = jest.fn(() => {
throw new Error('BOOM');
});

const { fetch } = getUsageCollector(mockKbnServer);
await expect(fetch()).rejects.toMatchObject(new Error('BOOM'));
const { fetch } = getUsageCollector(getMockTaskManager(mockTaskFetch));
await expect(fetch()).rejects.toThrowErrorMatchingInlineSnapshot(`"BOOM"`);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@
*/

import { get } from 'lodash';
import { HapiServer } from '../../../../';
import { PluginSetupContract as TaskManagerPluginSetupContract } from '../../../../../task_manager/plugin';
import { PLUGIN_ID, VIS_TELEMETRY_TASK, VIS_USAGE_TYPE } from '../../../../constants';

async function isTaskManagerReady(server: HapiServer) {
const result = await fetch(server);
async function isTaskManagerReady(taskManager: TaskManagerPluginSetupContract | undefined) {
const result = await fetch(taskManager);
return result !== null;
}

async function fetch(server: HapiServer) {
const taskManager = server.plugins.task_manager;

async function fetch(taskManager: TaskManagerPluginSetupContract | undefined) {
if (!taskManager) {
return null;
}
Expand All @@ -40,12 +38,12 @@ async function fetch(server: HapiServer) {
return docs;
}

export function getUsageCollector(server: HapiServer) {
export function getUsageCollector(taskManager: TaskManagerPluginSetupContract | undefined) {
let isCollectorReady = false;
async function determineIfTaskManagerIsReady() {
let isReady = false;
try {
isReady = await isTaskManagerReady(server);
isReady = await isTaskManagerReady(taskManager);
} catch (err) {} // eslint-disable-line

if (isReady) {
Expand All @@ -60,7 +58,7 @@ export function getUsageCollector(server: HapiServer) {
type: VIS_USAGE_TYPE,
isReady: () => isCollectorReady,
fetch: async () => {
const docs = await fetch(server);
const docs = await fetch(taskManager);
// get the accumulated state from the recurring task
return get(docs, '[0].state.stats');
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
*/

import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { HapiServer } from '../../../../';
import { PluginSetupContract as TaskManagerPluginSetupContract } from '../../../../../task_manager/plugin';
import { getUsageCollector } from './get_usage_collector';

export function registerVisualizationsCollector(
usageCollection: UsageCollectionSetup,
server: HapiServer
collectorSet: UsageCollectionSetup,
taskManager: TaskManagerPluginSetupContract | undefined
): void {
const collector = usageCollection.makeUsageCollector(getUsageCollector(server));
usageCollection.registerCollector(collector);
const collector = collectorSet.makeUsageCollector(getUsageCollector(taskManager));
collectorSet.registerCollector(collector);
}
47 changes: 36 additions & 11 deletions x-pack/legacy/plugins/oss_telemetry/server/lib/tasks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,58 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { HapiServer } from '../../../';
import { CoreSetup, Logger } from 'kibana/server';
import { PluginSetupContract as TaskManagerPluginSetupContract } from '../../../../task_manager/plugin';
import { PLUGIN_ID, VIS_TELEMETRY_TASK } from '../../../constants';
import { visualizationsTaskRunner } from './visualizations/task_runner';
import KbnServer from '../../../../../../../src/legacy/server/kbn_server';
import { LegacyConfig } from '../../plugin';
import { TaskInstance } from '../../../../task_manager';

export function registerTasks(server: HapiServer) {
const taskManager = server.plugins.task_manager;

export function registerTasks({
taskManager,
logger,
elasticsearch,
config,
}: {
taskManager?: TaskManagerPluginSetupContract;
logger: Logger;
elasticsearch: CoreSetup['elasticsearch'];
config: LegacyConfig;
}) {
if (!taskManager) {
server.log(['debug', 'telemetry'], `Task manager is not available`);
logger.debug('Task manager is not available');
return;
}

taskManager.registerTaskDefinitions({
[VIS_TELEMETRY_TASK]: {
title: 'X-Pack telemetry calculator for Visualizations',
type: VIS_TELEMETRY_TASK,
createTaskRunner({ taskInstance }: { taskInstance: any }) {
createTaskRunner({ taskInstance }: { taskInstance: TaskInstance }) {
return {
run: visualizationsTaskRunner(taskInstance, server),
run: visualizationsTaskRunner(taskInstance, config, elasticsearch),
};
},
},
});
}

export function scheduleTasks(server: HapiServer) {
const taskManager = server.plugins.task_manager;
const { kbnServer } = server.plugins.xpack_main.status.plugin;
export function scheduleTasks({
taskManager,
xpackMainStatus,
logger,
}: {
taskManager?: TaskManagerPluginSetupContract;
xpackMainStatus: { kbnServer: KbnServer };
logger: Logger;
}) {
if (!taskManager) {
logger.debug('Task manager is not available');
return;
}

const { kbnServer } = xpackMainStatus;

kbnServer.afterPluginsInit(() => {
// The code block below can't await directly within "afterPluginsInit"
Expand All @@ -46,9 +70,10 @@ export function scheduleTasks(server: HapiServer) {
id: `${PLUGIN_ID}-${VIS_TELEMETRY_TASK}`,
taskType: VIS_TELEMETRY_TASK,
state: { stats: {}, runs: 0 },
params: {},
});
} catch (e) {
server.log(['debug', 'telemetry'], `Error scheduling task, received ${e.message}`);
logger.debug(`Error scheduling task, received ${e.message}`);
}
})();
});
Expand Down
Loading

0 comments on commit 21cd68f

Please sign in to comment.