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] Server-side Migration to NP #60485

Merged
merged 28 commits into from
Mar 23, 2020

Conversation

afharo
Copy link
Member

@afharo afharo commented Mar 18, 2020

Summary

Migrate the server-side code of the Telemetry plugin to the NP.

Fixes #38765
Fixes #60443

Checklist

Delete any items that are not applicable to this PR.

For maintainers

@elasticmachine
Copy link
Contributor

Pinging @elastic/pulse (Team:Pulse)

@afharo
Copy link
Member Author

afharo commented Mar 19, 2020

@elasticmachine merge upstream

@elasticmachine
Copy link
Contributor

merge conflict between base and head

@@ -25,9 +25,6 @@ export default function(kibana: any) {
id: 'ui_metric',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still keeping this one here to maintain in legacy the ui_metric feature. But it's using the NP logic under the hood. It can safely be removed when getting rid of the legacy folder

@afharo afharo marked this pull request as ready for review March 19, 2020 16:16
@afharo afharo requested review from a team as code owners March 19, 2020 16:16
@afharo afharo requested a review from a team March 19, 2020 16:16
@chrisronline
Copy link
Contributor

FWIW, the PR for stack monitoring going to NP is nearly ready to merge: #56675

I imagine whoever goes second will need to update as a result and make any necessary changes

@afharo
Copy link
Member Author

afharo commented Mar 19, 2020

@chrisronline thanks for the heads up! :)

@@ -6,4 +6,4 @@ Telemetry allows Kibana features to have usage tracked in the wild. The general
2. Sending a payload of usage data up to Elastic's telemetry cluster.
3. Viewing usage data in the Kibana instance of the telemetry cluster (Viewing).

This plugin is responsible for sending usage data to the telemetry cluster. For collecting usage data, use
This plugin is responsible for sending usage data to the telemetry cluster. For collecting usage data, use the [`usageCollection` plugin](../usage_collection/README.md)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for finishing the sentence!

Copy link
Contributor

@TinaHeiligers TinaHeiligers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@afharo I'm still working through this. It's a huge PR but looking good so far.

if (isDev) {
// don't ignore errors when running in dev mode
throw err;
} else if (unencrypted && err.status === 403) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with splitting the ternary out here and making it more explicit.

Copy link
Contributor

@TinaHeiligers TinaHeiligers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran the code locally and the migration to NP works well!
Nice refactoring of some areas too, great work!
I've left a few comments and nits but otherwise LGTM once merge conflicts are resolved and tests pass again.

.config()
.get('pkg.version')
.replace(/-snapshot/i, '');
const version = serverVersion.replace(/-snapshot/i, ''); // Shouldn't we better maintain the -snapshot so we can differentiate between actual final releases and snapshots?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Shouldn't we better maintain the -snapshot so we can differentiate between actual final releases and snapshots?

I don't mind either way.

import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { CoreSetup } from 'kibana/server';

class Plugin {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: It might be worth adding an empty start method here to show the difference clearly between this example and the example below
e.g.

