Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Telemetry] Collector Schema #64942

Merged
merged 38 commits into from
Jun 26, 2020
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
86563ce
first working draft
Bamieh Apr 30, 2020
e80f27f
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh Apr 30, 2020
a870296
first working draft
Bamieh Apr 30, 2020
80b3257
add more test scenarios
Bamieh May 4, 2020
adb1bea
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh May 4, 2020
9f68343
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh May 6, 2020
b4dfeb8
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh May 11, 2020
babf185
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh May 17, 2020
1dbee95
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh May 23, 2020
16ed263
finalize initial implementation
Bamieh May 26, 2020
e580992
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh May 26, 2020
c452ab4
running typechecker
Bamieh May 26, 2020
ddc5f12
add telemetry cli checker - phase 1
Bamieh May 26, 2020
fa81c2a
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh May 27, 2020
a3fad35
xpack .telemetryrc file
Bamieh Jun 1, 2020
e2795af
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh Jun 1, 2020
1c3e112
code review changes
Bamieh Jun 12, 2020
34444f2
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh Jun 12, 2020
a924d65
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh Jun 12, 2020
526d132
reporting usage
Bamieh Jun 14, 2020
b5c50d7
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh Jun 14, 2020
b95a431
ready for review
Bamieh Jun 15, 2020
0e879d6
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh Jun 15, 2020
fd2086e
self code review
Bamieh Jun 15, 2020
23d087a
fix typecheck
Bamieh Jun 15, 2020
f957e67
fix some more schemas
Bamieh Jun 15, 2020
902f5ff
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh Jun 15, 2020
e04a074
move into a pacakge
Bamieh Jun 18, 2020
71dc5b1
merge master
Bamieh Jun 18, 2020
9afad1a
Merge branch 'master' into telemetry/automate_mapping
elasticmachine Jun 18, 2020
f1f4146
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh Jun 24, 2020
3c360f0
add CI job and complete code review suggestions
Bamieh Jun 24, 2020
3ecf97e
fix typecheck
Bamieh Jun 24, 2020
bf590ee
fix package tests
Bamieh Jun 24, 2020
32664b9
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh Jun 24, 2020
1fd4625
revert to maps-telemetry
Bamieh Jun 25, 2020
f5bd5f1
Merge branch 'master' of github.com:elastic/kibana into telemetry/aut…
Bamieh Jun 25, 2020
bac4718
revert to maps
Bamieh Jun 25, 2020
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
5 changes: 5 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@
/src/plugins/telemetry_management_section/ @elastic/pulse
/src/plugins/usage_collection/ @elastic/pulse
/x-pack/plugins/telemetry_collection_xpack/ @elastic/pulse
.telemetryrc.json @elastic/pulse
/src/dev/telemetry/ @elastic/pulse
src/plugins/telemetry/schema/legacy_oss_plugins.json @elastic/pulse
src/plugins/telemetry/schema/oss_plugins.json @elastic/pulse
x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @elastic/pulse
afharo marked this conversation as resolved.
Show resolved Hide resolved

# Kibana Alerting Services
/x-pack/plugins/alerts/ @elastic/kibana-alerting-services
Expand Down
25 changes: 25 additions & 0 deletions .telemetryrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[
{
"output": "src/plugins/telemetry/schema/legacy_oss_plugins.json",
"root": "src/legacy/core_plugins/",
"exclude": [
"src/legacy/core_plugins/testbed",
"src/legacy/core_plugins/elasticsearch",
"src/legacy/core_plugins/tests_bundle"
]
},
{
"output": "src/plugins/telemetry/schema/oss_plugins.json",
"root": "src/plugins/",
"exclude": [
"src/plugins/kibana_react/",
"src/plugins/testbed/",
"src/plugins/kibana_utils/",
"src/plugins/kibana_usage_collection/server/collectors/kibana/kibana_usage_collector.ts",
"src/plugins/kibana_usage_collection/server/collectors/application_usage/telemetry_application_usage_collector.ts",
"src/plugins/kibana_usage_collection/server/collectors/management/telemetry_management_collector.ts",
"src/plugins/kibana_usage_collection/server/collectors/ui_metric/telemetry_ui_metric_collector.ts",
"src/plugins/telemetry/server/collectors/usage/telemetry_usage_collector.ts"
Bamieh marked this conversation as resolved.
Show resolved Hide resolved
]
}
]
21 changes: 21 additions & 0 deletions scripts/telemetry_check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

require('../src/setup_node_env');
Bamieh marked this conversation as resolved.
Show resolved Hide resolved
require('../src/dev/run_telemetry_check');
21 changes: 21 additions & 0 deletions scripts/telemetry_extract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

require('../src/setup_node_env');
require('../src/dev/run_telemetry_extract');
107 changes: 107 additions & 0 deletions src/dev/run_telemetry_check.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import Listr from 'listr';
import chalk from 'chalk';
import { createFailError, run } from '@kbn/dev-utils';

import {
createTaskContext,
ErrorReporter,
parseConfigsTask,
extractCollectorsTask,
checkMatchingSchemasTask,
generateSchemasTask,
checkCompatibleTypesTask,
writeToFileTask,
TaskContext,
} from './telemetry/tasks';

run(
async ({ flags: { fix = false, path }, log }) => {
if (typeof fix !== 'boolean') {
throw createFailError(`${chalk.white.bgRed(' TELEMETRY ERROR ')} --fix can't have a value`);
}

if (typeof path === 'boolean') {
throw createFailError(`${chalk.white.bgRed(' TELEMETRY ERROR ')} --path require a value`);
}

if (fix && typeof path !== 'undefined') {
throw createFailError(
`${chalk.white.bgRed(' TELEMETRY ERROR ')} --fix is incompatible with --path flag.`
);
}

const list = new Listr([
{
title: 'Checking .telemetryrc.json files',
task: () => new Listr(parseConfigsTask(), { exitOnError: true }),
},
{
title: 'Extracting Collectors',
task: (context) => new Listr(extractCollectorsTask(context, path), { exitOnError: true }),
},
{
title: 'Checking Compatible collector.schema with collector.fetch type',
task: (context) => new Listr(checkCompatibleTypesTask(context), { exitOnError: true }),
},
{
title: 'Checking Matching collector.schema against stored json files',
task: (context) => new Listr(checkMatchingSchemasTask(context), { exitOnError: true }),
},
{
enabled: (_) => fix,
skip: ({ roots }: TaskContext) => {
return roots.every(({ esMappingDiffs }) => !esMappingDiffs || !esMappingDiffs.length);
},
title: 'Generating new telemetry mappings',
task: (context) => new Listr(generateSchemasTask(context), { exitOnError: true }),
},
{
enabled: (_) => fix,
skip: ({ roots }: TaskContext) => {
return roots.every(({ esMappingDiffs }) => !esMappingDiffs || !esMappingDiffs.length);
},
title: 'Updating telemetry mapping files',
task: (context) => new Listr(writeToFileTask(context), { exitOnError: true }),
},
]);

try {
const context = createTaskContext();
await list.run(context);
} catch (error) {
process.exitCode = 1;
if (error instanceof ErrorReporter) {
error.errors.forEach((e: string | Error) => log.error(e));
} else {
log.error('Unhandled exception!');
log.error(error);
}
}
process.exit();
},
{
flags: {
allowUnexpected: true,
guessTypesForUnexpectedFlags: true,
},
}
);
73 changes: 73 additions & 0 deletions src/dev/run_telemetry_extract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import Listr from 'listr';
import { run } from '@kbn/dev-utils';

import {
createTaskContext,
ErrorReporter,
parseConfigsTask,
extractCollectorsTask,
generateSchemasTask,
writeToFileTask,
} from './telemetry/tasks';

