0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-17 23:44:39 -05:00

Added Sentry reporting for slow editor saves (#17698)

closes https://github.com/TryGhost/Product/issues/3719

- adds Sentry reporting for slow saves in the editor to help investigate reports of a similar nature
  - uses different messages for lexical vs mobiledoc and successful vs failed saves so we can compare frequency of each in the Sentry UI
  - includes `save_time` tag so we can see a breakdown of timings and adjust the threshold if necessary
  - includes `post_type` tag which will be useful as we introduce further differences between the features and rendering cycle of posts and pages
  - includes `newsletter` and `email_segment` tags to help indicate if slow saves are due to email sending
  - includes `save_revision` tag to help indicate if forced revision saves cause slow saves
  - includes `convert_to_lexical` tag to help indicate if mobiledoc/lexical conversion is causing slow saves
This commit is contained in:
Kevin Ansfield 2023-08-11 16:00:26 +01:00 committed by GitHub
parent 99761242da
commit ff3b936a0a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 0 deletions

View file

@ -15,6 +15,7 @@ import {GENERIC_ERROR_MESSAGE} from '../services/notifications';
import {action, computed} from '@ember/object';
import {alias, mapBy} from '@ember/object/computed';
import {capitalize} from '@ember/string';
import {captureMessage} from '@sentry/ember';
import {dropTask, enqueueTask, restartableTask, task, taskGroup, timeout} from 'ember-concurrency';
import {htmlSafe} from '@ember/template';
import {inject} from 'ghost-admin/decorators/inject';
@ -626,10 +627,36 @@ export default class EditorController extends Controller {
this.post.set('emailOnly', options.emailOnly);
}
const startTime = Date.now();
try {
yield post.save(options);
// log if a save is slow
if (this.config.sentry_dsn && (Date.now() - startTime > 2000)) {
captureMessage('Successful Mobiledoc save took > 2s', (scope) => {
scope.setTag('save_time', Math.ceil((Date.now() - startTime) / 1000));
scope.setTag('post_type', post.isPage ? 'page' : 'post');
scope.setTag('newsletter', options.adapterOptions?.newsletter);
scope.setTag('email_segment', options.adapterOptions?.emailSegment);
scope.setTag('save_revision', options.adapterOptions?.saveRevision);
scope.setTag('convert_to_lexical', options.adapterOptions?.convertToLexical);
});
}
} catch (error) {
this.post.set('emailOnly', previousEmailOnlyValue);
if (this.config.sentry_dsn && (Date.now() - startTime > 2000)) {
captureMessage('Failed Mobiledoc save took > 2s', (scope) => {
scope.setTag('save_time', Math.ceil((Date.now() - startTime) / 1000));
scope.setTag('post_type', post.isPage ? 'page' : 'post');
scope.setTag('save_revision', options.adapterOptions?.saveRevision);
scope.setTag('email_segment', options.adapterOptions?.emailSegment);
scope.setTag('save_revision', options.adapterOptions?.saveRevision);
scope.setTag('convert_to_lexical', options.adapterOptions?.convertToLexical);
});
}
if (isServerUnreachableError(error)) {
const [prevStatus, newStatus] = this.post.changedAttributes().status || [this.post.status, this.post.status];
this._showErrorAlert(prevStatus, newStatus, error);

View file

@ -16,6 +16,7 @@ import {GENERIC_ERROR_MESSAGE} from '../services/notifications';
import {action, computed} from '@ember/object';
import {alias, mapBy} from '@ember/object/computed';
import {capitalize} from '@ember/string';
import {captureMessage} from '@sentry/ember';
import {dropTask, enqueueTask, restartableTask, task, taskGroup, timeout} from 'ember-concurrency';
import {htmlSafe} from '@ember/template';
import {inject} from 'ghost-admin/decorators/inject';
@ -676,10 +677,36 @@ export default class LexicalEditorController extends Controller {
this.post.set('emailOnly', options.emailOnly);
}
const startTime = Date.now();
try {
yield post.save(options);
// log if a save is slow
if (this.config.sentry_dsn && (Date.now() - startTime > 2000)) {
captureMessage('Successful Lexical save took > 2s', (scope) => {
scope.setTag('save_time', Math.ceil((Date.now() - startTime) / 1000));
scope.setTag('post_type', post.isPage ? 'page' : 'post');
scope.setTag('save_revision', options.adapterOptions?.saveRevision);
scope.setTag('email_segment', options.adapterOptions?.emailSegment);
scope.setTag('save_revision', options.adapterOptions?.saveRevision);
scope.setTag('convert_to_lexical', options.adapterOptions?.convertToLexical);
});
}
} catch (error) {
this.post.set('emailOnly', previousEmailOnlyValue);
if (this.config.sentry_dsn && (Date.now() - startTime > 2000)) {
captureMessage('Failed Mobiledoc save took > 2s', (scope) => {
scope.setTag('save_time', Math.ceil((Date.now() - startTime) / 1000));
scope.setTag('post_type', post.isPage ? 'page' : 'post');
scope.setTag('save_revision', options.adapterOptions?.saveRevision);
scope.setTag('email_segment', options.adapterOptions?.emailSegment);
scope.setTag('save_revision', options.adapterOptions?.saveRevision);
scope.setTag('convert_to_lexical', options.adapterOptions?.convertToLexical);
});
}
if (isServerUnreachableError(error)) {
const [prevStatus, newStatus] = this.post.changedAttributes().status || [this.post.status, this.post.status];
this._showErrorAlert(prevStatus, newStatus, error);