@qwant/telemetry-react
v0.0.2
Published
Qwant library for collecting telemetry information through react components
Downloads
3
Readme
Logger Documentation
The goal of the logger is to be able to log events happening on the app (click, display, loading...) trough a react app. This library try to solve the headache of building an event with data available at different levels of the application 🧠.
Definitions
- Event - The data representing the user's interaction that will be sent. An event has two parts, a string representing the type of the event (ui, url, display....), and an object transporting additional data (component, context, url, zone...)..
- Client - The browser
- DataHub - External service that will receive the event.
API
The telemetry is exposed with multiple systems.
Components
TelemetryConfiguration
To bootstrap useTelemetry
you need to set the configuration with TelemetryConfiguration
.
const telemetryLogger = (endpoint, data) => {
/* You can use whatever you want here */
navigator.sendBeacon(endpoint, JSON.stringify(data))
}
return (
<TelemetryConfiguration
fetcher={telemetryLogger}
endpoint="https://www.qwant.com/action"
product={{
name: 'front',
module: 'my-product',
version: '0.0.1',
}}
>
{/* Your application */}
</TelemetryConfiguration>
)
TelemetryProvider
The telemetry provider is used to "tag" specific area of the application and allows children to retrieve the context of an event more easily.
// app.jsx
return (
<TelemetryProvider context={TelemetryEnumContexts.HOMEPAGE}>
<Box>
<TelemetryProvider component={TelemetryEnumComponents.SIDEBAR}>
<Sidebar /> {/* // here we will have "context" and "component" set */}
</TelemetryProvider>
</Box>
</TelemetryProvider>
)
// Sidebar
function Sidebar() {
const logClick = useLogCallback('ui', {
component: TelemetryEnumZones.BUTTON,
})
return <button onClick={logClick}>I'm a button</button>
}
The button will automatically send the context and component retrieved from the provider and will call sendEvent('ui', {context: 'homepage', component: 'sidebar', zone: 'button'})
. Multiple providers can be nested to provide information for emitted events.
Hooks
useLogCallback(type: string, data: object): function
Return a memoized function that sends an event.
function MyComponent({ onClick }) {
const loggableClick = useLogCallback(TelemetryEvents.UI, {
zone: TelemetryEnumZones.BLOG,
})
return <button onClick={loggableClick}>Hello</button>
}
useLogCallback(callback: function, type: string, data: object): function
Wrap the callback
and return a function that will send an event after the original callback call.
function MyComponent({ onClick }) {
const loggableClick = useLogCallback(onClick, TelemetryEvents.UI, {
zone: TelemetryEnumZones.BLOG,
})
return <button onClick={loggableClick}>Hello</button>
}
useLogEffect(type: string, data: object, dependencies: array = []): void
Send an event when the dependencies change or when the component is mounted
useTelemetry(): {sendEvent: function}
This hook will retrieve the sendEvent
method from the context. Try to use the other hooks as much as possible before using this one.
function MyComponent({ onClick }) {
const { sendEvent } = useTelemetry()
return <button onClick={() => sendEvent('ui', {})}>Hello</button>
}
HOC
Hooks are a good way to inject the logger faster, but it's not always the best way to handle things. With HOC you can easily decorate external components.
Loggable(component, type: string)
Wraps a component and inject a log
function as a prop that can be used to send events.
function MyComponent({ log }) {
return <button onMouseUp={log({ component: 'button' })}>Click me</button>
}
const MyComponentWithLog = Loggable(MyComponent, 'ui')
Loggable(component, type: string, trigger: string)
Wraps a component and wraps the on{Trigger}
props
// my-components.jsx
function MyComponent({ onClick }) {
return <button onClick={onClick}>Click me</button>
}
export const MyComponentWithLog = Loggable(MyComponent, 'ui', 'click')
// app.jsx
return <MyComponentWithLog onClick={(e) => doSomething()} />
// An event will be emitted after the doSomething call
You can add additional information using props prefixed by "telemetry".
return (
<MyComponentWithLog
telemetryZone={TelemetryEnumZones.LINK}
onClick={(e) => doSomething()}
/>
)
WithTelemetryContext(component, data: object)
Wraps a component with a TelemetryProvider
// The goal is to avoid repeating provider
;<TelemetryProvider component="sidebar">
<Sidebar />
</TelemetryProvider>
// Instead we can export an already contextualized sidebar
const Sidebar = WithTelemetryContext(SidebarPure, { component: 'sidebar' })
// Then you can simply use <Sidebar/>
WithLogEffect(component, eventName: string, data: object, deps = array)
Wrap a component with an useLogEffect
. It is useful when we need to trigger
a display log when component is mounted for example.
import { Multi } from 'qwant-ia'
const LoggableMulti = WithLogEffect(
Multi,
TelemetryEvents.DISPLAY_ELEMENT,
{
ia: TelemetryEnumIA.MAPS_MULTI,
},
['myDeps']
)
function MapsPhoenix() {
/* ... */
if (places.length > 1) {
return <LoggableMulti /* ... */ />
}
}