Skip to content
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

Detect non-responsiveness (ANR) in Electron applications #729

Closed
7 tasks done
cstavitsky opened this issue Aug 31, 2023 · 19 comments
Closed
7 tasks done

Detect non-responsiveness (ANR) in Electron applications #729

cstavitsky opened this issue Aug 31, 2023 · 19 comments
Assignees

Comments

@cstavitsky
Copy link

cstavitsky commented Aug 31, 2023

Problem Statement

Submitting on behalf of a customer:

We have received feedback from our users regarding instances of unresponsiveness in our application. As such, we are keen on leveraging the capabilities of Sentry’s Electron SDK to implement ANR detection.

The Electron SDK currently does not detect non-responsiveness/ANRs.

Prior work:

Solution Brainstorm

We are interested in understanding whether the SDK offers built-in capabilities to detect and handle application unresponsiveness.

An internal chat with Abhi on slack notes that we may be able to do watchdog approach that monitors the main thread but it’ll have to investigated more.

@AbhiPrasad
Copy link
Member

@timfish could we do a quick investigation into how much time/effort this will take?

@timfish
Copy link
Collaborator

timfish commented Aug 31, 2023

Electron has the unresponsive event for renderer processes which fires when the event loop stops in the renderer for a number of seconds.

By default we currently only log breadcrumbs for these events.

Tracking "unresponsiveness" in the Electron main process could be trickier since it controls the entire app. Blocking the main process event loop can disrupt communication between renderers and the GPU process and cause jankiness so notifying of excessive blocking would be very helpful.

@fredyangRC
Copy link

As we briefly discussed in the meeting with your CFO and Anthony, ANR (or app freeze) monitoring is as critical as crash monitoring. I see on your web site that other platforms (mobile, Mac) actually are supported but the Windows. This is an essential function we are looking for.
We missed a major freeze issue in the recent release that caused a lot of customer complaints, and the analysis and troubleshooting was super hard due to lacking of this monitoring ability.

If Sentry cannot support it, then we have to develop this solution in house and that somewhat de-values the Sentry.

@AbhiPrasad
Copy link
Member

We're gonna take a more active look at this, but we need to spend time to make sure the solution has low overhead and is compatible with multiple Node/Electron versions. getsentry/sentry-javascript#9027

our end goal is not just to detect an ANR, but give you a stacktrace of what is causing it - hence the extra effort involved here.

Appreciate your patience while we investigate and experiment.

@AbhiPrasad
Copy link
Member

We've just released ANR tracking support for our Node SDK in v7.72.0. Now we can take a look at porting that solution for Electron!

@timfish
Copy link
Collaborator

timfish commented Oct 2, 2023

The top post now has a task list covering all the PRs adding ANR support to Electron

@AbhiPrasad
Copy link
Member

AbhiPrasad commented Oct 5, 2023

Thanks to the amazing work of @timfish we've shipped initial ANR tracking support for the Electron main process in a beta state in 4.13.0. Docs are coming (being worked on here getsentry/sentry-docs#8146).

@fredyangRC please give it a try - we would love any feedback!

@MercuryLiRC
Copy link

We will try this build and give feedback. Thank you! @AbhiPrasad @timfish

@beyondkmp
Copy link

beyondkmp commented Oct 11, 2023

I have a question. In this #753, there is a mainProcess in options.

import { init, enableAnrDetection } from '@sentry/electron';
 
init({ dsn: "__DSN__" });
 
// Electron v28+ with ESM
await enableAnrDetection({ mainProcess: { captureStackTrace: true }});
runApp();

// with CJS
enableAnrDetection({ mainProcess: { captureStackTrace: true }}).then(() => {
   runApp();
});

But From the index.d.ts in @sentry/electron 4.13.0, there's no mainProcess in options. How do I pass the options in typescript?

