From 77811c66d2dbb4c51a43437ca88b58d72168040b Mon Sep 17 00:00:00 2001 From: John Knox Date: Thu, 31 Jan 2019 03:17:13 -0800 Subject: [PATCH] Add reportPluginFailures in client.call method Summary: Adds an optional "plugin" field to the tracked metrics. The idea is to be able to see failures in plugins. Added it around all desktop -> sdk "call"s, so it won't require any effort from developers but we'll get lots of immediate data. E.g. How often layout -> getNodes fails. I think we can go modify the existing pipeline to take both platform and plugin data so we can get session roll-ups too. Corresponding change to the puma app: D13882629, adds a plugin field to all tables so we can filter by plugin, or null for platform failures. I'm thinking it will be worthwhile to expose some method to plugin developers, that lets them explicitly track failures. It would be better if it encapsulated their plugin id etc, so they just need to say what failed. But that can be done any time, I don't have any particular use cases in mind yet. Reviewed By: passy Differential Revision: D13878379 fbshipit-source-id: 2e2ef6b98f763e6edcfe937741d6988dae4b92d1 --- src/Client.js | 7 ++++++- src/fb-stubs/Logger.js | 2 +- src/utils/metrics.js | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/Client.js b/src/Client.js index 5d5a067c6..2aea2afb6 100644 --- a/src/Client.js +++ b/src/Client.js @@ -16,6 +16,7 @@ import {setPluginState} from './reducers/pluginStates.js'; import {ReactiveSocket, PartialResponder} from 'rsocket-core'; // $FlowFixMe perf_hooks is a new API in node import {performance} from 'perf_hooks'; +import {reportPluginFailures} from './utils/metrics'; const EventEmitter = (require('events'): any); const invariant = require('invariant'); @@ -368,7 +369,11 @@ export default class Client extends EventEmitter { } call(api: string, method: string, params?: Object): Promise { - return this.rawCall('execute', {api, method, params}); + return reportPluginFailures( + this.rawCall('execute', {api, method, params}), + `Call-${method}`, + api, + ); } send(api: string, method: string, params?: Object): void { diff --git a/src/fb-stubs/Logger.js b/src/fb-stubs/Logger.js index b57deedf7..b8d00a431 100644 --- a/src/fb-stubs/Logger.js +++ b/src/fb-stubs/Logger.js @@ -18,7 +18,7 @@ export default class LogManager { scribeLogger: ScribeLogger; - track(type: TrackType, event: string, data: ?any) {} + track(type: TrackType, event: string, data: ?any, plugin?: string) {} trackTimeSince(mark: string, eventName: ?string) {} diff --git a/src/utils/metrics.js b/src/utils/metrics.js index 99bde8c38..c6a7493e2 100644 --- a/src/utils/metrics.js +++ b/src/utils/metrics.js @@ -11,6 +11,8 @@ import {getInstance} from '../fb-stubs/Logger'; * Wraps a Promise, preserving it's functionality but logging the success or failure state of it, with a given name, based on whether it's fulfilled or rejected. + + Use this variant to report failures in core platform (Flipper) code. */ export function reportPlatformFailures( promise: Promise<*>, @@ -27,3 +29,27 @@ export function reportPlatformFailures( }, ); } + +/* + * Wraps a Promise, preserving it's functionality but logging the success or + failure state of it, with a given name, based on whether it's fulfilled or + rejected. + + Use this variant to report failures in plugin code. + */ +export function reportPluginFailures( + promise: Promise<*>, + name: string, + plugin: string, +): Promise<*> { + return promise.then( + fulfilledValue => { + getInstance().track('success-rate', name, 1, plugin); + return fulfilledValue; + }, + rejectionReason => { + getInstance().track('success-rate', name, 0, plugin); + return Promise.reject(rejectionReason); + }, + ); +}