    class Plugin {
      public setup(core: CoreSetup, plugins: { usageCollection?: UsageCollectionSetup }) {
        registerMyPluginUsageCollector(plugins.usageCollection);
      }
      public start() {}
    }

to worry about exceeding the 1000-field soft limit in Elasticsearch.

The only caveat is that it makes it harder to consume in Kibana when analysing each entry in the array separately. In the telemetry team we are working to find a solution to this. We are building a new way of reporting telemetry called [Pulse](../../../rfcs/text/0008_pulse.md) that will help on making these UI-Metrics easier to consume.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome!

expect(
await getHighLevelStats(server, callWith, clusterUuids, start, end, product)
).toStrictEqual(expectedClusters);
expect(await getHighLevelStats(callWith, clusterUuids, start, end, product, 1)).toStrictEqual(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd prefer an explicit declaration of maxBucketSize=1 being passed in here. Numbers tend to go 'missing' when directly embedded in code.

@@ -254,7 +243,7 @@ describe('get_high_level_stats', () => {
callWith.returns(Promise.resolve(response));

expect(
await fetchHighLevelStats(server, callWith, clusterUuids, start, end, product)
await fetchHighLevelStats(callWith, clusterUuids, start, end, product, 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above

export function registerMonitoringCollection(
telemetryCollectionManager: TelemetryCollectionManagerPluginSetup,
customContext: CustomContext
) {
telemetryCollectionManager.setCollection({
esCluster: 'monitoring',
title: 'monitoring',
priority: 2,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Should we not consider explicitly declaring collection priority in the telemetryCollectionManager rather than embedding priorities in here? That way, we could make the priority order more explicit.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that sounds like a neat suggestion, but I'd rather tackle it in a new issue since it's not related to the migration, itself


## Development

See the [kibana contributing guide](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md) for instructions setting up your development environment.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: 'See the kibana contributing guide for instructions on how to set up your development environment.'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha! good call! this is actually an auto-generated message by the node scripts/generate_plugin.js script :)

@@ -0,0 +1,9 @@
# telemetry_collection_xpack

> Add the telemetry collector with the xpack information
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the description into something that hopefully explains it better.

telemetryCollectionManager.setCollection({
esCluster: 'data',
title: 'local_xpack',
priority: 1,
Copy link
Contributor

@TinaHeiligers TinaHeiligers Mar 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment about embedding priority collection numbers in code above.

@afharo
Copy link
Member Author

afharo commented Mar 22, 2020

@elasticmachine merge upstream

@afharo afharo requested a review from a team as a code owner March 23, 2020 09:11
@afharo
Copy link
Member Author

afharo commented Mar 23, 2020

@chrisronline I've merged those changes and applied mine on top. Hopefully, they make sense now.

Copy link
Contributor

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only looked at platform owned files. LGTM.

Comment on lines 30 to 31
export async function i18nMixin(kbnServer: KbnServer, server: Server, config: KbnServer['config']) {
const locale = config.get('i18n.locale') as string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: KbnServer['config'] -> KbnConfig

const count = await getTranslationCount(i18nLoaderMock, 'en');
const count = await getTranslationCount(i18nLoaderMock as any, 'en');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: If createI18nLoaderMock cannot be adapted to return the proper signatures, I would at least have it handle the cast to typeof i18nLoader to avoid doing it in every test.

Comment on lines 20 to 29
import { i18nLoader } from '@kbn/i18n';
import { size } from 'lodash';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { getIntegrityHashes, Integrities } from './file_integrity';
import { KIBANA_LOCALIZATION_STATS_TYPE } from '../../../common/constants';
import { UsageCollectionSetup } from '../../../../../../plugins/usage_collection/server';
import { KIBANA_LOCALIZATION_STATS_TYPE } from '../constants';

export interface UsageStats {
locale: string;
integrities: Integrities;
labelsCount?: number;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this file moving out of the telemetry plugin?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it depends on the i18n configuration. In NP, we won't have access to other plugins' config.
Also: the way usage collection works is for every plugin to report its own specific telemetry. So it kind of makes more sense to me for the i18n to report the telemetry from here rather than exposing the config so the telemetry plugin can report it.
But happy to change it if necessary :)

Copy link
Contributor

@igoristic igoristic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good from the Stack Monitoring side 👍

Though I am curious why you're passing down maxBucketSize instead of using config.get('monitoring.ui.max_bucket_size') directly, and should we do that for other config.get('...') values if there are benefits

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@afharo
Copy link
Member Author

afharo commented Mar 23, 2020

@igoristic thank you for your review.

In NP the support to config.get('...') is dropped in favour of config.ui.max_bucket_size, that can be retrieved like:

export class MyPlugin implements Plugin {
  private readonly config$: Observable<MyPluginConfig>;
  constructor(initializerContext: PluginInitializerContext) {
    this.config$ = initializerContext.config.create();
  }

  public async setup(core: CoreSetup, deps: MyPluginDepsSetup) {
    const config = await this.config$.pipe(take(1)).toPromise();
    const maxBucketSize = config.ui.max_bucket_size;
  }
}

We can provide in the context the full config object if we want to. But I wanted to maintain some separation of concerns since only 1 config property was needed at this point :)

Copy link
Member

@Bamieh Bamieh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, i did pull the code locally but I havent done thorough testing over the changes.

@afharo afharo merged commit 452193f into elastic:master Mar 23, 2020
@afharo afharo deleted the telemetry/server-migration-to-np branch March 23, 2020 18:49
afharo added a commit to afharo/kibana that referenced this pull request Mar 23, 2020
* [Telemetry] Migration to NP

* Telemetry management advanced settings section + fix import paths + dropped support for injectVars

* Fix i18nrc paths for telemetry

* Move ui_metric mappings to NP registerType

* Fixed minor test tweaks

* Add README docs (elastic#60443)

* Add missing translation

* Update the telemetryService config only when authenticated

* start method is not a promise anymore

* Fix mocha tests

* No need to JSON.stringify the API responses

* Catch handleOldSettings as we used to do

* Deal with the forbidden use case in the optIn API

* No need to provide the plugin name in the logger.get(). It is automatically scoped + one missing CallCluster vs. APICaller type replacement

* Add empty start method in README.md to show differences with the other approach

* Telemetry collection with X-Pack README

* Docs update

* Allow monitoring collector to send its own ES client

* All collections should provide their own ES client

* PR feedback

* i18n NITs from kibana-platform feedback

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
afharo added a commit that referenced this pull request Mar 23, 2020
* [Telemetry] Migration to NP

* Telemetry management advanced settings section + fix import paths + dropped support for injectVars

* Fix i18nrc paths for telemetry

* Move ui_metric mappings to NP registerType

* Fixed minor test tweaks

* Add README docs (#60443)

* Add missing translation

* Update the telemetryService config only when authenticated

* start method is not a promise anymore

* Fix mocha tests

* No need to JSON.stringify the API responses

* Catch handleOldSettings as we used to do

* Deal with the forbidden use case in the optIn API

* No need to provide the plugin name in the logger.get(). It is automatically scoped + one missing CallCluster vs. APICaller type replacement

* Add empty start method in README.md to show differences with the other approach

* Telemetry collection with X-Pack README

* Docs update

* Allow monitoring collector to send its own ES client

* All collections should provide their own ES client

* PR feedback

* i18n NITs from kibana-platform feedback

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
@lukeelmers lukeelmers added Feature:Telemetry Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc labels Oct 1, 2021
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-core (Team:Core)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Telemetry Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.7.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Telemetry/Pulse] Update ui_metrics README [Telemetry] Fully migrate to new platform
10 participants