"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.TASK_ID = void 0; exports.dashboardTaskRunner = dashboardTaskRunner; exports.initializeDashboardTelemetryTask = initializeDashboardTelemetryTask; exports.scheduleDashboardTelemetry = scheduleDashboardTelemetry; var _moment = _interopRequireDefault(require("moment")); var _task_state = require("./task_state"); var _dashboard_telemetry = require("./dashboard_telemetry"); var _common = require("../../common"); /* * 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 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ // This task is responsible for running daily and aggregating all the Dashboard telemerty data // into a single document. This is an effort to make sure the load of fetching/parsing all of the // dashboards will only occur once per day const TELEMETRY_TASK_TYPE = 'dashboard_telemetry'; const TASK_ID = `Dashboard-${TELEMETRY_TASK_TYPE}`; exports.TASK_ID = TASK_ID; function initializeDashboardTelemetryTask(logger, core, taskManager, embeddable) { registerDashboardTelemetryTask(logger, core, taskManager, embeddable); } function scheduleDashboardTelemetry(logger, taskManager) { return scheduleTasks(logger, taskManager); } function registerDashboardTelemetryTask(logger, core, taskManager, embeddable) { taskManager.registerTaskDefinitions({ [TELEMETRY_TASK_TYPE]: { title: 'Dashboard telemetry collection task', timeout: '2m', stateSchemaByVersion: _task_state.stateSchemaByVersion, createTaskRunner: dashboardTaskRunner(logger, core, embeddable) } }); } async function scheduleTasks(logger, taskManager) { try { return await taskManager.ensureScheduled({ id: TASK_ID, taskType: TELEMETRY_TASK_TYPE, state: _task_state.emptyState, params: {} }); } catch (e) { logger.debug(`Error scheduling task, received ${e.message}`); } } function dashboardTaskRunner(logger, core, embeddable) { return ({ taskInstance }) => { const state = taskInstance.state; const getEsClient = async () => { const [coreStart] = await core.getStartServices(); return coreStart.elasticsearch.client.asInternalUser; }; return { async run() { let dashboardData = (0, _dashboard_telemetry.getEmptyDashboardData)(); const controlsCollector = (0, _dashboard_telemetry.controlsCollectorFactory)(embeddable); const processDashboards = dashboards => { for (const dashboard of dashboards) { const attributes = (0, _common.injectReferences)(dashboard, { embeddablePersistableStateService: embeddable }); dashboardData = controlsCollector(attributes, dashboardData); try { const panels = JSON.parse(attributes.panelsJSON); (0, _dashboard_telemetry.collectPanelsByType)(panels, dashboardData, embeddable); } catch (e) { logger.warn('Unable to parse panelsJSON for telemetry collection'); } } return dashboardData; }; const dashboardIndex = await core.getStartServices().then(([coreStart]) => coreStart.savedObjects.getIndexForType('dashboard')); const pageSize = 50; const searchParams = { size: pageSize, index: dashboardIndex, ignore_unavailable: true, filter_path: ['hits.hits', '_scroll_id'], body: { query: { bool: { filter: { term: { type: 'dashboard' } } } } }, scroll: '30s' }; // Get and process all of the dashboards try { const esClient = await getEsClient(); let result = await esClient.search(searchParams); dashboardData = processDashboards(result.hits.hits.map(h => { if (h._source) { return { attributes: h._source.dashboard, references: h._source.references }; } return undefined; }).filter(s => s !== undefined)); while (result._scroll_id && result.hits.hits.length > 0) { result = await esClient.scroll({ scroll_id: result._scroll_id, scroll: '30s' }); dashboardData = processDashboards(result.hits.hits.map(h => { if (h._source) { return { attributes: h._source.dashboard, references: h._source.references }; } return undefined; }).filter(s => s !== undefined)); } const updatedState = { runs: state.runs + 1, telemetry: dashboardData }; return { state: updatedState, runAt: getNextMidnight() }; } catch (e) { return { state: { runs: state.runs + 1 }, runAt: getNextFailureRetry() }; } }, async cancel() {} }; }; } function getNextMidnight() { return (0, _moment.default)().add(1, 'day').startOf('day').toDate(); } function getNextFailureRetry() { return (0, _moment.default)().add(1, 'hour').toDate(); }