Skip to content

Commit

Permalink
[7.x] Usage collector readme (#82548) (#82637)
Browse files Browse the repository at this point in the history
Updates README with more details on `isReady`
  • Loading branch information
TinaHeiligers committed Nov 4, 2020
1 parent f53ef78 commit 098f870
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
15 changes: 13 additions & 2 deletions src/plugins/usage_collection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ To integrate with the telemetry services for usage collection of your feature, t

## Creating and Registering Usage Collector

All you need to provide is a `type` for organizing your fields, `schema` field to define the expected types of usage fields reported, and a `fetch` method for returning your usage data. Then you need to make the Telemetry service aware of the collector by registering it.
Your usage collector needs to provide
- a `type` for organizing your fields,
- `schema` field to define the expected types of usage fields reported,
- a `fetch` method for returning your usage data, and
- an `isReady` method (that returns true or false) for letting the telemetry service know if it needs to wait for any asynchronous action (initialization of clients or other services) before calling the `fetch` method.

Then you need to make the Telemetry service aware of the collector by registering it.

1. Make sure `usageCollection` is in your optional Plugins:

Expand Down Expand Up @@ -62,6 +68,8 @@ All you need to provide is a `type` for organizing your fields, `schema` field t
total: 'long',
},
},
isReady: () => isCollectorFetchReady, // Method to return `true`/`false` or Promise(`true`/`false`) to confirm if the collector is ready for the `fetch` method to be called.

fetch: async (collectorFetchContext: CollectorFetchContext) => {

// query ES or saved objects and get some data
Expand All @@ -84,6 +92,9 @@ All you need to provide is a `type` for organizing your fields, `schema` field t
Some background:

- `MY_USAGE_TYPE` can be any string. It usually matches the plugin name. As a safety mechanism, we double check there are no duplicates at the moment of registering the collector.

- `isReady` (added in v7.2.0 and v6.8.4) is a way for a usage collector to announce that some async process must finish first before it can return data in the `fetch` method (e.g. a client needs to ne initialized, or the task manager needs to run a task first). If any collector reports that it is not ready when we call its `fetch` method, we reset a flag to try again and, after a set amount of time, collect data from those collectors that are ready and skip any that are not. This means that if a collector returns `true` for `isReady` and it actually isn't ready to return data, there won't be telemetry data from that collector in that telemetry report (usually once per day). You should consider what it means if your collector doesn't return data in the first few documents when Kibana starts or, if we should wait for any other reason (e.g. the task manager needs to run your task first). If you need to tell telemetry collection to wait, you should implement this function with custom logic. If your `fetch` method can run without the need of any previous dependencies, then you can return true for `isReady` as shown in the example below.

- The `fetch` method needs to support multiple contexts in which it is called. For example, when stats are pulled from a Kibana Metricbeat module, the Beat calls Kibana's stats API to invoke usage collection.
In this case, the `fetch` method is called as a result of an HTTP API request and `callCluster` wraps `callWithRequest` or `esClient` wraps `asCurrentUser`, where the request headers are expected to have read privilege on the entire `.kibana' index. The `fetch` method also exposes the saved objects client that will have the correct scope when the collectors' `fetch` method is called.

Expand Down Expand Up @@ -154,7 +165,7 @@ If any of your properties is an array, the schema definition must follow the con
```ts
export const myCollector = makeUsageCollector<Usage>({
type: 'my_working_collector',
isReady: () => true,
isReady: () => true, // `fetch` doesn't require any validation for dependencies to be met
fetch() {
return {
my_greeting: 'hello',
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/usage_collection/server/collector/collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export interface CollectorOptions<T = unknown, U = T> {
type: string;
init?: Function;
/**
* Method to return `true`/`false` to confirm if the collector is ready for the `fetch` method to be called.
* Method to return `true`/`false` or Promise(`true`/`false`) to confirm if the collector is ready for the `fetch` method to be called.
*/
isReady: () => Promise<boolean> | boolean;
/**
Expand Down Expand Up @@ -101,6 +101,7 @@ export class Collector<T = unknown, U = T> {
* @param {Function} options.init (optional) - initialization function
* @param {Function} options.fetch - function to query data
* @param {Function} options.formatForBulkUpload - optional
* @param {Function} options.isReady - method that returns a boolean or Promise of a boolean to indicate the collector is ready to report data
* @param {Function} options.rest - optional other properties
*/
constructor(
Expand Down

0 comments on commit 098f870

Please sign in to comment.