[EBT] Add Telemetry Labels (#135682)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Alejandro Fernández Haro 2022-07-14 15:58:57 +02:00 committed by GitHub
parent 21a9b24fed
commit 9888244e2c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 90 additions and 1 deletions

1
.github/CODEOWNERS vendored
View file

@ -332,6 +332,7 @@
/packages/kbn-handlebars/ @elastic/kibana-security
/packages/core/http/core-http-server-internal/src/csp/ @elastic/kibana-security @elastic/kibana-core
/src/plugins/interactive_setup/ @elastic/kibana-security
/src/plugins/telemetry/server/config/telemetry_labels.ts @elastic/kibana-security
/test/interactive_setup_api_integration/ @elastic/kibana-security
/test/interactive_setup_functional/ @elastic/kibana-security
/test/plugin_functional/test_suites/core_plugins/rendering.ts @elastic/kibana-security

View file

@ -40,6 +40,7 @@ export function mockTelemetryService({
allowChangingOptInStatus: true,
telemetryNotifyUserAboutOptInDefault: true,
userCanChangeSettings: true,
labels: {},
...configOverride,
};

View file

@ -21,6 +21,7 @@ import type { ScreenshotModePluginSetup } from '@kbn/screenshot-mode-plugin/publ
import type { HomePublicPluginSetup } from '@kbn/home-plugin/public';
import { ElasticV3BrowserShipper } from '@kbn/analytics-shippers-elastic-v3-browser';
import { of } from 'rxjs';
import { TelemetrySender, TelemetryService, TelemetryNotifications } from './services';
import type {
TelemetrySavedObjectAttributes,
@ -104,6 +105,8 @@ export interface TelemetryPluginConfig {
userCanChangeSettings?: boolean;
/** Should we hide the privacy statement notice? Useful on some environments, e.g. Cloud */
hidePrivacyStatement?: boolean;
/** Extra labels to add to the telemetry context */
labels: Record<string, unknown>;
}
function getTelemetryConstants(docLinks: DocLinksStart): TelemetryConstants {
@ -146,6 +149,19 @@ export class TelemetryPlugin implements Plugin<TelemetryPluginSetup, TelemetryPl
telemetryConstants = getTelemetryConstants(docLinks);
});
analytics.registerContextProvider({
name: 'telemetry labels',
context$: of({ labels: this.config.labels }),
schema: {
labels: {
type: 'pass_through',
_meta: {
description: 'Custom labels added to the telemetry.labels config in the kibana.yml',
},
},
},
});
analytics.registerShipper(ElasticV3BrowserShipper, {
channelName: 'kibana-browser',
version: currentKibanaVersion,

View file

@ -9,6 +9,7 @@
import { schema, TypeOf, Type } from '@kbn/config-schema';
import { getConfigPath } from '@kbn/utils';
import { PluginConfigDescriptor } from '@kbn/core/server';
import { labelsSchema } from './telemetry_labels';
const clusterEnvSchema: [Type<'prod'>, Type<'staging'>] = [
schema.literal('prod'),
@ -32,6 +33,8 @@ const configSchema = schema.object({
sendUsageFrom: schema.oneOf([schema.literal('server'), schema.literal('browser')], {
defaultValue: 'server',
}),
// Used for extra enrichment of telemetry
labels: labelsSchema,
});
export type TelemetryConfigType = TypeOf<typeof configSchema>;
@ -45,6 +48,7 @@ export const config: PluginConfigDescriptor<TelemetryConfigType> = {
sendUsageFrom: true,
sendUsageTo: true,
hidePrivacyStatement: true,
labels: true,
},
deprecations: () => [
(cfg) => {

View file

@ -8,3 +8,4 @@
export { config } from './config';
export type { TelemetryConfigType } from './config';
export type { TelemetryConfigLabels } from './telemetry_labels';

View file

@ -0,0 +1,33 @@
/*
* 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.
*/
import { schema, TypeOf } from '@kbn/config-schema';
/**
* Labels to enrich the context of the telemetry generated.
* When adding new keys, bear in mind that this info is exposed
* to the browser **even to unauthenticated pages**.
*/
export const labelsSchema = schema.object(
{
branch: schema.maybe(schema.string()),
ciBuildJobId: schema.maybe(schema.string()),
ciBuildId: schema.maybe(schema.string()),
ciBuildNumber: schema.maybe(schema.number()),
ftrConfig: schema.maybe(schema.string()),
git_rev: schema.maybe(schema.string()),
isPr: schema.maybe(schema.boolean()),
prId: schema.maybe(schema.string()),
journeyName: schema.maybe(schema.string()),
testBuildId: schema.maybe(schema.string()),
testJobId: schema.maybe(schema.string()),
},
{ defaultValue: {} }
);
export type TelemetryConfigLabels = TypeOf<typeof labelsSchema>;

View file

@ -19,6 +19,7 @@ import {
takeUntil,
tap,
shareReplay,
map,
} from 'rxjs';
import { ElasticV3ServerShipper } from '@kbn/analytics-shippers-elastic-v3-server';
@ -45,7 +46,7 @@ import {
registerTelemetryUsageCollector,
registerTelemetryPluginUsageCollector,
} from './collectors';
import type { TelemetryConfigType } from './config';
import type { TelemetryConfigLabels, TelemetryConfigType } from './config';
import { FetcherTask } from './fetcher';
import { getTelemetrySavedObject, TelemetrySavedObject } from './telemetry_repository';
import { OPT_IN_POLL_INTERVAL_MS } from '../common/constants';
@ -157,6 +158,19 @@ export class TelemetryPlugin implements Plugin<TelemetryPluginSetup, TelemetryPl
sendTo: this.initialConfig.sendUsageTo === 'prod' ? 'production' : 'staging',
});
analytics.registerContextProvider<{ labels: TelemetryConfigLabels }>({
name: 'telemetry labels',
context$: this.config$.pipe(map(({ labels }) => ({ labels }))),
schema: {
labels: {
type: 'pass_through',
_meta: {
description: 'Custom labels added to the telemetry.labels config in the kibana.yml',
},
},
},
});
const config$ = this.config$;
const isDev = this.isDev;
registerCollection(telemetryCollectionManager);

View file

@ -264,6 +264,7 @@ exports[`TelemetryManagementSectionComponent renders null because allowChangingO
"defaultConfig": Object {
"allowChangingOptInStatus": false,
"banner": true,
"labels": Object {},
"optIn": true,
"sendUsageFrom": "browser",
"sendUsageTo": "staging",

View file

@ -30,6 +30,7 @@ describe('TelemetryManagementSectionComponent', () => {
allowChangingOptInStatus: true,
optIn: true,
sendUsageFrom: 'browser',
labels: {},
},
isScreenshotMode: false,
reportOptInStatusChange: false,
@ -61,6 +62,7 @@ describe('TelemetryManagementSectionComponent', () => {
optIn: false,
sendUsageFrom: 'browser',
sendUsageTo: 'staging',
labels: {},
},
isScreenshotMode: false,
reportOptInStatusChange: false,
@ -112,6 +114,7 @@ describe('TelemetryManagementSectionComponent', () => {
optIn: false,
sendUsageTo: 'staging',
sendUsageFrom: 'browser',
labels: {},
},
isScreenshotMode: false,
reportOptInStatusChange: false,
@ -157,6 +160,7 @@ describe('TelemetryManagementSectionComponent', () => {
optIn: true,
sendUsageTo: 'staging',
sendUsageFrom: 'browser',
labels: {},
},
isScreenshotMode: false,
reportOptInStatusChange: false,
@ -193,6 +197,7 @@ describe('TelemetryManagementSectionComponent', () => {
optIn: false,
sendUsageTo: 'staging',
sendUsageFrom: 'browser',
labels: {},
},
isScreenshotMode: false,
reportOptInStatusChange: false,
@ -233,6 +238,7 @@ describe('TelemetryManagementSectionComponent', () => {
optIn: false,
sendUsageTo: 'staging',
sendUsageFrom: 'browser',
labels: {},
},
isScreenshotMode: false,
reportOptInStatusChange: false,
@ -280,6 +286,7 @@ describe('TelemetryManagementSectionComponent', () => {
optIn: false,
sendUsageTo: 'staging',
sendUsageFrom: 'browser',
labels: {},
},
isScreenshotMode: false,
reportOptInStatusChange: false,

View file

@ -143,6 +143,17 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
'newsfeed.service.urlRoot (string)',
'telemetry.allowChangingOptInStatus (boolean)',
'telemetry.banner (boolean)',
'telemetry.labels.branch (string)',
'telemetry.labels.ciBuildId (string)',
'telemetry.labels.ciBuildJobId (string)',
'telemetry.labels.ciBuildNumber (number)',
'telemetry.labels.ftrConfig (string)',
'telemetry.labels.git_rev (string)',
'telemetry.labels.isPr (boolean)',
'telemetry.labels.journeyName (string)',
'telemetry.labels.prId (string)',
'telemetry.labels.testBuildId (string)',
'telemetry.labels.testJobId (string)',
'telemetry.hidePrivacyStatement (boolean)',
'telemetry.optIn (boolean)',
'telemetry.sendUsageFrom (alternatives)',