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] Application Usage implemented in @kbn/analytics #58401

Merged

Conversation

afharo
Copy link
Member

@afharo afharo commented Feb 24, 2020

Summary

Add a plugin that retrieves the time (in minutes) and the number of clicks on each application inside Kibana and report it via telemetry.

It uses its own index to store the grouped events in the form of { timestamp, appId, numberOfClicks, minutesOfScreenTime }. Rolling up the information to saved objects for the entries older than 90 days (because the required reported data has 3 levels of aggregation: 30 days, 90 days and total).

The finally reported information to our telemetry service looks like below:

    "stack_stats": {
      "kibana": {
        "plugins": {
           ...
           "application_usage": {
             "logs": {
                 "clicks_total": 1000,
                 "clicks_30_days": 10,
                 "clicks_90_days": 100,
                 "minutes_on_screen_total": 58.93,
                 "minutes_on_screen_30_days": 10.23,
                 "minutes_on_screen_90_days": 30.0,
             },
             "apm": { ...},
             ...
           }
           ...
       }
  }

Fixes #52737

Checklist

Delete any items that are not applicable to this PR.

For maintainers

@elasticmachine
Copy link
Contributor

Pinging @elastic/pulse (Team:Pulse)

@afharo afharo requested a review from Bamieh February 24, 2020 19:44
@afharo
Copy link
Member Author

afharo commented Feb 24, 2020

I'm pending to write tests to this alternative implementation.

@Bamieh the bit I like #57893 best is that the implementation is self-contained in one plugin, whereas in this one the logic is spread across 3 entities:

  • @kbn/analytics for the frontend collection logic: listeners + localStorage + batch reporting to the API
  • usage_collector for the API handling (storing into Saved Objects)
  • telemetry for the usage collection logic (aggregate documents from the Saved Objects + roll up indices old documents.

But I get it that this one reuses many of the capabilities already implemented and tested in those 3 components 👍

@afharo
Copy link
Member Author

afharo commented Feb 24, 2020

@elasticmachine merge upstream

@afharo afharo marked this pull request as ready for review February 26, 2020 11:43
@afharo afharo requested a review from a team as a code owner February 26, 2020 11:43
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, lets get it merged!

Just a thought: I wish we had the event listeners in the application_usage/public plugin instead of kbn-analytics/src/reporter.ts and then these listeners would call the kbn analytics methods to update usage state.

Thanks for all the thorough tests!

@afharo
Copy link
Member Author

afharo commented Feb 27, 2020

I wish we had the event listeners in the application_usage/public plugin instead of kbn-analytics/src/reporter.ts

I thought about it but then I thought it was maybe not a good idea to publicly expose the "add clicks" or like the common logic when it's supposed to send the report (similar to the setInterval for sending the report sits in the reporter instead of the plugin).

But I don't have a strong opinion about it. Happy to revisit this at any point.

Similarly, we should start adding tests to that side library at some point 😅(especially if it's going to grow over time). But we can do it on a separate PR if that's fine :)


export type Metric = UiStatsMetric | UserAgentMetric;
export type Metric = UiStatsMetric | UserAgentMetric | ApplicationUsageCurrent;
Copy link
Contributor

Choose a reason for hiding this comment

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

Aside and not for this PR: We might want to consider adding a generic type that devs can use for metrics not falling into any of the current metric types. For example: the recent File Upload migration to the NP includes a a request to add File Upload as a type. We should think about how to handle cases like these where we might not necessarily allow an overwrite of the generic type but rather have that if a generic type is used, there must be another descriptor (like a description) tag in the data we're capturing. e.g. metric type='generic', and description='File Upload`.

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's a fair comment. I think the main reason why we haven't used the UIStatsMetrics more is because of the way we report them (as arrays).

I'm sure we'll be coming back to this at some point with the new Pulse approach where arrays won't be an issue anymore.

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.

In an ideal world, we'd be adding the new collector directly in the NP and not extending anything in the Legacy world.
One nit to add yet more tests and I know I'm being greedy! Feel free to add later.
LGTM!

jest.runTimersToTime(ROLL_INDICES_INTERVAL);
});

test('when savedObjectClient is initialised, return something', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: We should also be testing internal methods used when we are returning the 'something'. i.e: rollTotals.

setTimeout(() => rollTotals(getSavedObjectsClient()), ROLL_INDICES_START);
}

async function rollTotals(savedObjectsClient?: ISavedObjectsRepository) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We're using this method to aggregate data and it should at least have a rudimentary test since it's also using findAll.

@afharo
Copy link
Member Author

afharo commented Feb 28, 2020

In an ideal world, we'd be adding the new collector directly in the NP and not extending anything in the Legacy world.

You are right! I feel bad for having all these new additions to the Legacy folder. Good thing it's using the NP components internally, so migrating them should be a piece of cake once we solve all the other challenges (i.e.: the registered routes at the moment rely heavily on the Legacy code). The public side of the telemetry plugin has already been migrated to NP. It's only the server side the one that is missing at this point. Maybe we should bring back up in the priorities #38765

Since I have a fresh memory regarding this piece of code. I can volunteer to do the changes.

One nit to add yet more tests and I know I'm being greedy! Feel free to add later.

You are totally right! I was force-running it via jest.runTimersToTime(ROLL_INDICES_INTERVAL);, but not testing the outcoming results (and actually found a bug that I was adding the totals on every iteration so we were coming up with a number way higher than expected). Just added a check at the mock to ensure we are storing the right data.
You should be able to see the changes in this commit

LGTM!

Thank you for your review :)

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

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

@afharo afharo merged commit fd25ae6 into elastic:master Feb 28, 2020
@afharo afharo deleted the telemetry/application-usage-in-kbn-analytics branch February 28, 2020 16:52
afharo added a commit to afharo/kibana that referenced this pull request Feb 28, 2020
…58401)

* [Telemetry] Report the Application Usage (time of usage + number of clicks)

* Add Unit tests to the server side

* Do not use optional chaining in JS

* Add tests on the public end

* Fix jslint errors

* jest.useFakeTimers() + jest.clearAllTimers()

* Remove Jest timer handlers from my tests (only affecting to a minimum coverage bit)

* Catch ES actions in the setup/start steps because it broke core_services tests

* Fix boolean check

* Use core's ES.adminCLient over .createClient

* Fix tests after ES.adminClient

* [Telemetry] Application Usage implemented in kbn-analytics

* Use bulkCreate in store_report

* ApplicationUsagePluginStart does not exist anymore

* Fix usage_collection mock interface

* Check there is something to store before calling the bulkCreate method

* Add unit tests

* Fix types in tests

* Unit tests for rollTotals and actual fix for the bug found

* Fix usage_collection mock after elastic#57693 got merged

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
afharo added a commit that referenced this pull request Feb 28, 2020
…58904)

* [Telemetry] Report the Application Usage (time of usage + number of clicks)

* Add Unit tests to the server side

* Do not use optional chaining in JS

* Add tests on the public end

* Fix jslint errors

* jest.useFakeTimers() + jest.clearAllTimers()

* Remove Jest timer handlers from my tests (only affecting to a minimum coverage bit)

* Catch ES actions in the setup/start steps because it broke core_services tests

* Fix boolean check

* Use core's ES.adminCLient over .createClient

* Fix tests after ES.adminClient

* [Telemetry] Application Usage implemented in kbn-analytics

* Use bulkCreate in store_report

* ApplicationUsagePluginStart does not exist anymore

* Fix usage_collection mock interface

* Check there is something to store before calling the bulkCreate method

* Add unit tests

* Fix types in tests

* Unit tests for rollTotals and actual fix for the bug found

* Fix usage_collection mock after #57693 got merged

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

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
@TinaHeiligers TinaHeiligers moved this from 7.x / 8.0 to Closed in Telemetry 7.6 / 7.x Mar 10, 2020
@lukeelmers lukeelmers added the Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc label 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 release_note:enhancement Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.7.0 v8.0.0
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

Add telemetry for application usage
6 participants