/**
 * **Note** This feature is still in beta so there may be breaking changes in future releases.
 *
 * Starts a child process that detects Application Not Responding (ANR) errors.
 *
 * It's important to await on the returned promise before your app code to ensure this code does not run in the ANR
 * child process.
 *
 * ```js
 * import { init, enableAnrDetection } from '@sentry/electron';
 *
 * init({ dsn: "__DSN__" });
 *
 * // with ESM + Electron v28+
 * await enableAnrDetection({ captureStackTrace: true });
 * runApp();
 *
 * // with CJS
 * enableAnrDetection({ captureStackTrace: true }).then(() => {
 *   runApp();
 * });
 * ```
 */
export declare function enableAnrDetection(options: Parameters<typeof enableNodeAnrDetection>[0]): Promise<void>;
//# sourceMappingURL=index.d.ts.map

@beyondkmp
Copy link

Currently, ANRs can only be detected if they are caused by JavaScript code within the main process. If I directly suspend the main process from within the Process Explorer tool, this situation cannot be monitored. Is this the expected behavior?

image

@timfish
Copy link
Collaborator

timfish commented Oct 11, 2023

there's no mainProcess in options

mainProcess is in the typescript types. It looks like the jsdocs are incorrect and need updating.

Currently, ANRs can only be detected if they are caused by JavaScript code

ANR will be detected whenever the main process JavaScript event loop is prevented from running and sending messages to the ANR process.

@beyondkmp
Copy link

In my code, I cannot use mainProcess. There's an error.
image

@timfish
Copy link
Collaborator

timfish commented Oct 11, 2023

Ah you're correct, the types exported from @sentry/electron are not correct. I will fix these in a PR.

Until then, the types exported from @sentry/electron/main are correct.

@MercuryLiRC
Copy link

Hi @timfish
Will Sentry provide a dashboard to monitor the ANR rate? Currently, we are unable to monitor the ANR rate in the dashboard and have to calculate it manually.

@timfish
Copy link
Collaborator

timfish commented Oct 11, 2023

Will Sentry provide a dashboard to monitor the ANR rate?

I will find out what's required to get that working.

Do you have any feedback to share? For example are ANR levels what you would expect? Do you have captureStackTrace enabled and if so are the stack traces useful?

@AbhiPrasad
Copy link
Member

AbhiPrasad commented Oct 12, 2023

As per getsentry/develop#931 we can add the abnormal_mechanism mechanism field to sessions to indicate to Sentry if a session was errored because of ANR. This allows the product to calculate ANR rate.

ref getsentry/sentry-java#2475 and cc @romtsn

Abnormal mechanism can be either one of anr_foreground or `anr_background as per https://github.com/getsentry/sentry/blob/bf6651cb323c6c45eab2b31d4078b21756dbdff6/src/sentry/sentry_metrics/indexer/strings.py#L139-L140

@AbhiPrasad
Copy link
Member

Opened #774 to track ANR rate separately @MercuryLiRC please follow GH issue there for progress on that!

@AbhiPrasad
Copy link
Member

Closing since we've merged in ANR work for the renderer. Now we just need to update docs for that and work toward closing #774.

@timfish
Copy link
Collaborator

timfish commented Oct 17, 2023

It's worth noting that in the next release, enableAnrDetection has been renamed to enableMainProcessAnrDetection so it's clear that this method is only for enabling main process ANR detection.

/**
 * **Note** This feature is still in beta so there may be breaking changes in future releases.
 *
 * Starts a child process that detects Application Not Responding (ANR) errors.
 *
 * It's important to await on the returned promise before your app code to ensure this code does not run in the ANR
 * child process.
 *
 * ```js
 * import { init, enableMainProcessAnrDetection } from '@sentry/electron';
 *
 * init({ dsn: "__DSN__" });
 *
 * // with ESM + Electron v28+
 * await enableMainProcessAnrDetection({ captureStackTrace: true });
 * runApp();
 *
 * // with CJS
 * enableMainProcessAnrDetection({ captureStackTrace: true }).then(() => {
 *   runApp();
 * });
 * ```
 */
export function enableMainProcessAnrDetection(options: Parameters<typeof enableNodeAnrDetection>[0]): Promise<void> {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants