-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[lens] Basic usage telemetry for total visualizations, and by type #47597
Conversation
Pinging @elastic/kibana-app (Team:KibanaApp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @wylieconlon this is a good start.
Can we do the same for the last 30 days? only counting the saved objects that were done in the last 30 days
💔 Build Failed |
@AlonaNadler Yes, I'll be adding that as soon as I understand whether there is some way of doing that automatically. |
💔 Build Failed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM w/ tweaks. This all looks fine to me, except I think we should probably optimize the querying a bit.
import { getVisualizationCounts } from './visualization_counts'; | ||
import { LensUsage } from './types'; | ||
|
||
export function getSavedObjectsClient( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to only be used internally. Maybe don't export it?
return getVisualizationCounts(savedObjectsClient); | ||
} catch (err) { | ||
return { | ||
saved_total: 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the right behavior? It seems like it'd skew our data if errors are happening. Not sure what else we should do, and I know nothing about the usage collector system, so this may be the right thing. It just feels wrong, and makes me doubt our metrics, if this is the recommended approach.
*/ | ||
|
||
export interface LensUsage { | ||
visualization_types_overall: Record<string, number>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason you're using snake_case instead of camelCase? JavaScript is generally camel cased.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the pattern being used in the rest of the metrics we collect
function groupByType(response: SavedObjectsFindResponse) { | ||
const byVisType: Record<string, number> = {}; | ||
|
||
response.saved_objects.forEach(({ attributes }) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: this feels like it should be a reduce, since that's basically what you're doing in the forEach.
return response.saved_objects.reduce((acc, { attributes }) => {
const type = getTypeName(attributes as Document);
byVisType[type] = (byVisType[type] || 0) + 1;
return acc;
}, {} as Record<string, number>);
export async function getVisualizationCounts( | ||
savedObjectsClient: SavedObjectsClient | ||
): Promise<LensUsage> { | ||
const [overall, last30, last90] = await Promise.all([ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're doing three fetches, when you only need one: the first one. You can change your groupByType function to return overall, 30_days, and 90_days. That may be premature optimization, but it seems worth it. To me, telemetry should be very light-weight and have as low an impact on the system as possible, since it is not a primary feature.
I also think we should filter this down to only fetch the subset of fields that we care about, rather than fetching the entire saved object. I think all that we care about is type, visualizationType, and updated_at, right?
💚 Build Succeeded |
💚 Build Succeeded |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM I know next to nothing about painless, so can't speak to the accuracy of it, but it looks right based on a read-through and glancing at the docs.
// without this kind of mapping we would not be able to access `lens.state` in painless | ||
map_script: ` | ||
String visType = doc['lens.visualizationType'].value; | ||
String niceType = visType == 'lnsXY' ? doc['lens.state.visualization.preferredSeriesType'].value : visType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine for now, but I really don't like special casing like this. Eventually, we should solve this more generally so that if other visualizations / Lens plugins have sub-types, we still get metrics about that.
💚 Build Succeeded |
…lastic#47597) * [lens] Basic usage telemetry for total visualizations, and by type * Implement overall, 30 day, 90 day tracking for saved visualizations * Add forgotten file * Implement collection using scripted metrics * Add functional test to ensure painless script is working
This implements new telemetry that tracks saved Lens visualizations broken down by type, and also by three categories: overall, 30 day window, 90 day window.
Because we have the XY visualization type which contains sub-types, this splits that visualization into subtypes. It does not account for each of the layers.
The shape of this telemetry object is: