mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Telemetry] move from xpack main (#35403)
* enabling xpack in new plugins * move telemetry into separate new platform plugin * remap constants * resolved hacks issue * remove extra dir * js -> ts * run linter * fix tests * reset kibana.yml * reset kibana.yml * ts types * add telemetry translations to i18n * use deprecated configs * checkout config.yml * fix test * move telemetry from xpack_main in api_integration * add telemetry apis * hide banner * remove routes/get_stats in favor of collectors/get_stats * code review fixes
This commit is contained in:
parent
d6cf22f9ff
commit
c308048f04
106 changed files with 436 additions and 386 deletions
|
@ -38,6 +38,7 @@
|
|||
"xpack.ml": "x-pack/plugins/ml",
|
||||
"xpack.logstash": "x-pack/plugins/logstash",
|
||||
"xpack.main": "x-pack/plugins/xpack_main",
|
||||
"xpack.telemetry": "x-pack/plugins/telemetry",
|
||||
"xpack.monitoring": "x-pack/plugins/monitoring",
|
||||
"xpack.remoteClusters": "x-pack/plugins/remote_clusters",
|
||||
"xpack.reporting": "x-pack/plugins/reporting",
|
||||
|
|
|
@ -54,7 +54,7 @@ Specifies the password that {kib} uses for authentication when it retrieves data
|
|||
from the monitoring cluster. If not set, {kib} uses the value of the
|
||||
`elasticsearch.password` setting.
|
||||
|
||||
`xpack.xpack_main.telemetry.enabled`::
|
||||
`xpack.telemetry.enabled`::
|
||||
Set to `true` (default) to send cluster statistics to Elastic. Reporting your
|
||||
cluster statistics helps us improve your user experience. Your data is never
|
||||
shared with anyone. Set to `false` to disable statistics reporting from any
|
||||
|
|
|
@ -143,7 +143,7 @@ kibana_vars=(
|
|||
xpack.security.encryptionKey
|
||||
xpack.security.secureCookies
|
||||
xpack.security.sessionTimeout
|
||||
xpack.xpack_main.telemetry.enabled
|
||||
xpack.telemetry.enabled
|
||||
)
|
||||
|
||||
longopts=''
|
||||
|
|
|
@ -39,12 +39,14 @@ import { translations } from './plugins/translations';
|
|||
import { upgradeAssistant } from './plugins/upgrade_assistant';
|
||||
import { uptime } from './plugins/uptime';
|
||||
import { ossTelemetry } from './plugins/oss_telemetry';
|
||||
import { telemetry } from './plugins/telemetry';
|
||||
import { encryptedSavedObjects } from './plugins/encrypted_saved_objects';
|
||||
import { snapshotRestore } from './plugins/snapshot_restore';
|
||||
|
||||
module.exports = function (kibana) {
|
||||
return [
|
||||
xpackMain(kibana),
|
||||
telemetry(kibana),
|
||||
graph(kibana),
|
||||
monitoring(kibana),
|
||||
reporting(kibana),
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { fetchTelemetry } from '../../../xpack_main/public/hacks/fetch_telemetry';
|
||||
export { PRIVACY_STATEMENT_URL } from '../../../xpack_main/common/constants';
|
||||
export { TelemetryOptInProvider } from '../../../xpack_main/public/services/telemetry_opt_in';
|
||||
export { OptInExampleFlyout } from '../../../xpack_main/public/components';
|
||||
import { fetchTelemetry } from '../../../telemetry/public/hacks/fetch_telemetry';
|
||||
export { PRIVACY_STATEMENT_URL } from '../../../telemetry/common/constants';
|
||||
export { TelemetryOptInProvider } from '../../../telemetry/public/services/telemetry_opt_in';
|
||||
export { OptInExampleFlyout } from '../../../telemetry/public/components';
|
||||
|
||||
let telemetryEnabled;
|
||||
let httpClient;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { MONITORING_SYSTEM_API_VERSION } from '../../../common/constants';
|
||||
import { KIBANA_SYSTEM_ID } from '../../../../xpack_main/common/constants';
|
||||
import { KIBANA_SYSTEM_ID } from '../../../../telemetry/common/constants';
|
||||
|
||||
/*
|
||||
* Send the Kibana usage data to the ES Monitoring Bulk endpoint
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { get, uniq } from 'lodash';
|
||||
import { METRICBEAT_INDEX_NAME_UNIQUE_TOKEN } from '../../../../common/constants';
|
||||
import { KIBANA_SYSTEM_ID, BEATS_SYSTEM_ID, LOGSTASH_SYSTEM_ID } from '../../../../../xpack_main/common/constants';
|
||||
import { KIBANA_SYSTEM_ID, BEATS_SYSTEM_ID, LOGSTASH_SYSTEM_ID } from '../../../../../telemetry/common/constants';
|
||||
|
||||
const APM_CUSTOM_ID = 'apm';
|
||||
const ELASTICSEARCH_CUSTOM_ID = 'elasticsearch';
|
||||
|
|
|
@ -16,9 +16,9 @@ export const CONFIG_TELEMETRY = 'telemetry:optIn';
|
|||
* @type {string}
|
||||
*/
|
||||
export const getConfigTelemetryDesc = () => {
|
||||
return i18n.translate('xpack.main.telemetry.telemetryConfigDescription', {
|
||||
return i18n.translate('xpack.telemetry.telemetryConfigDescription', {
|
||||
defaultMessage:
|
||||
'Help us improve the Elastic Stack by providing usage statistics for basic features. We will not share this data outside of Elastic.'
|
||||
'Help us improve the Elastic Stack by providing usage statistics for basic features. We will not share this data outside of Elastic.',
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* 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 { KibanaConfig } from 'src/legacy/server/kbn_server';
|
||||
|
||||
export function getXpackConfigWithDeprecated(config: KibanaConfig, configPath: string) {
|
||||
const deprecatedConfig = config.get(`xpack.xpack_main.${configPath}`);
|
||||
if (typeof deprecatedConfig !== 'undefined') {
|
||||
return deprecatedConfig;
|
||||
}
|
||||
return config.get(`xpack.${configPath}`);
|
||||
}
|
95
x-pack/plugins/telemetry/index.ts
Normal file
95
x-pack/plugins/telemetry/index.ts
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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 { resolve } from 'path';
|
||||
import JoiNamespace from 'joi';
|
||||
import { Server } from 'hapi';
|
||||
import { CoreSetup, PluginInitializerContext } from 'src/core/server';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import mappings from './mappings.json';
|
||||
import { CONFIG_TELEMETRY, getConfigTelemetryDesc, REPORT_INTERVAL_MS } from './common/constants';
|
||||
import { getXpackConfigWithDeprecated } from './common/get_xpack_config_with_deprecated';
|
||||
import { telemetryPlugin } from './server';
|
||||
|
||||
import {
|
||||
createLocalizationUsageCollector,
|
||||
createTelemetryUsageCollector,
|
||||
} from './server/collectors';
|
||||
|
||||
const ENDPOINT_VERSION = 'v2';
|
||||
|
||||
export const telemetry = (kibana: any) => {
|
||||
return new kibana.Plugin({
|
||||
id: 'telemetry',
|
||||
configPrefix: 'xpack.telemetry',
|
||||
publicDir: resolve(__dirname, 'public'),
|
||||
require: ['elasticsearch'],
|
||||
config(Joi: typeof JoiNamespace) {
|
||||
return Joi.object({
|
||||
enabled: Joi.boolean().default(true),
|
||||
// `config` is used internally and not intended to be set
|
||||
config: Joi.string().default(Joi.ref('$defaultConfigPath')),
|
||||
url: Joi.when('$dev', {
|
||||
is: true,
|
||||
then: Joi.string().default(
|
||||
`https://telemetry-staging.elastic.co/xpack/${ENDPOINT_VERSION}/send`
|
||||
),
|
||||
otherwise: Joi.string().default(
|
||||
`https://telemetry.elastic.co/xpack/${ENDPOINT_VERSION}/send`
|
||||
),
|
||||
}),
|
||||
}).default();
|
||||
},
|
||||
uiExports: {
|
||||
managementSections: ['plugins/telemetry/views/management'],
|
||||
uiSettingDefaults: {
|
||||
[CONFIG_TELEMETRY]: {
|
||||
name: i18n.translate('xpack.telemetry.telemetryConfigTitle', {
|
||||
defaultMessage: 'Telemetry opt-in',
|
||||
}),
|
||||
description: getConfigTelemetryDesc(),
|
||||
value: false,
|
||||
readonly: true,
|
||||
},
|
||||
},
|
||||
savedObjectSchemas: {
|
||||
telemetry: {
|
||||
isNamespaceAgnostic: true,
|
||||
},
|
||||
},
|
||||
injectDefaultVars(server: Server) {
|
||||
const config = server.config();
|
||||
return {
|
||||
telemetryEnabled: getXpackConfigWithDeprecated(config, 'telemetry.enabled'),
|
||||
telemetryUrl: getXpackConfigWithDeprecated(config, 'telemetry.url'),
|
||||
spacesEnabled: config.get('xpack.spaces.enabled'),
|
||||
telemetryOptedIn: null,
|
||||
activeSpace: null,
|
||||
};
|
||||
},
|
||||
hacks: [
|
||||
'plugins/telemetry/hacks/telemetry_opt_in',
|
||||
'plugins/telemetry/hacks/telemetry_trigger',
|
||||
],
|
||||
mappings,
|
||||
},
|
||||
init(server: Server) {
|
||||
const initializerContext = {} as PluginInitializerContext;
|
||||
const coreSetup = ({
|
||||
http: { server },
|
||||
} as any) as CoreSetup;
|
||||
|
||||
telemetryPlugin(initializerContext).setup(coreSetup);
|
||||
|
||||
// register collectors
|
||||
server.usage.collectorSet.register(createLocalizationUsageCollector(server));
|
||||
server.usage.collectorSet.register(createTelemetryUsageCollector(server));
|
||||
|
||||
// expose
|
||||
server.expose('telemetryCollectionInterval', REPORT_INTERVAL_MS);
|
||||
},
|
||||
});
|
||||
};
|
|
@ -15,7 +15,7 @@ exports[`OptInDetailsComponent renders as expected 1`] = `
|
|||
<h2>
|
||||
<FormattedMessage
|
||||
defaultMessage="Cluster statistics"
|
||||
id="xpack.main.telemetry.callout.clusterStatisticsTitle"
|
||||
id="xpack.telemetry.callout.clusterStatisticsTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
|
@ -26,7 +26,7 @@ exports[`OptInDetailsComponent renders as expected 1`] = `
|
|||
<EuiText>
|
||||
<FormattedMessage
|
||||
defaultMessage="This is an example of the basic cluster statistics that we'll collect. It includes the number of indices, shards, and nodes. It also includes high-level usage statistics, such as whether monitoring is turned on."
|
||||
id="xpack.main.telemetry.callout.clusterStatisticsDescription"
|
||||
id="xpack.telemetry.callout.clusterStatisticsDescription"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiText>
|
|
@ -18,7 +18,7 @@ exports[`TelemetryForm renders as expected 1`] = `
|
|||
<h2>
|
||||
<FormattedMessage
|
||||
defaultMessage="Usage Data"
|
||||
id="xpack.main.telemetry.usageDataTitle"
|
||||
id="xpack.telemetry.usageDataTitle"
|
||||
values={Object {}}
|
||||
/>
|
||||
</h2>
|
||||
|
@ -47,7 +47,7 @@ exports[`TelemetryForm renders as expected 1`] = `
|
|||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="See an example of what we collect"
|
||||
id="xpack.main.telemetry.seeExampleOfWhatWeCollectLinkText"
|
||||
id="xpack.telemetry.seeExampleOfWhatWeCollectLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>
|
||||
|
@ -61,7 +61,7 @@ exports[`TelemetryForm renders as expected 1`] = `
|
|||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Read our usage data privacy statement"
|
||||
id="xpack.main.telemetry.readOurUsageDataPrivacyStatementLinkText"
|
||||
id="xpack.telemetry.readOurUsageDataPrivacyStatementLinkText"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiLink>
|
|
@ -4,4 +4,5 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export { telemetryRoute } from './telemetry';
|
||||
export { TelemetryForm } from './telemetry_form';
|
||||
export { OptInExampleFlyout } from './opt_in_details_component';
|
|
@ -80,14 +80,14 @@ export class OptInExampleFlyout extends Component {
|
|||
return (
|
||||
<EuiCallOut
|
||||
title={<FormattedMessage
|
||||
id="xpack.main.telemetry.callout.errorUnprivilegedUserTitle"
|
||||
id="xpack.telemetry.callout.errorUnprivilegedUserTitle"
|
||||
defaultMessage="Error displaying cluster statistics"
|
||||
/>}
|
||||
color="danger"
|
||||
iconType="cross"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.main.telemetry.callout.errorUnprivilegedUserDescription"
|
||||
id="xpack.telemetry.callout.errorUnprivilegedUserDescription"
|
||||
defaultMessage="You do not have access to see unencrypted cluster statistics."
|
||||
/>
|
||||
</EuiCallOut>
|
||||
|
@ -98,14 +98,14 @@ export class OptInExampleFlyout extends Component {
|
|||
return (
|
||||
<EuiCallOut
|
||||
title={<FormattedMessage
|
||||
id="xpack.main.telemetry.callout.errorLoadingClusterStatisticsTitle"
|
||||
id="xpack.telemetry.callout.errorLoadingClusterStatisticsTitle"
|
||||
defaultMessage="Error loading cluster statistics"
|
||||
/>}
|
||||
color="danger"
|
||||
iconType="cross"
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.main.telemetry.callout.errorLoadingClusterStatisticsDescription"
|
||||
id="xpack.telemetry.callout.errorLoadingClusterStatisticsDescription"
|
||||
defaultMessage="An unexpected error occured while attempting to fetch the cluster statistics.
|
||||
This can occur because Elasticsearch failed, Kibana failed, or there is a network error.
|
||||
Check Kibana, then reload the page and try again."
|
||||
|
@ -133,7 +133,7 @@ export class OptInExampleFlyout extends Component {
|
|||
<EuiTitle>
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.main.telemetry.callout.clusterStatisticsTitle"
|
||||
id="xpack.telemetry.callout.clusterStatisticsTitle"
|
||||
defaultMessage="Cluster statistics"
|
||||
/>
|
||||
</h2>
|
||||
|
@ -141,7 +141,7 @@ export class OptInExampleFlyout extends Component {
|
|||
<EuiTextColor color="subdued">
|
||||
<EuiText>
|
||||
<FormattedMessage
|
||||
id="xpack.main.telemetry.callout.clusterStatisticsDescription"
|
||||
id="xpack.telemetry.callout.clusterStatisticsDescription"
|
||||
defaultMessage="This is an example of the basic cluster statistics that we'll collect.
|
||||
It includes the number of indices, shards, and nodes.
|
||||
It also includes high-level usage statistics, such as whether monitoring is turned on."
|
|
@ -16,7 +16,7 @@ import {
|
|||
EuiSpacer,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { getConfigTelemetryDesc, PRIVACY_STATEMENT_URL } from '../../../common/constants';
|
||||
import { getConfigTelemetryDesc, PRIVACY_STATEMENT_URL } from '../../common/constants';
|
||||
import { OptInExampleFlyout } from './opt_in_details_component';
|
||||
import { Field } from 'ui/management';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
@ -85,7 +85,7 @@ export class TelemetryForm extends Component {
|
|||
<EuiFlexItem grow={false}>
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.main.telemetry.usageDataTitle"
|
||||
id="xpack.telemetry.usageDataTitle"
|
||||
defaultMessage="Usage Data"
|
||||
/>
|
||||
</h2>
|
||||
|
@ -123,13 +123,13 @@ export class TelemetryForm extends Component {
|
|||
title={
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.main.telemetry.callout.appliesSettingTitle"
|
||||
id="xpack.telemetry.callout.appliesSettingTitle"
|
||||
defaultMessage="This setting applies to {allOfKibanaText}"
|
||||
values={{
|
||||
allOfKibanaText: (
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id="xpack.main.telemetry.callout.appliesSettingTitle.allOfKibanaText"
|
||||
id="xpack.telemetry.callout.appliesSettingTitle.allOfKibanaText"
|
||||
defaultMessage="all of Kibana."
|
||||
/>
|
||||
</strong>
|
||||
|
@ -148,7 +148,7 @@ export class TelemetryForm extends Component {
|
|||
<p>
|
||||
<EuiLink onClick={this.toggleExample}>
|
||||
<FormattedMessage
|
||||
id="xpack.main.telemetry.seeExampleOfWhatWeCollectLinkText"
|
||||
id="xpack.telemetry.seeExampleOfWhatWeCollectLinkText"
|
||||
defaultMessage="See an example of what we collect"
|
||||
/>
|
||||
</EuiLink>
|
||||
|
@ -156,7 +156,7 @@ export class TelemetryForm extends Component {
|
|||
<p>
|
||||
<EuiLink href={PRIVACY_STATEMENT_URL} target="_blank">
|
||||
<FormattedMessage
|
||||
id="xpack.main.telemetry.readOurUsageDataPrivacyStatementLinkText"
|
||||
id="xpack.telemetry.readOurUsageDataPrivacyStatementLinkText"
|
||||
defaultMessage="Read our usage data privacy statement"
|
||||
/>
|
||||
</EuiLink>
|
|
@ -7,7 +7,7 @@
|
|||
import React from 'react';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { TelemetryForm } from './telemetry_form';
|
||||
import { TelemetryOptInProvider } from '../../services/telemetry_opt_in';
|
||||
import { TelemetryOptInProvider } from '../services/telemetry_opt_in';
|
||||
|
||||
const buildTelemetryOptInProvider = () => {
|
||||
const mockHttp = {
|
|
@ -8,4 +8,4 @@ import { uiModules } from 'ui/modules';
|
|||
|
||||
import { injectBanner } from './welcome_banner';
|
||||
|
||||
uiModules.get('xpack_main/hacks').run(injectBanner);
|
||||
uiModules.get('telemetry/hacks').run(injectBanner);
|
|
@ -8,9 +8,10 @@ import { uiModules } from 'ui/modules';
|
|||
import { Path } from 'plugins/xpack_main/services/path';
|
||||
import { Telemetry } from './telemetry';
|
||||
import { fetchTelemetry } from './fetch_telemetry';
|
||||
import { npStart } from 'ui/new_platform';
|
||||
|
||||
function telemetryStart($injector) {
|
||||
const telemetryEnabled = $injector.get('telemetryEnabled');
|
||||
const telemetryEnabled = npStart.core.injectedMetadata.getInjectedVar('telemetryEnabled');
|
||||
|
||||
if (telemetryEnabled) {
|
||||
// no telemetry for non-logged in users
|
||||
|
@ -23,4 +24,4 @@ function telemetryStart($injector) {
|
|||
}
|
||||
}
|
||||
|
||||
uiModules.get('xpack_main/hacks').run(telemetryStart);
|
||||
uiModules.get('telemetry/hacks').run(telemetryStart);
|
|
@ -43,7 +43,7 @@ export async function clickBanner(
|
|||
_toastNotifications.addDanger({
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="xpack.main.telemetry.telemetryErrorNotificationMessageTitle"
|
||||
id="xpack.telemetry.telemetryErrorNotificationMessageTitle"
|
||||
defaultMessage="Telemetry Error"
|
||||
/>
|
||||
),
|
||||
|
@ -51,13 +51,13 @@ export async function clickBanner(
|
|||
<EuiText>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.main.telemetry.telemetryErrorNotificationMessageDescription.unableToSaveTelemetryPreferenceText"
|
||||
id="xpack.telemetry.telemetryErrorNotificationMessageDescription.unableToSaveTelemetryPreferenceText"
|
||||
defaultMessage="Unable to save telemetry preference."
|
||||
/>
|
||||
</p>
|
||||
<EuiText size="xs">
|
||||
<FormattedMessage
|
||||
id="xpack.main.telemetry.telemetryErrorNotificationMessageDescription.tryAgainText"
|
||||
id="xpack.telemetry.telemetryErrorNotificationMessageDescription.tryAgainText"
|
||||
defaultMessage="Check that Kibana and Elasticsearch are still running, then try again."
|
||||
/>
|
||||
</EuiText>
|
|
@ -10,6 +10,7 @@ import { fetchTelemetry } from '../fetch_telemetry';
|
|||
import { renderBanner } from './render_banner';
|
||||
import { shouldShowBanner } from './should_show_banner';
|
||||
import { TelemetryOptInProvider } from '../../services/telemetry_opt_in';
|
||||
import { npStart } from 'ui/new_platform';
|
||||
|
||||
/**
|
||||
* Add the Telemetry opt-in banner if the user has not already made a decision.
|
||||
|
@ -20,16 +21,10 @@ import { TelemetryOptInProvider } from '../../services/telemetry_opt_in';
|
|||
* @param {Object} $injector The Angular injector
|
||||
*/
|
||||
async function asyncInjectBanner($injector) {
|
||||
const telemetryEnabled = $injector.get('telemetryEnabled');
|
||||
const Private = $injector.get('Private');
|
||||
const telemetryOptInProvider = Private(TelemetryOptInProvider);
|
||||
const config = $injector.get('config');
|
||||
|
||||
// no banner if the server config has telemetry disabled
|
||||
if (!telemetryEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// and no banner for non-logged in users
|
||||
if (Path.isUnauthenticated()) {
|
||||
return;
|
||||
|
@ -54,5 +49,9 @@ async function asyncInjectBanner($injector) {
|
|||
* @param {Object} $injector The Angular injector
|
||||
*/
|
||||
export function injectBanner($injector) {
|
||||
asyncInjectBanner($injector);
|
||||
const telemetryEnabled = npStart.core.injectedMetadata.getInjectedVar('telemetryEnabled');
|
||||
const telemetryBanner = npStart.core.injectedMetadata.getInjectedVar('telemetryBanner');
|
||||
if (telemetryEnabled && telemetryBanner) {
|
||||
asyncInjectBanner($injector);
|
||||
}
|
||||
}
|
|
@ -58,7 +58,7 @@ export class OptInBanner extends Component {
|
|||
<EuiText>
|
||||
<p tabIndex="0">
|
||||
<FormattedMessage
|
||||
id="xpack.main.welcomeBanner.telemetryConfigDetailsDescription"
|
||||
id="xpack.telemetry.welcomeBanner.telemetryConfigDetailsDescription"
|
||||
defaultMessage="No information about the data you process or store will be sent. This feature
|
||||
will periodically send basic feature usage statistics. See an {exampleLink} or read our {telemetryPrivacyStatementLink}.
|
||||
You can disable this feature at any time."
|
||||
|
@ -66,7 +66,7 @@ export class OptInBanner extends Component {
|
|||
exampleLink: (
|
||||
<EuiLink onClick={() => this.setState({ showExample: !this.state.showExample })}>
|
||||
<FormattedMessage
|
||||
id="xpack.main.welcomeBanner.telemetryConfigDetailsDescription.exampleLinkText"
|
||||
id="xpack.telemetry.welcomeBanner.telemetryConfigDetailsDescription.exampleLinkText"
|
||||
defaultMessage="example"
|
||||
/>
|
||||
</EuiLink>
|
||||
|
@ -74,7 +74,7 @@ export class OptInBanner extends Component {
|
|||
telemetryPrivacyStatementLink: (
|
||||
<EuiLink href={PRIVACY_STATEMENT_URL} target="_blank" >
|
||||
<FormattedMessage
|
||||
id="xpack.main.welcomeBanner.telemetryConfigDetailsDescription.telemetryPrivacyStatementLinkText"
|
||||
id="xpack.telemetry.welcomeBanner.telemetryConfigDetailsDescription.telemetryPrivacyStatementLinkText"
|
||||
defaultMessage="telemetry privacy statement"
|
||||
/>
|
||||
</EuiLink>
|
||||
|
@ -99,7 +99,7 @@ export class OptInBanner extends Component {
|
|||
{getConfigTelemetryDesc()} {(
|
||||
<EuiLink onClick={() => this.setState({ showDetails: true })}>
|
||||
<FormattedMessage
|
||||
id="xpack.main.welcomeBanner.telemetryConfigDescription.readMoreLinkText"
|
||||
id="xpack.telemetry.welcomeBanner.telemetryConfigDescription.readMoreLinkText"
|
||||
defaultMessage="Read more"
|
||||
/>
|
||||
</EuiLink>
|
||||
|
@ -124,7 +124,7 @@ export class OptInBanner extends Component {
|
|||
onClick={() => this.props.optInClick(true)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.main.welcomeBanner.yesButtonLabel"
|
||||
id="xpack.telemetry.welcomeBanner.yesButtonLabel"
|
||||
defaultMessage="Yes"
|
||||
/>
|
||||
</EuiButton>
|
||||
|
@ -135,7 +135,7 @@ export class OptInBanner extends Component {
|
|||
onClick={() => this.props.optInClick(false)}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.main.welcomeBanner.noButtonLabel"
|
||||
id="xpack.telemetry.welcomeBanner.noButtonLabel"
|
||||
defaultMessage="No"
|
||||
/>
|
||||
</EuiButton>
|
|
@ -25,10 +25,10 @@ export function TelemetryOptInProvider($injector, chrome) {
|
|||
currentOptInStatus = enabled;
|
||||
} catch (error) {
|
||||
toastNotifications.addError(error, {
|
||||
title: i18n.translate('xpack.main.telemetry.optInErrorToastTitle', {
|
||||
title: i18n.translate('xpack.telemetry.optInErrorToastTitle', {
|
||||
defaultMessage: 'Error',
|
||||
}),
|
||||
toastMessage: i18n.translate('xpack.main.telemetry.optInErrorToastText', {
|
||||
toastMessage: i18n.translate('xpack.telemetry.optInErrorToastText', {
|
||||
defaultMessage: 'An error occured while trying to set the usage statistics preference.',
|
||||
}),
|
||||
});
|
46
x-pack/plugins/telemetry/server/collectors/get_stats.ts
Normal file
46
x-pack/plugins/telemetry/server/collectors/get_stats.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 { getAllStats, getLocalStats } from './';
|
||||
|
||||
/**
|
||||
* Get the telemetry data.
|
||||
*
|
||||
* @param {Object} req The incoming request.
|
||||
* @param {Object} config Kibana config.
|
||||
* @param {String} start The start time of the request (likely 20m ago).
|
||||
* @param {String} end The end time of the request.
|
||||
* @param {Boolean} unencrypted Is the request payload going to be unencrypted.
|
||||
* @return {Promise} An array of telemetry objects.
|
||||
*/
|
||||
export async function getStats(
|
||||
req: any,
|
||||
config: any,
|
||||
start: string,
|
||||
end: string,
|
||||
unencrypted: boolean,
|
||||
statsGetters: any = {}
|
||||
) {
|
||||
const { _getAllStats = getAllStats, _getLocalStats = getLocalStats } = statsGetters;
|
||||
let response = [];
|
||||
const useInternalUser = !unencrypted;
|
||||
|
||||
if (config.get('xpack.monitoring.enabled')) {
|
||||
try {
|
||||
// attempt to collect stats from multiple clusters in monitoring data
|
||||
response = await _getAllStats(req, start, end, { useInternalUser });
|
||||
} catch (err) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
if (!Array.isArray(response) || response.length === 0) {
|
||||
// return it as an array for a consistent API response
|
||||
response = [await _getLocalStats(req, { useInternalUser })];
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
|
@ -4,7 +4,11 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
// @ts-ignore
|
||||
export { getAllStats } from './monitoring';
|
||||
// @ts-ignore
|
||||
export { getLocalStats } from './local';
|
||||
export { getStats } from './get_stats';
|
||||
export { encryptTelemetry } from './encryption';
|
||||
export { createTelemetryUsageCollector } from './usage';
|
||||
export { createLocalizationUsageCollector } from './localization';
|
|
@ -4,4 +4,4 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export { telemetryRoute } from './telemetry';
|
||||
export { createLocalizationUsageCollector } from './telemetry_localization_collector';
|
|
@ -18,7 +18,7 @@ const createI18nLoaderMock = (translations: TranslationsMock) => {
|
|||
};
|
||||
};
|
||||
|
||||
import { getTranslationCount } from './get_localization_usage_collector';
|
||||
import { getTranslationCount } from './telemetry_localization_collector';
|
||||
|
||||
describe('getTranslationCount', () => {
|
||||
it('returns 0 if no translations registered', async () => {
|
|
@ -6,10 +6,8 @@
|
|||
|
||||
import { i18nLoader } from '@kbn/i18n';
|
||||
import { size } from 'lodash';
|
||||
// @ts-ignore
|
||||
import { KIBANA_LOCALIZATION_STATS_TYPE } from '../../common/constants';
|
||||
import { getIntegrityHashes, Integrities } from './file_integrity';
|
||||
|
||||
import { KIBANA_LOCALIZATION_STATS_TYPE } from '../../../common/constants';
|
||||
export interface UsageStats {
|
||||
locale: string;
|
||||
integrities: Integrities;
|
||||
|
@ -44,7 +42,7 @@ export function createCollectorFetch(server: any) {
|
|||
* @param {Object} server
|
||||
* @return {Object} kibana usage stats type collection object
|
||||
*/
|
||||
export function getLocalizationUsageCollector(server: any) {
|
||||
export function createLocalizationUsageCollector(server: any) {
|
||||
const { collectorSet } = server.usage;
|
||||
return collectorSet.makeUsageCollector({
|
||||
type: KIBANA_LOCALIZATION_STATS_TYPE,
|
|
@ -5,17 +5,15 @@
|
|||
*/
|
||||
|
||||
import { get, set, merge } from 'lodash';
|
||||
import {
|
||||
KIBANA_SYSTEM_ID,
|
||||
LOGSTASH_SYSTEM_ID,
|
||||
BEATS_SYSTEM_ID,
|
||||
} from '../../../../common/constants';
|
||||
|
||||
import { constants } from '../../';
|
||||
import { getClusterUuids } from './get_cluster_uuids';
|
||||
import { getElasticsearchStats } from './get_es_stats';
|
||||
import { getKibanaStats } from './get_kibana_stats';
|
||||
import { getBeatsStats } from './get_beats_stats';
|
||||
import { getHighLevelStats } from './get_high_level_stats';
|
||||
|
||||
|
||||
/**
|
||||
* Get statistics for all products joined by Elasticsearch cluster.
|
||||
*
|
||||
|
@ -66,7 +64,7 @@ function getAllStatsWithCaller(server, callCluster, start, end) {
|
|||
return Promise.all([
|
||||
getElasticsearchStats(server, callCluster, clusterUuids), // cluster_stats, stack_stats.xpack, cluster_name/uuid, license, version
|
||||
getKibanaStats(server, callCluster, clusterUuids, start, end), // stack_stats.kibana
|
||||
getHighLevelStats(server, callCluster, clusterUuids, start, end, LOGSTASH_SYSTEM_ID), // stack_stats.logstash
|
||||
getHighLevelStats(server, callCluster, clusterUuids, start, end, constants.LOGSTASH_SYSTEM_ID), // stack_stats.logstash
|
||||
getBeatsStats(server, callCluster, clusterUuids, start, end), // stack_stats.beats
|
||||
])
|
||||
.then(([esClusters, kibana, logstash, beats]) => handleAllStats(esClusters, { kibana, logstash, beats }));
|
||||
|
@ -85,9 +83,9 @@ function getAllStatsWithCaller(server, callCluster, start, end) {
|
|||
export function handleAllStats(clusters, { kibana, logstash, beats }) {
|
||||
return clusters.map(cluster => {
|
||||
// if they are using Kibana or Logstash, then add it to the cluster details under cluster.stack_stats
|
||||
addStackStats(cluster, kibana, KIBANA_SYSTEM_ID);
|
||||
addStackStats(cluster, logstash, LOGSTASH_SYSTEM_ID);
|
||||
addStackStats(cluster, beats, BEATS_SYSTEM_ID);
|
||||
addStackStats(cluster, kibana, constants.KIBANA_SYSTEM_ID);
|
||||
addStackStats(cluster, logstash, constants.LOGSTASH_SYSTEM_ID);
|
||||
addStackStats(cluster, beats, constants.BEATS_SYSTEM_ID);
|
||||
mergeXPackStats(cluster, kibana, 'graph_workspace', 'graph'); // copy graph_workspace info out of kibana, merge it into stack_stats.xpack.graph
|
||||
|
||||
return cluster;
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { get } from 'lodash';
|
||||
import { createQuery } from './create_query';
|
||||
import { INDEX_PATTERN_BEATS } from '../../../../../monitoring/common/constants';
|
||||
import { INDEX_PATTERN_BEATS } from '../../../../monitoring/common/constants';
|
||||
|
||||
const HITS_SIZE = 10000; // maximum hits to receive from ES with each search
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { get } from 'lodash';
|
||||
import { createQuery } from './create_query';
|
||||
import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../monitoring/common/constants';
|
||||
import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../monitoring/common/constants';
|
||||
|
||||
/**
|
||||
* Get a list of Cluster UUIDs that exist within the specified timespan.
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { get } from 'lodash';
|
||||
import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../monitoring/common/constants';
|
||||
import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../monitoring/common/constants';
|
||||
|
||||
/**
|
||||
* Get statistics for all selected Elasticsearch clusters.
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
import { get } from 'lodash';
|
||||
import { createQuery } from './create_query';
|
||||
import { INDEX_PATTERN_KIBANA, INDEX_PATTERN_BEATS, INDEX_PATTERN_LOGSTASH } from '../../../../../monitoring/common/constants';
|
||||
import { KIBANA_SYSTEM_ID, BEATS_SYSTEM_ID, APM_SYSTEM_ID, LOGSTASH_SYSTEM_ID, TELEMETRY_QUERY_SOURCE } from '../../../../common/constants';
|
||||
import { INDEX_PATTERN_KIBANA, INDEX_PATTERN_BEATS, INDEX_PATTERN_LOGSTASH } from '../../../../monitoring/common/constants';
|
||||
import { KIBANA_SYSTEM_ID, BEATS_SYSTEM_ID, APM_SYSTEM_ID, LOGSTASH_SYSTEM_ID, TELEMETRY_QUERY_SOURCE } from '../../../common/constants';
|
||||
|
||||
/**
|
||||
* Update a counter associated with the {@code key}.
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { get, isEmpty, omit } from 'lodash';
|
||||
import { KIBANA_SYSTEM_ID } from '../../../../common/constants';
|
||||
import { KIBANA_SYSTEM_ID } from '../../../common/constants';
|
||||
import { fetchHighLevelStats, handleHighLevelStatsResponse } from './get_high_level_stats';
|
||||
|
||||
export function rollUpTotals(rolledUp, addOn, field) {
|
|
@ -5,4 +5,3 @@
|
|||
*/
|
||||
|
||||
export { getAllStats } from './get_all_stats';
|
||||
|
|
@ -28,8 +28,8 @@ const serverWithConfig = (configPath: string): KibanaHapiServer & Server => {
|
|||
...getMockServer(),
|
||||
config: () => ({
|
||||
get: (key: string) => {
|
||||
if (key !== 'xpack.xpack_main.telemetry.config') {
|
||||
throw new Error('Expected `xpack.xpack_main.telemetry.config`');
|
||||
if (key !== 'xpack.telemetry.config' && key !== 'xpack.xpack_main.telemetry.config') {
|
||||
throw new Error('Expected `xpack.telemetry.config`');
|
||||
}
|
||||
|
||||
return configPath;
|
|
@ -11,6 +11,7 @@ import { dirname, join } from 'path';
|
|||
|
||||
// look for telemetry.yml in the same places we expect kibana.yml
|
||||
import { ensureDeepObject } from './ensure_deep_object';
|
||||
import { getXpackConfigWithDeprecated } from '../../../common/get_xpack_config_with_deprecated';
|
||||
|
||||
/**
|
||||
* The maximum file size before we ignore it (note: this limit is arbitrary).
|
||||
|
@ -85,7 +86,8 @@ export function createTelemetryUsageCollector(server: KibanaHapiServer) {
|
|||
type: 'static_telemetry',
|
||||
isReady: () => true,
|
||||
fetch: async () => {
|
||||
const configPath: string = server.config().get('xpack.xpack_main.telemetry.config');
|
||||
const config = server.config();
|
||||
const configPath = getXpackConfigWithDeprecated(config, 'telemetry.config') as string;
|
||||
const telemetryPath = join(dirname(configPath), 'telemetry.yml');
|
||||
return await readTelemetryFile(telemetryPath);
|
||||
},
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export async function getTelemetryOptIn(request) {
|
||||
export async function getTelemetryOptIn(request: any) {
|
||||
const isRequestingApplication = request.path.startsWith('/app');
|
||||
|
||||
// Prevent interstitial screens (such as the space selector) from prompting for telemetry
|
14
x-pack/plugins/telemetry/server/index.ts
Normal file
14
x-pack/plugins/telemetry/server/index.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 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 { PluginInitializerContext } from 'src/core/server';
|
||||
import { TelemetryPlugin } from './plugin';
|
||||
import * as constants from '../common/constants';
|
||||
|
||||
export { getTelemetryOptIn } from './get_telemetry_opt_in';
|
||||
export const telemetryPlugin = (initializerContext: PluginInitializerContext) =>
|
||||
new TelemetryPlugin();
|
||||
export { constants };
|
14
x-pack/plugins/telemetry/server/plugin.ts
Normal file
14
x-pack/plugins/telemetry/server/plugin.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 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 { CoreSetup } from 'src/core/server';
|
||||
import { registerRoutes } from './routes';
|
||||
|
||||
export class TelemetryPlugin {
|
||||
public setup(core: CoreSetup) {
|
||||
registerRoutes(core);
|
||||
}
|
||||
}
|
14
x-pack/plugins/telemetry/server/routes/index.ts
Normal file
14
x-pack/plugins/telemetry/server/routes/index.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* 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 { CoreSetup } from 'src/core/server';
|
||||
import { registerOptInRoutes } from './opt_in';
|
||||
import { registerTelemetryDataRoutes } from './telemetry_stats';
|
||||
|
||||
export function registerRoutes(core: CoreSetup) {
|
||||
registerOptInRoutes(core);
|
||||
registerTelemetryDataRoutes(core);
|
||||
}
|
43
x-pack/plugins/telemetry/server/routes/opt_in.ts
Normal file
43
x-pack/plugins/telemetry/server/routes/opt_in.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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 Joi from 'joi';
|
||||
import { boomify } from 'boom';
|
||||
import { CoreSetup } from 'src/core/server';
|
||||
|
||||
export function registerOptInRoutes(core: CoreSetup) {
|
||||
const { server } = core.http as any;
|
||||
|
||||
server.route({
|
||||
method: 'POST',
|
||||
path: '/api/telemetry/v2/optIn',
|
||||
options: {
|
||||
validate: {
|
||||
payload: Joi.object({
|
||||
enabled: Joi.bool().required(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
handler: async (req: any, h: any) => {
|
||||
const savedObjectsClient = req.getSavedObjectsClient();
|
||||
try {
|
||||
await savedObjectsClient.create(
|
||||
'telemetry',
|
||||
{
|
||||
enabled: req.payload.enabled,
|
||||
},
|
||||
{
|
||||
id: 'telemetry',
|
||||
overwrite: true,
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
return boomify(err);
|
||||
}
|
||||
return h.response({}).code(200);
|
||||
},
|
||||
});
|
||||
}
|
52
x-pack/plugins/telemetry/server/routes/telemetry_stats.ts
Normal file
52
x-pack/plugins/telemetry/server/routes/telemetry_stats.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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 Joi from 'joi';
|
||||
import { boomify } from 'boom';
|
||||
import { CoreSetup } from 'src/core/server';
|
||||
import { getStats, encryptTelemetry } from '../collectors';
|
||||
|
||||
export function registerTelemetryDataRoutes(core: CoreSetup) {
|
||||
const { server } = core.http as any;
|
||||
|
||||
server.route({
|
||||
method: 'POST',
|
||||
path: '/api/telemetry/v2/clusters/_stats',
|
||||
config: {
|
||||
validate: {
|
||||
payload: Joi.object({
|
||||
unencrypted: Joi.bool(),
|
||||
timeRange: Joi.object({
|
||||
min: Joi.date().required(),
|
||||
max: Joi.date().required(),
|
||||
}).required(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
handler: async (req: any, h: any) => {
|
||||
const config = req.server.config();
|
||||
const start = req.payload.timeRange.min;
|
||||
const end = req.payload.timeRange.max;
|
||||
const unencrypted = req.payload.unencrypted;
|
||||
const isDev = config.get('env.dev');
|
||||
|
||||
try {
|
||||
const usageData = await getStats(req, config, start, end, unencrypted);
|
||||
if (unencrypted) return usageData;
|
||||
return encryptTelemetry(usageData, isDev);
|
||||
} catch (err) {
|
||||
if (isDev) {
|
||||
// don't ignore errors when running in dev mode
|
||||
return boomify(err, { statusCode: err.status });
|
||||
} else {
|
||||
const statusCode = unencrypted && err.status === 403 ? 403 : 200;
|
||||
// ignore errors and return empty set
|
||||
return h.response([]).code(statusCode);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
|
@ -5226,31 +5226,31 @@
|
|||
"xpack.main.featureRegistry.indexPatternFeatureName": "インデックスパターン管理",
|
||||
"xpack.main.featureRegistry.savedObjectsManagementFeatureName": "保存されたオブジェクトの管理",
|
||||
"xpack.main.featureRegistry.visualizeFeatureName": "可視化",
|
||||
"xpack.main.telemetry.callout.appliesSettingTitle": "この設定は {allOfKibanaText} に適用されます",
|
||||
"xpack.main.telemetry.callout.appliesSettingTitle.allOfKibanaText": "Kibana のすべて",
|
||||
"xpack.main.telemetry.callout.clusterStatisticsDescription": "これは収集される基本的なクラスター統計の例です。インデックス、チャート、ノードの数が含まれます。監視がオンになっているかどうかなどのハイレベルの使用統計も含まれます。",
|
||||
"xpack.main.telemetry.callout.clusterStatisticsTitle": "クラスター統計",
|
||||
"xpack.main.telemetry.callout.errorLoadingClusterStatisticsDescription": "クラスター統計の取得中に予期せぬエラーが発生しました。Elasticsearch、Kibana、またはネットワークのエラーが原因の可能性があります。Kibana を確認し、ページを再読み込みして再試行してください。",
|
||||
"xpack.main.telemetry.callout.errorLoadingClusterStatisticsTitle": "クラスター統計の読み込みエラー",
|
||||
"xpack.main.telemetry.readOurUsageDataPrivacyStatementLinkText": "使用データのプライバシーステートメントをお読みください",
|
||||
"xpack.main.telemetry.seeExampleOfWhatWeCollectLinkText": "収集されるデータの例を見る",
|
||||
"xpack.main.telemetry.telemetryConfigDescription": "基本機能の使用統計を提供して Elastic Stack の改善にご協力ください。このデータは Elastic 社外と共有されません。",
|
||||
"xpack.main.telemetry.telemetryConfigTitle": "遠隔測定オプトイン",
|
||||
"xpack.main.telemetry.telemetryErrorNotificationMessageDescription.tryAgainText": "Kibana と Elasticsearch が現在も実行中であることを確認し、再試行してください。",
|
||||
"xpack.main.telemetry.telemetryErrorNotificationMessageDescription.unableToSaveTelemetryPreferenceText": "遠隔測定設定を保存できません。",
|
||||
"xpack.main.telemetry.telemetryErrorNotificationMessageTitle": "遠隔測定エラー",
|
||||
"xpack.main.telemetry.usageDataTitle": "使用データ",
|
||||
"xpack.telemetry.callout.appliesSettingTitle": "この設定は {allOfKibanaText} に適用されます",
|
||||
"xpack.telemetry.callout.appliesSettingTitle.allOfKibanaText": "Kibana のすべて",
|
||||
"xpack.telemetry.callout.clusterStatisticsDescription": "これは収集される基本的なクラスター統計の例です。インデックス、チャート、ノードの数が含まれます。監視がオンになっているかどうかなどのハイレベルの使用統計も含まれます。",
|
||||
"xpack.telemetry.callout.clusterStatisticsTitle": "クラスター統計",
|
||||
"xpack.telemetry.callout.errorLoadingClusterStatisticsDescription": "クラスター統計の取得中に予期せぬエラーが発生しました。Elasticsearch、Kibana、またはネットワークのエラーが原因の可能性があります。Kibana を確認し、ページを再読み込みして再試行してください。",
|
||||
"xpack.telemetry.callout.errorLoadingClusterStatisticsTitle": "クラスター統計の読み込みエラー",
|
||||
"xpack.telemetry.readOurUsageDataPrivacyStatementLinkText": "使用データのプライバシーステートメントをお読みください",
|
||||
"xpack.telemetry.seeExampleOfWhatWeCollectLinkText": "収集されるデータの例を見る",
|
||||
"xpack.telemetry.telemetryConfigDescription": "基本機能の使用統計を提供して Elastic Stack の改善にご協力ください。このデータは Elastic 社外と共有されません。",
|
||||
"xpack.telemetry.telemetryConfigTitle": "遠隔測定オプトイン",
|
||||
"xpack.telemetry.telemetryErrorNotificationMessageDescription.tryAgainText": "Kibana と Elasticsearch が現在も実行中であることを確認し、再試行してください。",
|
||||
"xpack.telemetry.telemetryErrorNotificationMessageDescription.unableToSaveTelemetryPreferenceText": "遠隔測定設定を保存できません。",
|
||||
"xpack.telemetry.telemetryErrorNotificationMessageTitle": "遠隔測定エラー",
|
||||
"xpack.telemetry.usageDataTitle": "使用データ",
|
||||
"xpack.main.uiSettings.adminEmailDescription": "監視からのクラスターアラートメール通知など、X-Pack 管理オペレーションの送信先のメールアドレスです。",
|
||||
"xpack.main.uiSettings.adminEmailTitle": "管理者メール",
|
||||
"xpack.main.welcomeBanner.licenseIsExpiredDescription": "管理者または {updateYourLicenseLinkText} に直接お問い合わせください。",
|
||||
"xpack.main.welcomeBanner.licenseIsExpiredDescription.updateYourLicenseLinkText": "ライセンスを更新",
|
||||
"xpack.main.welcomeBanner.licenseIsExpiredTitle": "ご使用の {licenseType} ライセンスは期限切れです",
|
||||
"xpack.main.welcomeBanner.noButtonLabel": "いいえ",
|
||||
"xpack.main.welcomeBanner.telemetryConfigDescription.readMoreLinkText": "詳細",
|
||||
"xpack.main.welcomeBanner.telemetryConfigDetailsDescription": "ユーザーが処理したり保管したりするデータに関する情報は一切送信されません。この機能は定期的に基本機能の使用統計を送信します。{exampleLink} をご覧いただくか、{telemetryPrivacyStatementLink} をお読みください。この機能はいつでも無効にできます。",
|
||||
"xpack.main.welcomeBanner.telemetryConfigDetailsDescription.exampleLinkText": "例",
|
||||
"xpack.main.welcomeBanner.telemetryConfigDetailsDescription.telemetryPrivacyStatementLinkText": "遠隔測定に関するプライバシーステートメント",
|
||||
"xpack.main.welcomeBanner.yesButtonLabel": "はい",
|
||||
"xpack.telemetry.welcomeBanner.noButtonLabel": "いいえ",
|
||||
"xpack.telemetry.welcomeBanner.telemetryConfigDescription.readMoreLinkText": "詳細",
|
||||
"xpack.telemetry.welcomeBanner.telemetryConfigDetailsDescription": "ユーザーが処理したり保管したりするデータに関する情報は一切送信されません。この機能は定期的に基本機能の使用統計を送信します。{exampleLink} をご覧いただくか、{telemetryPrivacyStatementLink} をお読みください。この機能はいつでも無効にできます。",
|
||||
"xpack.telemetry.welcomeBanner.telemetryConfigDetailsDescription.exampleLinkText": "例",
|
||||
"xpack.telemetry.welcomeBanner.telemetryConfigDetailsDescription.telemetryPrivacyStatementLinkText": "遠隔測定に関するプライバシーステートメント",
|
||||
"xpack.telemetry.welcomeBanner.yesButtonLabel": "はい",
|
||||
"xpack.maps.addLayerPanel.addLayerButtonLabel": "レイヤーを追加",
|
||||
"xpack.maps.addLayerPanel.cancelButtonLabel": "キャンセル",
|
||||
"xpack.maps.addLayerPanel.changeDataSourceButtonLabel": "データソースを変更",
|
||||
|
|
|
@ -4367,31 +4367,31 @@
|
|||
"xpack.logstash.upgradeFailureActions.goBackButtonLabel": "返回",
|
||||
"xpack.logstash.upstreamPipelineArgumentMustContainAnIdPropertyErrorMessage": "upstreamPipeline 参数必须包含 id 属性",
|
||||
"xpack.logstash.workersTooltip": "并行执行管道的筛选和输出阶段的工作线程数目。如果您发现事件出现积压或 CPU 未饱和,请考虑增大此数值,以更好地利用机器处理能力。\n\n默认值:主机的 CPU 核心数",
|
||||
"xpack.main.telemetry.callout.appliesSettingTitle": "此设置适用于{allOfKibanaText}",
|
||||
"xpack.main.telemetry.callout.appliesSettingTitle.allOfKibanaText": "所有 Kibana。",
|
||||
"xpack.main.telemetry.callout.clusterStatisticsDescription": "这是我们将收集的基本集群统计信息的示例。其包括索引、分片和节点的数目。还包括高级使用情况统计信息,例如监测是否打开。",
|
||||
"xpack.main.telemetry.callout.clusterStatisticsTitle": "集群统计信息",
|
||||
"xpack.main.telemetry.callout.errorLoadingClusterStatisticsDescription": "尝试提取集群统计信息时发生意外错误。发生此问题的原因可能是 Elasticsearch 出故障、Kibana 出故障,或者有网络错误。检查 Kibana,然后重新加载页面并重试。",
|
||||
"xpack.main.telemetry.callout.errorLoadingClusterStatisticsTitle": "加载集群统计信息时出错",
|
||||
"xpack.main.telemetry.readOurUsageDataPrivacyStatementLinkText": "阅读我们的使用情况数据隐私声明",
|
||||
"xpack.main.telemetry.seeExampleOfWhatWeCollectLinkText": "查看我们收集的内容示例",
|
||||
"xpack.main.telemetry.telemetryConfigDescription": "通过提供基本功能的使用情况统计信息,来帮助我们改进 Elastic Stack。我们不会在 Elastic 之外共享此数据。",
|
||||
"xpack.main.telemetry.telemetryConfigTitle": "遥测选择加入",
|
||||
"xpack.main.telemetry.telemetryErrorNotificationMessageDescription.tryAgainText": "确认 Kibana 和 Elasticsearch 仍在运行,然后重试。",
|
||||
"xpack.main.telemetry.telemetryErrorNotificationMessageDescription.unableToSaveTelemetryPreferenceText": "无法保存遥测首选项。",
|
||||
"xpack.main.telemetry.telemetryErrorNotificationMessageTitle": "遥测错误",
|
||||
"xpack.main.telemetry.usageDataTitle": "使用情况数据",
|
||||
"xpack.telemetry.callout.appliesSettingTitle": "此设置适用于{allOfKibanaText}",
|
||||
"xpack.telemetry.callout.appliesSettingTitle.allOfKibanaText": "所有 Kibana。",
|
||||
"xpack.telemetry.callout.clusterStatisticsDescription": "这是我们将收集的基本集群统计信息的示例。其包括索引、分片和节点的数目。还包括高级使用情况统计信息,例如监测是否打开。",
|
||||
"xpack.telemetry.callout.clusterStatisticsTitle": "集群统计信息",
|
||||
"xpack.telemetry.callout.errorLoadingClusterStatisticsDescription": "尝试提取集群统计信息时发生意外错误。发生此问题的原因可能是 Elasticsearch 出故障、Kibana 出故障,或者有网络错误。检查 Kibana,然后重新加载页面并重试。",
|
||||
"xpack.telemetry.callout.errorLoadingClusterStatisticsTitle": "加载集群统计信息时出错",
|
||||
"xpack.telemetry.readOurUsageDataPrivacyStatementLinkText": "阅读我们的使用情况数据隐私声明",
|
||||
"xpack.telemetry.seeExampleOfWhatWeCollectLinkText": "查看我们收集的内容示例",
|
||||
"xpack.telemetry.telemetryConfigDescription": "通过提供基本功能的使用情况统计信息,来帮助我们改进 Elastic Stack。我们不会在 Elastic 之外共享此数据。",
|
||||
"xpack.telemetry.telemetryConfigTitle": "遥测选择加入",
|
||||
"xpack.telemetry.telemetryErrorNotificationMessageDescription.tryAgainText": "确认 Kibana 和 Elasticsearch 仍在运行,然后重试。",
|
||||
"xpack.telemetry.telemetryErrorNotificationMessageDescription.unableToSaveTelemetryPreferenceText": "无法保存遥测首选项。",
|
||||
"xpack.telemetry.telemetryErrorNotificationMessageTitle": "遥测错误",
|
||||
"xpack.telemetry.usageDataTitle": "使用情况数据",
|
||||
"xpack.main.uiSettings.adminEmailDescription": "X-Pack 管理操作的接收人电子邮件地址,例如来自 Monitoring 的集群告警通知。",
|
||||
"xpack.main.uiSettings.adminEmailTitle": "管理电子邮件",
|
||||
"xpack.main.welcomeBanner.licenseIsExpiredDescription": "联系您的管理员或直接{updateYourLicenseLinkText}。",
|
||||
"xpack.main.welcomeBanner.licenseIsExpiredDescription.updateYourLicenseLinkText": "更新您的许可",
|
||||
"xpack.main.welcomeBanner.licenseIsExpiredTitle": "您的{licenseType}许可已过期",
|
||||
"xpack.main.welcomeBanner.noButtonLabel": "否",
|
||||
"xpack.main.welcomeBanner.telemetryConfigDescription.readMoreLinkText": "阅读更多内容",
|
||||
"xpack.main.welcomeBanner.telemetryConfigDetailsDescription": "不会发送有关您处理或存储的数据的信息。此功能将定期发送基本功能使用情况统计信息。请参阅{exampleLink}或阅读我们的{telemetryPrivacyStatementLink}。您可以随时禁用此功能。",
|
||||
"xpack.main.welcomeBanner.telemetryConfigDetailsDescription.exampleLinkText": "示例",
|
||||
"xpack.main.welcomeBanner.telemetryConfigDetailsDescription.telemetryPrivacyStatementLinkText": "遥测隐私声明",
|
||||
"xpack.main.welcomeBanner.yesButtonLabel": "是",
|
||||
"xpack.telemetry.welcomeBanner.noButtonLabel": "否",
|
||||
"xpack.telemetry.welcomeBanner.telemetryConfigDescription.readMoreLinkText": "阅读更多内容",
|
||||
"xpack.telemetry.welcomeBanner.telemetryConfigDetailsDescription": "不会发送有关您处理或存储的数据的信息。此功能将定期发送基本功能使用情况统计信息。请参阅{exampleLink}或阅读我们的{telemetryPrivacyStatementLink}。您可以随时禁用此功能。",
|
||||
"xpack.telemetry.welcomeBanner.telemetryConfigDetailsDescription.exampleLinkText": "示例",
|
||||
"xpack.telemetry.welcomeBanner.telemetryConfigDetailsDescription.telemetryPrivacyStatementLinkText": "遥测隐私声明",
|
||||
"xpack.telemetry.welcomeBanner.yesButtonLabel": "是",
|
||||
"xpack.ml.accessDenied.backToKibanaHomeButtonLabel": "返回 Kibana 主页",
|
||||
"xpack.ml.accessDenied.noGrantedPrivilegesDescription": "您必须具有 {kibanaUserParam} 和 {machineLearningUserParam} 角色授予的权限。{br}您的系统管理员可以在“管理用户”页面上设置这些角色。",
|
||||
"xpack.ml.accessDenied.noPermissionToAccessMLLabel": "您需要具备访问 Machine Learning 的权限",
|
||||
|
|
|
@ -13,34 +13,26 @@ import {
|
|||
import { mirrorPluginStatus } from '../../server/lib/mirror_plugin_status';
|
||||
import { replaceInjectedVars } from './server/lib/replace_injected_vars';
|
||||
import { setupXPackMain } from './server/lib/setup_xpack_main';
|
||||
import { getLocalizationUsageCollector } from './server/lib/get_localization_usage_collector';
|
||||
import { createTelemetryUsageCollector } from './server/lib/telemetry';
|
||||
import { uiCapabilitiesForFeatures } from './server/lib/ui_capabilities_for_features';
|
||||
import {
|
||||
xpackInfoRoute,
|
||||
featuresRoute,
|
||||
settingsRoute,
|
||||
} from './server/routes/api/v1';
|
||||
import { telemetryRoute } from './server/routes/api/v2';
|
||||
import {
|
||||
CONFIG_TELEMETRY,
|
||||
getConfigTelemetryDesc,
|
||||
} from './common/constants';
|
||||
import mappings from './mappings.json';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export { callClusterFactory } from './server/lib/call_cluster_factory';
|
||||
import { registerOssFeatures } from './server/lib/register_oss_features';
|
||||
import { uiCapabilitiesForFeatures } from './server/lib/ui_capabilities_for_features';
|
||||
import { has } from 'lodash';
|
||||
|
||||
/**
|
||||
* Determine if Telemetry is enabled.
|
||||
*
|
||||
* @param {Object} config Kibana configuration object.
|
||||
*/
|
||||
function isTelemetryEnabled(config) {
|
||||
return config.get('xpack.xpack_main.telemetry.enabled');
|
||||
function movedToTelemetry(configPath) {
|
||||
return (settings, log) => {
|
||||
if (has(settings, configPath)) {
|
||||
log(`Config key ${configPath} is deprecated. Use "xpack.telemetry.${configPath}" instead.`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export { callClusterFactory } from './server/lib/call_cluster_factory';
|
||||
export const xpackMain = (kibana) => {
|
||||
return new kibana.Plugin({
|
||||
id: 'xpack_main',
|
||||
|
@ -52,15 +44,10 @@ export const xpackMain = (kibana) => {
|
|||
return Joi.object({
|
||||
enabled: Joi.boolean().default(true),
|
||||
telemetry: Joi.object({
|
||||
// `config` is used internally and not intended to be set
|
||||
config: Joi.string().default(Joi.ref('$defaultConfigPath')),
|
||||
enabled: Joi.boolean().default(true),
|
||||
url: Joi.when('$dev', {
|
||||
is: true,
|
||||
then: Joi.string().default('https://telemetry-staging.elastic.co/xpack/v2/send'),
|
||||
otherwise: Joi.string().default('https://telemetry.elastic.co/xpack/v2/send')
|
||||
}),
|
||||
}).default(),
|
||||
config: Joi.string().default(),
|
||||
enabled: Joi.boolean().default(),
|
||||
url: Joi.string().default(),
|
||||
}).default(), // deprecated
|
||||
xpack_api_polling_frequency_millis: Joi.number().default(XPACK_INFO_API_DEFAULT_POLL_FREQUENCY_IN_MILLIS),
|
||||
}).default();
|
||||
},
|
||||
|
@ -70,16 +57,7 @@ export const xpackMain = (kibana) => {
|
|||
},
|
||||
|
||||
uiExports: {
|
||||
managementSections: ['plugins/xpack_main/views/management'],
|
||||
uiSettingDefaults: {
|
||||
[CONFIG_TELEMETRY]: {
|
||||
name: i18n.translate('xpack.main.telemetry.telemetryConfigTitle', {
|
||||
defaultMessage: 'Telemetry opt-in'
|
||||
}),
|
||||
description: getConfigTelemetryDesc(),
|
||||
value: false,
|
||||
readonly: true,
|
||||
},
|
||||
[XPACK_DEFAULT_ADMIN_EMAIL_UI_SETTING]: {
|
||||
name: i18n.translate('xpack.main.uiSettings.adminEmailTitle', {
|
||||
defaultMessage: 'Admin email'
|
||||
|
@ -93,26 +71,8 @@ export const xpackMain = (kibana) => {
|
|||
value: null
|
||||
}
|
||||
},
|
||||
savedObjectSchemas: {
|
||||
telemetry: {
|
||||
isNamespaceAgnostic: true,
|
||||
},
|
||||
},
|
||||
injectDefaultVars(server) {
|
||||
const config = server.config();
|
||||
|
||||
return {
|
||||
telemetryUrl: config.get('xpack.xpack_main.telemetry.url'),
|
||||
telemetryEnabled: isTelemetryEnabled(config),
|
||||
telemetryOptedIn: null,
|
||||
activeSpace: null,
|
||||
spacesEnabled: config.get('xpack.spaces.enabled'),
|
||||
};
|
||||
},
|
||||
hacks: [
|
||||
'plugins/xpack_main/hacks/check_xpack_info_change',
|
||||
'plugins/xpack_main/hacks/telemetry_opt_in',
|
||||
'plugins/xpack_main/hacks/telemetry_trigger',
|
||||
],
|
||||
replaceInjectedVars,
|
||||
__webpackPluginProvider__(webpack) {
|
||||
|
@ -124,7 +84,6 @@ export const xpackMain = (kibana) => {
|
|||
raw: true,
|
||||
});
|
||||
},
|
||||
mappings,
|
||||
},
|
||||
|
||||
init(server) {
|
||||
|
@ -136,13 +95,13 @@ export const xpackMain = (kibana) => {
|
|||
|
||||
// register routes
|
||||
xpackInfoRoute(server);
|
||||
telemetryRoute(server);
|
||||
settingsRoute(server, this.kbnServer);
|
||||
featuresRoute(server);
|
||||
|
||||
// usage collection
|
||||
server.usage.collectorSet.register(getLocalizationUsageCollector(server));
|
||||
server.usage.collectorSet.register(createTelemetryUsageCollector(server));
|
||||
}
|
||||
},
|
||||
deprecations: () => [
|
||||
movedToTelemetry('telemetry.config'),
|
||||
movedToTelemetry('telemetry.url'),
|
||||
movedToTelemetry('telemetry.enabled'),
|
||||
],
|
||||
});
|
||||
};
|
||||
|
|
|
@ -11,6 +11,3 @@ export { AddLicense } from '../../../license_management/public/sections/license_
|
|||
* For to link to management
|
||||
*/
|
||||
export { BASE_PATH as MANAGEMENT_BASE_PATH } from '../../../license_management/common/constants';
|
||||
|
||||
export { TelemetryForm } from './telemetry/telemetry_form';
|
||||
export { OptInExampleFlyout } from './telemetry/opt_in_details_component';
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { getTelemetryOptIn } from './get_telemetry_opt_in';
|
||||
import { getTelemetryOptIn } from '../../../telemetry/server';
|
||||
|
||||
export async function replaceInjectedVars(originalInjectedVars, request, server) {
|
||||
const xpackInfo = server.plugins.xpack_main.info;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
import { injectXPackInfoSignature } from './inject_xpack_info_signature';
|
||||
import { XPackInfo } from './xpack_info';
|
||||
import { REPORT_INTERVAL_MS } from '../../common/constants';
|
||||
import { FeatureRegistry } from './feature_registry';
|
||||
|
||||
/**
|
||||
|
@ -23,7 +22,6 @@ export function setupXPackMain(server) {
|
|||
});
|
||||
|
||||
server.expose('info', info);
|
||||
server.expose('telemetryCollectionInterval', REPORT_INTERVAL_MS);
|
||||
server.expose('createXPackInfo', (options) => new XPackInfo(server, options));
|
||||
server.ext('onPreResponse', (request, h) => injectXPackInfoSignature(info, request, h));
|
||||
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import { getTelemetry } from '../telemetry';
|
||||
|
||||
describe('telemetry', () => {
|
||||
|
||||
describe('getTelemetry', () => {
|
||||
|
||||
const req = { };
|
||||
const config = { };
|
||||
const start = 'start';
|
||||
const end = 'end';
|
||||
let _getAllStats;
|
||||
let _getLocalStats;
|
||||
|
||||
beforeEach(() => {
|
||||
config.get = sinon.stub();
|
||||
_getAllStats = sinon.stub();
|
||||
_getLocalStats = sinon.stub();
|
||||
});
|
||||
|
||||
it('returns monitoring telemetry when possible', async () => {
|
||||
const response = [ { totally: 'real' } ];
|
||||
|
||||
config.get.withArgs('xpack.monitoring.enabled').returns(true);
|
||||
_getAllStats.withArgs(req, start, end).returns(response);
|
||||
|
||||
expect(await getTelemetry(req, config, start, end, false, { _getAllStats, _getLocalStats })).to.be(response);
|
||||
|
||||
expect(config.get.calledOnce).to.be(true);
|
||||
expect(_getAllStats.calledOnce).to.be(true);
|
||||
expect(_getLocalStats.calledOnce).to.be(false);
|
||||
});
|
||||
|
||||
it('uses local and ignores monitoring telemetry when empty', async () => {
|
||||
const response = { collection: 'local' };
|
||||
|
||||
config.get.withArgs('xpack.monitoring.enabled').returns(true);
|
||||
_getAllStats.withArgs(req, start, end).returns([]);
|
||||
_getLocalStats.withArgs(req).returns(response);
|
||||
|
||||
expect(await getTelemetry(req, config, start, end, false, { _getAllStats, _getLocalStats })).to.eql([ response ]);
|
||||
|
||||
expect(config.get.calledOnce).to.be(true);
|
||||
expect(_getAllStats.calledOnce).to.be(true);
|
||||
expect(_getLocalStats.calledOnce).to.be(true);
|
||||
});
|
||||
|
||||
it('uses local and ignores monitoring telemetry when invalid', async () => {
|
||||
const response = { collection: 'local' };
|
||||
|
||||
config.get.withArgs('xpack.monitoring.enabled').returns(true);
|
||||
_getAllStats.withArgs(req, start, end).returns({ not: 'an array' });
|
||||
_getLocalStats.withArgs(req).returns(response);
|
||||
|
||||
expect(await getTelemetry(req, config, start, end, false, { _getAllStats, _getLocalStats })).to.eql([ response ]);
|
||||
|
||||
expect(config.get.calledOnce).to.be(true);
|
||||
expect(_getAllStats.calledOnce).to.be(true);
|
||||
expect(_getLocalStats.calledOnce).to.be(true);
|
||||
});
|
||||
|
||||
it('uses local when monitoring is disabled', async () => {
|
||||
const response = { collection: 'local' };
|
||||
|
||||
config.get.withArgs('xpack.monitoring.enabled').returns(false);
|
||||
_getLocalStats.withArgs(req).returns(response);
|
||||
|
||||
expect(await getTelemetry(req, config, start, end, false, { _getAllStats, _getLocalStats })).to.eql([ response ]);
|
||||
|
||||
expect(config.get.calledOnce).to.be(true);
|
||||
expect(_getAllStats.calledOnce).to.be(false);
|
||||
expect(_getLocalStats.calledOnce).to.be(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* 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 Joi from 'joi';
|
||||
import { boomify } from 'boom';
|
||||
import { getAllStats, getLocalStats, encryptTelemetry } from '../../../../lib/telemetry';
|
||||
|
||||
/**
|
||||
* Get the telemetry data.
|
||||
*
|
||||
* @param {Object} req The incoming request.
|
||||
* @param {Object} config Kibana config.
|
||||
* @param {String} start The start time of the request (likely 20m ago).
|
||||
* @param {String} end The end time of the request.
|
||||
* @param {Boolean} unencrypted Is the request payload going to be unencrypted.
|
||||
* @return {Promise} An array of telemetry objects.
|
||||
*/
|
||||
export async function getTelemetry(req, config, start, end, unencrypted, statsGetters = {}) {
|
||||
const { _getAllStats = getAllStats, _getLocalStats = getLocalStats } = statsGetters;
|
||||
let response = [];
|
||||
const useInternalUser = !unencrypted;
|
||||
|
||||
if (config.get('xpack.monitoring.enabled')) {
|
||||
try {
|
||||
// attempt to collect stats from multiple clusters in monitoring data
|
||||
response = await _getAllStats(req, start, end, { useInternalUser });
|
||||
} catch (err) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
if (!Array.isArray(response) || response.length === 0) {
|
||||
// return it as an array for a consistent API response
|
||||
response = [await _getLocalStats(req, { useInternalUser })];
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export function telemetryRoute(server) {
|
||||
/**
|
||||
* Change Telemetry Opt-In preference.
|
||||
*/
|
||||
server.route({
|
||||
method: 'POST',
|
||||
path: '/api/telemetry/v2/optIn',
|
||||
config: {
|
||||
validate: {
|
||||
payload: Joi.object({
|
||||
enabled: Joi.bool().required()
|
||||
})
|
||||
}
|
||||
},
|
||||
handler: async (req, h) => {
|
||||
const savedObjectsClient = req.getSavedObjectsClient();
|
||||
try {
|
||||
await savedObjectsClient.create('telemetry', {
|
||||
enabled: req.payload.enabled
|
||||
}, {
|
||||
id: 'telemetry',
|
||||
overwrite: true,
|
||||
});
|
||||
} catch (err) {
|
||||
return boomify(err);
|
||||
}
|
||||
return h.response({}).code(200);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Telemetry Data
|
||||
*
|
||||
* This provides a mechanism for fetching minor details about all clusters, including details related to the rest of the
|
||||
* stack (e.g., Kibana).
|
||||
*/
|
||||
server.route({
|
||||
method: 'POST',
|
||||
path: '/api/telemetry/v2/clusters/_stats',
|
||||
config: {
|
||||
validate: {
|
||||
payload: Joi.object({
|
||||
unencrypted: Joi.bool(),
|
||||
timeRange: Joi.object({
|
||||
min: Joi.date().required(),
|
||||
max: Joi.date().required()
|
||||
}).required()
|
||||
})
|
||||
}
|
||||
},
|
||||
handler: async (req, h) => {
|
||||
const config = req.server.config();
|
||||
const start = req.payload.timeRange.min;
|
||||
const end = req.payload.timeRange.max;
|
||||
const unencrypted = req.payload.unencrypted;
|
||||
const isDev = config.get('env.dev');
|
||||
|
||||
try {
|
||||
const usageData = await getTelemetry(req, config, start, end, unencrypted);
|
||||
if (unencrypted) return usageData;
|
||||
return encryptTelemetry(usageData, isDev);
|
||||
} catch (err) {
|
||||
if (isDev) {
|
||||
// don't ignore errors when running in dev mode
|
||||
return boomify(err, { statusCode: err.status });
|
||||
} else {
|
||||
const statusCode = unencrypted && err.status === 403 ? 403 : 200;
|
||||
// ignore errors and return empty set
|
||||
return h.response([]).code(statusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
|
@ -12,6 +12,7 @@ export default function ({ loadTestFile }) {
|
|||
loadTestFile(require.resolve('./security'));
|
||||
loadTestFile(require.resolve('./monitoring'));
|
||||
loadTestFile(require.resolve('./xpack_main'));
|
||||
loadTestFile(require.resolve('./telemetry'));
|
||||
loadTestFile(require.resolve('./logstash'));
|
||||
loadTestFile(require.resolve('./kibana'));
|
||||
loadTestFile(require.resolve('./infra'));
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue