Healthcheck failures analytics
Summary: Send per-healthcheck success/failure event to be able to analyze most common problems. Send event when doctor warning bar shown. Send event when doctor report is opened by user. Send event when user set flag "Do not show warning again" in the doctor report. Reviewed By: passy Differential Revision: D19312127 fbshipit-source-id: 01b648d1154a3aeadc85980190cb9e5e221b572e
This commit is contained in:
committed by
Facebook Github Bot
parent
451db57fa5
commit
2599dffe48
@@ -29,6 +29,8 @@ import {
|
||||
finishHealthchecks,
|
||||
} from '../reducers/healthchecks';
|
||||
|
||||
import {reportUsage} from '../utils/metrics';
|
||||
|
||||
type StateFromProps = {
|
||||
healthcheckResult: HealthcheckResult;
|
||||
} & HealthcheckSettings;
|
||||
@@ -58,6 +60,7 @@ class DoctorBar extends Component<Props, State> {
|
||||
!this.props.healthcheckResult.isAcknowledged
|
||||
) {
|
||||
this.setVisible(true);
|
||||
reportUsage('doctor:warning:shown');
|
||||
}
|
||||
}
|
||||
render() {
|
||||
|
||||
@@ -38,6 +38,7 @@ import runHealthchecks, {
|
||||
HealthcheckEventsHandler,
|
||||
} from '../utils/runHealthchecks';
|
||||
import {shell} from 'electron';
|
||||
import {reportUsage} from '../utils/metrics';
|
||||
|
||||
type StateFromProps = {
|
||||
healthcheckReport: HealthcheckReport;
|
||||
@@ -234,6 +235,10 @@ class DoctorSheet extends Component<Props, State> {
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
reportUsage('doctor:report:opened');
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(props: Props, state: State): State | null {
|
||||
if (
|
||||
!state.acknowledgeCheckboxVisible &&
|
||||
@@ -264,8 +269,16 @@ class DoctorSheet extends Component<Props, State> {
|
||||
|
||||
componentWillUnmount(): void {
|
||||
if (this.state.acknowledgeOnClose) {
|
||||
if (hasNewProblems(this.props.healthcheckReport.result)) {
|
||||
reportUsage('doctor:report:closed:newProblems:acknowledged');
|
||||
}
|
||||
reportUsage('doctor:report:closed:acknowleged');
|
||||
this.props.acknowledgeProblems();
|
||||
} else {
|
||||
if (hasNewProblems(this.props.healthcheckReport.result)) {
|
||||
reportUsage('doctor:report:closed:newProblems:notAcknowledged');
|
||||
}
|
||||
reportUsage('doctor:report:closed:notAcknowledged');
|
||||
this.props.resetAcknowledgedProblems();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ export function reportUsage(
|
||||
getInstance().track('usage', action, data, plugin);
|
||||
}
|
||||
|
||||
function logPlatformSuccessRate(name: string, result: Result) {
|
||||
export function logPlatformSuccessRate(name: string, result: Result) {
|
||||
if (result.kind === 'success') {
|
||||
getInstance().track('success-rate', name, {value: 1});
|
||||
} else if (result.kind === 'cancelled') {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
import {HealthcheckResult} from '../reducers/healthchecks';
|
||||
import {getHealthchecks, getEnvInfo, Healthchecks} from 'flipper-doctor';
|
||||
import {logPlatformSuccessRate, reportPlatformFailures} from '../utils/metrics';
|
||||
|
||||
let healthcheckIsRunning: boolean;
|
||||
let runningHealthcheck: Promise<void>;
|
||||
@@ -41,12 +42,26 @@ async function launchHealthchecks(options: HealthcheckOptions): Promise<void> {
|
||||
}
|
||||
options.startHealthchecks(healthchecks);
|
||||
const environmentInfo = await getEnvInfo();
|
||||
let hasProblems = false;
|
||||
for (const [categoryKey, category] of Object.entries(healthchecks)) {
|
||||
if (category.isSkipped) {
|
||||
continue;
|
||||
}
|
||||
for (const h of category.healthchecks) {
|
||||
const checkResult = await h.run(environmentInfo);
|
||||
const metricName = `doctor:${h.key.replace('.', ':')}.healthcheck`; // e.g. "doctor:ios:xcode-select.healthcheck"
|
||||
if (checkResult.hasProblem) {
|
||||
hasProblems = true;
|
||||
logPlatformSuccessRate(metricName, {
|
||||
kind: 'failure',
|
||||
supportedOperation: true,
|
||||
error: null,
|
||||
});
|
||||
} else {
|
||||
logPlatformSuccessRate(metricName, {
|
||||
kind: 'success',
|
||||
});
|
||||
}
|
||||
const result: HealthcheckResult =
|
||||
checkResult.hasProblem && h.isRequired
|
||||
? {
|
||||
@@ -63,6 +78,17 @@ async function launchHealthchecks(options: HealthcheckOptions): Promise<void> {
|
||||
}
|
||||
}
|
||||
options.finishHealthchecks();
|
||||
if (hasProblems) {
|
||||
logPlatformSuccessRate('doctor.healthcheck', {
|
||||
kind: 'failure',
|
||||
supportedOperation: true,
|
||||
error: null,
|
||||
});
|
||||
} else {
|
||||
logPlatformSuccessRate('doctor.healthcheck', {
|
||||
kind: 'success',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default async function runHealthchecks(
|
||||
@@ -71,6 +97,9 @@ export default async function runHealthchecks(
|
||||
if (healthcheckIsRunning) {
|
||||
return runningHealthcheck;
|
||||
}
|
||||
runningHealthcheck = launchHealthchecks(options);
|
||||
runningHealthcheck = reportPlatformFailures(
|
||||
launchHealthchecks(options),
|
||||
'doctor:runHealthchecks',
|
||||
);
|
||||
return runningHealthcheck;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user