Skip to content

Commit

Permalink
updates usage_collection README with more details about isReady
Browse files Browse the repository at this point in the history
  • Loading branch information
TinaHeiligers committed Nov 3, 2020
1 parent b945ad0 commit ac46d8b
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 5 deletions.
15 changes: 10 additions & 5 deletions src/plugins/usage_collection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ 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.
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,7 +67,7 @@ All you need to provide is a `type` for organizing your fields, `schema` field t
total: 'long',
},
},
isReady: () => isCollectorFetchReady, // method to return true/false to confirm if the collector is ready for the fetch method to be called.
isReady: () => isCollectorFetchReady, // Method to return `true`/`false` to confirm if the collector is ready for the `fetch` method to be called.

fetch: async (collectorFetchContext: CollectorFetchContext) => {

Expand All @@ -86,9 +91,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 will return data synchronously. If any collector is not ready, we try fetching again, up to a set amount of time. Once the allocated time interval is up, we collect data from those collectors that are ready and skip any that are not. What this means is that if a collector returns `true` for `isReady` and it actually isn't ready to return data, there won't be telemetry data for that user for the day. Every usage collector owner needs to really think about what it would mean for them if they missed the first few documents when Kibana starts and should implement this function with custom logic.

(e.g. the task manager needs to run a task first). If any collector reports that it is not ready when we try and collect data, we reset a flag to try again up to a specified interval
- `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 will return data synchronously (e.g. 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 for the 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 will always return data synchronously or you're intentionally catching errors in your `fetch` method, 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 @@ -159,7 +164,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: () => isFetchReadyToReturnData(),
isReady: () => true, // `fetch` doesn't call async methods
fetch() {
return {
my_greeting: 'hello',
Expand Down
1 change: 1 addition & 0 deletions src/plugins/usage_collection/server/collector/collector.ts
Original file line number Diff line number Diff line change
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 {boolean} options.isReady - boolean to indicate collector is ready to report data
* @param {Function} options.rest - optional other properties
*/
constructor(
Expand Down

0 comments on commit ac46d8b

Please sign in to comment.