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

[Usage collection] Usage counters #96696

Merged
merged 17 commits into from
Apr 14, 2021
Merged

Conversation

Bamieh
Copy link
Member

@Bamieh Bamieh commented Apr 9, 2021

Usage Counters

Usage counters allows plugins to report user triggered events from the server. This api has feature parity with UI Counters on the public plugin side of usage_collection.

Usage counters provide instrumentation on the server to count triggered events such as "api called", "threshold reached", and miscellaneous events count.

It is useful for gathering semi-aggregated events with a per day granularity.
This allows tracking trends in usage and provides enough granularity for this type of telemetry to provide insights such as

  • "How many times this threshold has been reached"
  • "What is the trend in usage of this api"
  • "How frequent are users hitting this error per day"
  • "What is the success rate of this operation"
  • "Which option is being selected the most/least"

How to use it

To create a usage counter for your plugin, use the API usageCollection.createUsageCounter as follows:

// server/plugin.ts
import { Plugin, CoreStart } from '../../../core/public';
import { UsageCollectionSetup, UsageCounter } from '../../../plugins/usage_collection/server';

export class MyPlugin implements Plugin {
  private usageCounter?: UsageCounter;
  public setup(
    core: CoreStart,
    { usageCollection }: { usageCollection?: UsageCollectionSetup }
  ) {

    /**
     * Create a usage counter for this plugin. Domain ID must be unique.
     * It is advised to use the plugin name as the domain ID for most cases.
     */
    this.usageCounter = usageCollection?.createUsageCounter('<Domain ID>');
    try {
      doSomeOperation();
      this.usageCounter?.incrementCounter({
        counterName: 'doSomeOperation_success',
        incrementBy: 1,
      });
    } catch (err) {
      this.usageCounter?.incrementCounter({
        counterName: 'doSomeOperation_error',
        counterType: 'error',
        incrementBy: 1,
      });
      logger.error(err);
    }
  }
}

Pass the created usageCounter around in your service to instrument usage.

That's all you need to do! The Usage counters service will handle piping these counters all the way to the telemetry service.

Telemetry reported usage

Usage counters are reported inside the telemetry usage payload under stack_stats.kibana.plugins.usage_counters.

{
  usage_counters: {
    dailyEvents: [
      {
        domainId: '<Domain ID>',
        counterName: 'doSomeOperation_success',
        counterType: 'count',
        lastUpdatedAt: '2021-11-20T11:43:00.961Z',
        fromTimestamp: '2021-11-20T00:00:00Z',
        total: 3,
      },
      {
        domainId: '<Domain ID>',
        counterName: 'doSomeOperation_success',
        counterType: 'count',
        lastUpdatedAt: '2021-11-21T10:30:00.961Z',
        fromTimestamp: '2021-11-21T00:00:00Z',
        total: 5,
      },
      {
        domainId: '<Domain ID>',
        counterName: 'doSomeOperation_error',
        counterType: 'error',
        lastUpdatedAt: '2021-11-20T11:43:00.961Z',
        fromTimestamp: '2021-11-20T00:00:00Z',
        total: 1,
      },
    ],
  },
}

Code reviewer?

Closes #81645

I've updated the usage_collection.mocks file which might have affected a few files outside the core team owned files. If you are requested a review please filter by CODEOWNERS and look for changes ❤️ .

Implementation Notes

RxJS is used to handle buffering the events every 5s to avoid redundant SO calls from the same counter.
The service uses a single source$ which keeps the implementation light and allows batching multiple counters as a future enhancement (currently not supported by savedObjects.incrementCounter).

Daily-aggregated events are deleted by a rollup function once they become older than 5 days. Until then telemetry will keep reporting these events in the daily payload.

We've chosen 5 days to make sure all triggered events are reported while accomodating to "The weekend effect".

If usageCollection.usageCounters.enabled is set to false the service will not subscribe to the events source effectively it stops collecitng the data avoiding redundant function calls and if statements. Currently the service will keep on collecting data usage even if telemetry is disabled to stay consistent with other collection services. This can be easily changed via rxjs by changing the subject.connect logic from automtic on subscribe to manually calling connect in the telemetry plugin on start.

Usage counters will be flushed to savedobjects on start once SO is ready. During setup the service will cache any counter increments in an in memory buffer (Rx.RelaySubject).

UI Counters is now using usage counters api to store the counters data. The collector is also fetching the data from the Usage Counters service and filtering on uiCounter domain ID.

UI Counters will trigger roll ups against the deprecated ui-counter saved objects registry until all the previous data is drained. Migration from one SO registry to another is not yet supported hence this draining logic is needed to make sure we dont lose any data from the no longer used ui-counter SO registry. In a future release we can remove the UI Counters roll up code.

The service was implemented closely to how we've implemented other service inside core to allow easier transfer of usage_collection to core in the future.

The service is fully tested: api_integration/usage_counters, api_integration/telemetry, plugin_functional (demo plugin), and unit tests!

@Bamieh Bamieh added v8.0.0 release_note:skip Skip the PR/issue when compiling release notes v7.13.0 labels Apr 9, 2021
Copy link
Member

@afharo afharo left a comment

Choose a reason for hiding this comment

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

Wow! What an effort! Great job @Bamieh! I've added a few comments and NITs. Will review more in detail on Tuesday or when the PR is released from draft. Have a great weekend.

@Bamieh Bamieh marked this pull request as ready for review April 12, 2021 08:58
@Bamieh Bamieh requested a review from a team as a code owner April 12, 2021 08:58
@Bamieh Bamieh requested a review from a team April 12, 2021 08:58
@Bamieh Bamieh requested review from a team as code owners April 12, 2021 08:58
@Bamieh Bamieh requested a review from afharo April 12, 2021 08:58
Copy link
Contributor

@flash1293 flash1293 left a comment

Choose a reason for hiding this comment

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

Kibana app changes LGTM, code review only. Only mock import changes in tests.

Copy link
Member

@afharo afharo left a comment

Choose a reason for hiding this comment

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

I've noticed a potential bug, holding the SOs from being stored.

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 a few NITs and questions

Copy link
Contributor

@mattkime mattkime left a comment

Choose a reason for hiding this comment

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

app services changes look good to me

Co-authored-by: Alejandro Fernández Haro <[email protected]>
Copy link
Member

@afharo afharo left a comment

Choose a reason for hiding this comment

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

Tested locally (and played with the APIs). LGTM!

Great PR @Bamieh! 🎉

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.

LGTM once the config renaming is done

src/plugins/usage_collection/server/config.ts Outdated Show resolved Hide resolved
@Bamieh Bamieh added the auto-backport Deprecated - use backport:version if exact versions are needed label Apr 14, 2021
@Bamieh Bamieh enabled auto-merge (squash) April 14, 2021 10:21
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Saved Objects .kibana field count

Every field in each saved object type adds overhead to Elasticsearch. Kibana needs to keep the total field count below Elasticsearch's default limit of 1000 fields. Only specify field mappings for the fields you wish to search on or query. See https://www.elastic.co/guide/en/kibana/master/development-plugin-saved-objects.html#_mappings

id before after diff
usage-counters - 2 +2

History

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

@Bamieh Bamieh merged commit 69f570f into elastic:master Apr 14, 2021
kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Apr 14, 2021
@kibanamachine
Copy link
Contributor

💚 Backport successful

Status Branch Result
7.x

This backport PR will be merged automatically after passing CI.

phillipb added a commit to phillipb/kibana that referenced this pull request Apr 14, 2021
…to-metrics-tab

* 'master' of github.com:elastic/kibana: (61 commits)
  [Usage collection] Usage counters (elastic#96696)
  UI actions readme (elastic#96925)
  [TSVB] Enable brush for visualizations created with no index patterns (elastic#96727)
  [Data telemetry] Add Async Search to the tests (elastic#96693)
  added missing optional chain for bracket notation (elastic#96939)
  [Discover][DocViewer] Fix toggle columns from doc viewer table tab (elastic#95748)
  [TSVB] Fix per-request caching of index patterns (elastic#97043)
  [Datatable] Fix filter cell flakiness (elastic#96934)
  Unskip heatmap suite and fixes flakiness (elastic#96941)
  [Fleet] Improve performance of data stream API (elastic#97058)
  [ML] Data Frame Analytics: remove beta badge (elastic#96977)
  [App Search] Migrate expanded rows for meta engines table in Engines Overview (elastic#96251)
  Instances latency distribution chart tooltips and axis fixes (elastic#95577)
  [Monitoring] Using primary average shard size (elastic#96177)
  [Workplace Search] Hide Kibana chrome on 3rd party connector redirects (elastic#97028)
  ## [Security Solution] Fixes `Exit full screen` and `Copy to cliboard` styling issues (elastic#96676)
  Index pattern field editor - Add warning on name or type change (elastic#95528)
  [App Search] Add small engine breadcrumb utility helper (elastic#96917)
  Copy esArchiver commands from ./reassign.ts to fix tests (elastic#97012)
  [Security Solution][Detections] Updates MITRE Tactics, Techniques, and Subtechniques for 7.13 (elastic#97011)
  ...
@Bamieh Bamieh deleted the telemetry/usage_counters branch April 14, 2021 14:02
kibanamachine added a commit that referenced this pull request Apr 14, 2021
Co-authored-by: Alejandro Fernández Haro <[email protected]>

Co-authored-by: Ahmad Bamieh <[email protected]>
Co-authored-by: Alejandro Fernández Haro <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Deprecated - use backport:version if exact versions are needed release_note:skip Skip the PR/issue when compiling release notes v7.13.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Provide a way to gather and store server side telemetry data
6 participants