run(
async ({ flags: {}, log }) => {
const list = new Listr([
{
title: 'Parsing .telemetryrc.json files',
task: () => new Listr(parseConfigsTask(), { exitOnError: true }),
},
{
title: 'Extracting Telemetry Collectors',
task: (context) => new Listr(extractCollectorsTask(context), { exitOnError: true }),
},
{
title: 'Generating Schema files',
task: (context) => new Listr(generateSchemasTask(context), { exitOnError: true }),
},
{
title: 'Writing to file',
task: (context) => new Listr(writeToFileTask(context), { exitOnError: true }),
},
]);

try {
const context = createTaskContext();
await list.run(context);
} catch (error) {
process.exitCode = 1;
if (error instanceof ErrorReporter) {
error.errors.forEach((e: string | Error) => log.error(e));
} else {
log.error('Unhandled exception');
log.error(error);
}
}
process.exit();
},
{
flags: {
allowUnexpected: true,
guessTypesForUnexpectedFlags: true,
},
}
);
89 changes: 89 additions & 0 deletions src/dev/telemetry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Telemetry Tools

## Schema extraction tool

### Description

The tool is used to extract telemetry collectors schema from all `*.{js, ts, jsx, tsx, html, pug}` files in provided plugins directories to JSON files. The tool looks for `.telemeryrc.json` files in the root of the project and in the `x-pack` dir for its runtime configurations.
Bamieh marked this conversation as resolved.
Show resolved Hide resolved

It uses typescript parser to build an AST for each file. The tool is able to validate, extract and match collector schemas.

### Examples and restrictions

**Global restrictions**:

The `id` can be only a string literal, it cannot be a template literals w/o expressions or string-only concatenation expressions or anything else.

```
export const myCollector = makeUsageCollector<Usage>({
type: 'string_literal_only',
...
});
```

### Usage

```bash
node scripts/telemetry_extract.js
```

This command has no additional flags or arguments. The `.telemetryrc.json` files specify the path to the directory(-es) where searching should start, output json files, and files to exclude.
Bamieh marked this conversation as resolved.
Show resolved Hide resolved


### Output


The generated JSON files contain an ES mapping for each schema. This mapping is used to verify changes in the collectors and as the basis to map those fields into the external telemetry cluster.

**Example**:

```json
{
"properties": {
"cloud": {
"properties": {
"isCloudEnabled": {
"type": "boolean"
}
}
}
}
}
```

## Schema validation tool

### Description

The tool performs a number of checks on all telemetry collectors and verifies the following:

1. Verifies the collector structure, fields, and returned values are using the appropriate types.
2. Verifies that the collector `fetch` function Type matches the specified `schema` in the collector.
3. Verifies that the collector `schema` matches the stored json schema .

### Notes

We don't catch every possible misuse of the collectors, but only the most common and critical ones.

What will not be caught by the validator:

* Mistyped SavedObject/CallCluster return value. Since the hits returned from ES can be typed to anything without any checks. It is advised to add functional tests that grabs the schema json file and checks that the returned usage matches the types exactly.

* Fields in the schema that are never collected. If you are trying to report a field from ES but that value is never stored in ES, the check will not be able to detect if that field is ever collected in the first palce. It is advised to add unit/functional tests to check that all the fields are being reported as expected.

The tool looks for `.telemeryrc.json` files in the root of the project and in the `x-pack` dir for its runtime configurations.
Bamieh marked this conversation as resolved.
Show resolved Hide resolved

Currently auto-fixer (`--fix`) can automatically fix the json files with the following errors:

* incompatible schema - this error means that the collector schema was changed but the stored json schema file was not updated.

* unused schemas - this error means that a collector was removed or its `type` renamed, the json schema file contains a schema that does not have a corrisponding collector.

### Usage

```bash
node scripts/telemetry_check --path src/plugins/my_plugin --fix
```

* `--path` specifies a collector path instead of checking all collectors specified in the `.telemetryrc.json` files. Accepts a `.ts` file. The file must be discoverable by at least one rc file.
* `--fix` tells the tool to try to fix as much violations as possible. All errors that tool won't be able to fix will be reported.
Bamieh marked this conversation as resolved.
Show resolved Hide resolved
7 changes: 7 additions & 0 deletions src/dev/telemetry/__fixture__/.telemetryrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"root": ".",
"output": ".",
"exclude": [
"./unmapped_collector.ts"
]
}
Loading