Add metrics

Summary:
Add some usage and failure rate stats to the PluginInstaller. Small
typo fix and added a helper to the metrics utils to make simple
usage tracking a little more intuitive.

Reviewed By: jknoxville

Differential Revision: D17760511

fbshipit-source-id: 957031d428f3124435925415619b1555a0c2dc2a
This commit is contained in:
Pascal Hartig
2019-10-04 08:25:06 -07:00
committed by Facebook Github Bot
parent a3f7e6aa59
commit ff76b17a5b
2 changed files with 35 additions and 7 deletions

View File

@@ -30,10 +30,12 @@ import path from 'path';
import fs from 'fs-extra'; import fs from 'fs-extra';
import {homedir} from 'os'; import {homedir} from 'os';
import {PluginManager as PM} from 'live-plugin-manager'; import {PluginManager as PM} from 'live-plugin-manager';
import {reportPlatformFailures, reportUsage} from '../utils/metrics';
const PLUGIN_DIR = path.join(homedir(), '.flipper', 'thirdparty'); const PLUGIN_DIR = path.join(homedir(), '.flipper', 'thirdparty');
const ALGOLIA_APPLICATION_ID = 'OFCNCOG2CU'; const ALGOLIA_APPLICATION_ID = 'OFCNCOG2CU';
const ALGOLIA_API_KEY = 'f54e21fa3a2a0160595bb058179bfb1e'; const ALGOLIA_API_KEY = 'f54e21fa3a2a0160595bb058179bfb1e';
const TAG = 'PluginInstaller';
const PluginManager = new PM({ const PluginManager = new PM({
ignoredDependencies: ['flipper', 'react', 'react-dom', '@types/*'], ignoredDependencies: ['flipper', 'react', 'react-dom', '@types/*'],
}); });
@@ -146,6 +148,7 @@ function InstallButton(props: {
type InstallAction = 'Install' | 'Waiting' | 'Remove'; type InstallAction = 'Install' | 'Waiting' | 'Remove';
const onInstall = useCallback(async () => { const onInstall = useCallback(async () => {
reportUsage(`${TAG}:install`, undefined, props.name);
setAction('Waiting'); setAction('Waiting');
await fs.ensureDir(PLUGIN_DIR); await fs.ensureDir(PLUGIN_DIR);
// create empty watchman config (required by metro's file watcher) // create empty watchman config (required by metro's file watcher)
@@ -178,6 +181,7 @@ function InstallButton(props: {
}, [props.name, props.version]); }, [props.name, props.version]);
const onRemove = useCallback(async () => { const onRemove = useCallback(async () => {
reportUsage(`${TAG}:remove`, undefined, props.name);
setAction('Waiting'); setAction('Waiting');
await fs.remove(path.join(PLUGIN_DIR, props.name)); await fs.remove(path.join(PLUGIN_DIR, props.name));
props.onInstall(); props.onInstall();
@@ -195,7 +199,11 @@ function InstallButton(props: {
<TableButton <TableButton
compact compact
type={action === 'Install' ? 'primary' : undefined} type={action === 'Install' ? 'primary' : undefined}
onClick={action === 'Install' ? onInstall : onRemove}> onClick={
action === 'Install'
? () => reportPlatformFailures(onInstall(), `${TAG}:install`)
: () => reportPlatformFailures(onRemove(), `${TAG}:remove`)
}>
{action} {action}
</TableButton> </TableButton>
); );
@@ -216,7 +224,11 @@ function useNPMSearch(
); );
useEffect(() => { useEffect(() => {
getInstalledPlugns().then(setInstalledPlugins); reportUsage(`${TAG}:open`);
reportPlatformFailures(
getInstalledPlugns(),
`${TAG}:getInstalledPlugins`,
).then(setInstalledPlugins);
}, []); }, []);
const onInstall = useCallback(async () => { const onInstall = useCallback(async () => {
@@ -264,11 +276,14 @@ function useNPMSearch(
useEffect(() => { useEffect(() => {
(async () => { (async () => {
const {hits} = await index.search({ const {hits} = await reportPlatformFailures(
index.search({
query, query,
filters: 'keywords:flipper-plugin', filters: 'keywords:flipper-plugin',
hitsPerPage: 20, hitsPerPage: 20,
}); }),
`${TAG}:queryIndex`,
);
setSearchResults(hits.filter(hit => !installedPlugins.has(hit.name))); setSearchResults(hits.filter(hit => !installedPlugins.has(hit.name)));
setQuery(query); setQuery(query);

View File

@@ -108,6 +108,19 @@ export function tryCatchReportPlatformFailures<T>(
} }
} }
/**
* Track usage of a feature.
* @param action Unique name for the action performed. E.g. captureScreenshot
* @param data Optional additional metadata attached to the event.
*/
export function reportUsage(
action: string,
data?: {[key: string]: string},
plugin?: string,
) {
getInstance().track('usage', action, data, plugin);
}
function logPlatformSuccessRate(name: string, result: Result) { function logPlatformSuccessRate(name: string, result: Result) {
if (result.kind === 'success') { if (result.kind === 'success') {
getInstance().track('success-rate', name, {value: 1}); getInstance().track('success-rate', name, {value: 1});