forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Infrastructure UI] Add TelemetryService documentation (elastic#151641)
## 📓 Summary Closes elastic#150977 This documentation helps to better understand how we can define and trigger custom events in the infra plugin using a centralized service that is injected into the Kibana context for the easiest consumption. It includes documentation for: - Quick overview of the `TelemetryService` - How to define custom events with TelemetryService - Examples of using custom events in the plugin It also includes some minor changes to the definition of the TelemetryService types. --------- Co-authored-by: Marco Antonio Ghiani <[email protected]> Co-authored-by: kibanamachine <[email protected]>
- Loading branch information
1 parent
44241bc
commit ea26816
Showing
8 changed files
with
292 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Telemetry Implementation Guide | `infra` plugin | ||
|
||
Welcome to the documentation on implementing custom Telemetry events using the TelemetryService. Tracking Telemetry events is part of our workflow for better understanding what users like the most and constantly improving the Observability Metrics and Logs. | ||
|
||
Custom events provide a flexible way to track specific user behaviors and application events. By using the [`TelemetryService`](https://github.com/elastic/kibana/tree/main/x-pack/plugins/infra/public/services/telemetry), you can easily create and track custom events, allowing you to gain valuable insights into how your application is being used. | ||
|
||
In this documentation, we will see how to implement custom events and how to trigger them while working with React. | ||
|
||
- [TelemetryService Overview](./telemetry_service_overview.md) | ||
- [Define custom events with TelemetryService](./define_custom_events.md) | ||
- [Examples of using custom events in the plugin](./trigger_custom_events_examples.md) |
116 changes: 116 additions & 0 deletions
116
x-pack/plugins/infra/docs/telemetry/define_custom_events.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
# Define custom events with TelemetryService | ||
|
||
The `TelemetryService` provides an easy way to track custom events that are specific to the `infra` plugin features. | ||
This guide walks through the process of creating and implementing custom events into the TelemetryService, to use them easily while developing the feature with React. This is a step-by-step tutorial with code examples to be able to develop and track custom events that are tailored to your application's unique needs. | ||
|
||
## Step 1: Add event name into event types enum | ||
|
||
The first step is to add the name of the custom event you want to track to the [event types enum](../../public/services/telemetry/types.ts). This is a simple TypeScript enum that contains all the event types that can be tracked by the TelemetryService. For example: | ||
|
||
```ts | ||
export enum InfraTelemetryEventTypes { | ||
SEARCH_SUBMITTED = 'Search Submitted', | ||
} | ||
``` | ||
|
||
In this example, we're adding a new event type called `SEARCH_SUBMITTED` with a value `Search Submitted` that will be used for tracking the event. | ||
|
||
N.B. Each custom event should also be added to the whitelist defined in the [core analytics package](../../../cloud_integrations/cloud_full_story/server/config.ts) to be tracked correctly. | ||
|
||
## Step 2: Update types and define the event schema | ||
|
||
Next, you'll need to update the types file for the TelemetryService to include the new event schema. | ||
This involves: | ||
|
||
- Defining an interface that specifies the properties of the custom event | ||
```ts | ||
export interface SearchSubmittedParams { | ||
query: string; | ||
filters: string[]; | ||
} | ||
``` | ||
|
||
- Add the created params interface to the `InfraTelemetryEventParams` union type: | ||
```ts | ||
export type InfraTelemetryEventParams = SomeEventParams | SearchSubmittedParams; | ||
``` | ||
|
||
- Add into the `ITelemetryClient` interface the signature for the method we'll create into the Telemetry client for triggering the event: | ||
```ts | ||
export interface ITelemetryClient { | ||
//... | ||
reportSearchSubmitted(params: SearchSubmittedParams): void; | ||
} | ||
``` | ||
|
||
- Add into the `InfraTelemetryEvent` union the new event configuration: | ||
```ts | ||
export type InfraTelemetryEvent = | ||
| // Other event config | ||
| { | ||
eventType: InfraTelemetryEventTypes.SEARCH_SUBMITTED; | ||
schema: RootSchema<SearchSubmittedParams>; | ||
}; | ||
``` | ||
|
||
In this example, we're defining a new interface called `SearchSubmittedParams` that specifies the properties of the custom event. We're also adding a new method to the `ITelemetryClient` interface called `reportSearchSubmitted`, which takes the event params interface as its arguments. | ||
|
||
## Step 3: Define the tracking method | ||
|
||
Next, you'll need to define the implementation of the tracking method. | ||
This involves creating a new method in the [TelemetryClient](../../public/services/telemetry/telemetry_client.ts) class that takes the event parameters as its arguments and tracks the event data to the target analytics platform using the core analytics API, which gets injected with the class constructor. For example: | ||
|
||
```ts | ||
export class TelemetryClient implements ITelemetryClient { | ||
constructor(private analytics: AnalyticsServiceSetup) {} | ||
|
||
// Other tracking methods... | ||
|
||
public reportSearchSubmitted = (params: SearchSubmittedParams) => { | ||
this.analytics.reportEvent(InfraTelemetryEventTypes.SEARCH_SUBMITTED, params); | ||
}; | ||
} | ||
``` | ||
|
||
## Step 4: Add method name to telemetry client mock | ||
|
||
If you're using a mock version of the TelemetryClient class for testing purposes, you'll need to update the [mock](../../public/services/telemetry/telemetry_client.mock.ts) to include the new track method. | ||
|
||
```ts | ||
export const createTelemetryClientMock = (): jest.Mocked<ITelemetryClient> => ({ | ||
// ... | ||
reportSearchSubmitted: jest.fn(), | ||
}); | ||
``` | ||
|
||
## Step 5: Test your method implementation | ||
|
||
Finally, you'll want to test your new custom event tracking method to ensure that it's working correctly. You can do this by adding your test to the [existing tests suite](../../public/services/telemetry/telemetry_service.test.ts) for the TelemetryService, calling the tracking method with your new event type and event params, and verifying that the event call is correctly running. For example: | ||
|
||
```ts | ||
describe('#reportSearchSubmitted', () => { | ||
it('should report searches', async () => { | ||
const setupParams = getSetupParams(); | ||
service.setup(setupParams); | ||
const telemetry = service.start(); | ||
|
||
telemetry.reportSearchSubmitted({ | ||
query: 'host.name : "host-0"', | ||
filters: ['test-filter'] | ||
}); | ||
|
||
expect(setupParams.analytics.reportEvent).toHaveBeenCalledTimes(1); | ||
expect(setupParams.analytics.reportEvent).toHaveBeenCalledWith( | ||
InfraTelemetryEventTypes.SEARCH_SUBMITTED, | ||
{ | ||
query: 'host.name : "host-0"', | ||
filters: ['test-filter'] | ||
} | ||
); | ||
}); | ||
}); | ||
``` | ||
|
||
## Usage | ||
|
||
You can check many usage examples for custom events in the [Usage examples guide](./trigger_custom_events_examples.md). |
15 changes: 15 additions & 0 deletions
15
x-pack/plugins/infra/docs/telemetry/telemetry_service_overview.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# TelemetryService Overview | ||
|
||
The TelemetryService is a centralized service that provides a set of tracking functions to be used throughout a plugin. It makes it easy to define and report custom events using the core analytics API behind the scene. | ||
The service is accessed via the `useKibanaContextForPlugin` custom hook, which makes it available anywhere inside the `infra` plugin. | ||
|
||
It consists of 3 main components: | ||
|
||
- **infraTelemetryEvents**: holds the list is exported from the [`telemetry_events.ts`](../../public/services/telemetry/telemetry_events.ts) file and contains the configuration and schema for all the custom events. Any new event configuration needs to be added here. | ||
|
||
- **TelemetryClient**: This class provides the methods needed on the client side to report events using the core analytics API. This allows typing and centralizing the definition of the event. | ||
|
||
- **TelemetryService**: This service class is responsible for setting up and starting the `TelemetryClient`. | ||
It receives the custom events definition from the `infraTelemetryEvents` list, registering all the events in the plugin. Its main role is then to create and inject into the Kibana context a new instance of the `TelemetryClient`. | ||
|
||
Overall, the TelemetryService simplifies the process of defining and reporting custom events in a plugin. By centralizing the tracking functions and providing an easy-to-use API, it helps ensure that important metrics are collected consistently and accurately. |
99 changes: 99 additions & 0 deletions
99
x-pack/plugins/infra/docs/telemetry/trigger_custom_events_examples.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
# Examples of using custom events in the plugin | ||
|
||
The previous examples demonstrate how to use the TelemetryService in different scenarios in a React application. | ||
These examples showcase how you can easily track custom events as users interact with your application. You can use these examples as a starting point and adapt them to your specific use case. | ||
|
||
Any new example is more than welcome and should be added here in case we see more use cases. | ||
|
||
## Trigger an event when the component mounts | ||
|
||
**Use case example**: We want to track when a user preview alerts details and opens a flyout. | ||
|
||
**Implementation**: when the flyout component mounts and is viewed, triggers the event. | ||
|
||
```ts | ||
function AlertsFlyout() { | ||
const { | ||
services: { telemetry }, | ||
} = useKibanaContextForPlugin(); | ||
|
||
useEffect(() => { | ||
telemetry.reportAlertDetailViewed(); | ||
}, []); | ||
|
||
return <div>Alert details</div>; | ||
} | ||
``` | ||
|
||
## Trigger an event when the component unmounts: | ||
|
||
**Use case example**: We want to track when a user closes an alert details flyout. | ||
|
||
**Implementation**: when the flyout component unmounts and is viewed, triggers the event. | ||
|
||
```ts | ||
function AlertsFlyout() { | ||
const { | ||
services: { telemetry }, | ||
} = useKibanaContextForPlugin(); | ||
|
||
useEffect(() => { | ||
return () => { | ||
telemetry.reportAlertDetailClosed(); | ||
}; | ||
}, []); | ||
|
||
return <div>Alert details</div>; | ||
} | ||
``` | ||
|
||
## Trigger an event when the user interacts/clicks with something | ||
|
||
**Use case example**: We want to track hosts' related details when a user clicks on a table entry. | ||
|
||
**Implementation**: update the `handleClick` handler for the table entry to track the event adding properties related to the clicked host. | ||
|
||
```ts | ||
function HostsView() { | ||
const { | ||
services: { telemetry }, | ||
} = useKibanaContextForPlugin(); | ||
|
||
const handleHostClick = ({hostname, cloudProvider}) => { | ||
telemetry.reportHostsEntryClicked({ | ||
hostname, | ||
cloud_provider: cloudProvider | ||
}) | ||
|
||
// Do something more | ||
} | ||
|
||
return ( | ||
<HostList> | ||
<HostEntry onClick={() => handleHostClick({hostname: 'host-0', cloudProvider: 'aws'})}/> | ||
<HostEntry onClick={() => handleHostClick({hostname: 'host-1', cloudProvider: 'aws'})}/> | ||
<HostEntry onClick={() => handleHostClick({hostname: 'host-2', cloudProvider: 'aws'})}/> | ||
</HostList> | ||
) | ||
} | ||
``` | ||
|
||
## Trigger an event as a side effect | ||
|
||
**Use case example**: We want to track how many logs entry a user sees on each update in real-time mode. | ||
|
||
**Implementation**: Each time new logs are shown, track the event as a side effect. | ||
|
||
```ts | ||
function LogsUI() { | ||
const { | ||
services: { telemetry }, | ||
} = useKibanaContextForPlugin(); | ||
|
||
useEffect(() => { | ||
telemetry.reportLogsAddedCount({ count: logsData.length }); | ||
}, [logsData]); | ||
|
||
return <LogStream logs={logsData} />; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.