Sentry-javascript: Направления для офлайн-отчетности?

Созданный на 31 окт. 2014  ·  27Комментарии  ·  Источник: getsentry/sentry-javascript

Привет, у нас есть развернутое веб-приложение с офлайн-возможностями, и было бы здорово использовать Sentry для мониторинга приложений. Мы уже используем его для нашей серверной части, и он отлично работает!

К сожалению, я не вижу поддержки этого в raven js, поэтому я думаю, что нам придется развернуть собственное решение. Вы можете это подтвердить? Что бы вы посоветовали, как действовать? Вы бы порекомендовали повторно использовать логику из raven js?

Самый полезный комментарий

Наше решение:

Передать shouldSendCallback в Raven init

Если соединения нет, out logStorageService сохранит данные о событии.

var options = {
    ...
    shouldSendCallback: function(data) {
        if (connectionStatus.check() && Raven.isSetup()) {
            return true;
        } else {
            // store log data somewhere
            logStorageService.set(data);
            return false;
        }
    }
    ...
};

Raven.config(SENTRY_KEY, options).install();

Очередь пытается отправить журналы

Queue запускает этот код каждые 25 секунд, в конечном итоге доставляя все события в Sentry.

queue.enqueue(function () {
                    logStorageService
                        .getKeys()
                        .then(function (keys) {
                            if (keys && keys[0]) {
                                logStorageService
                                    .get(keys[0])
                                    .then(function (log) {
                                        Raven.captureMessage('', log);
                                        logStorageService.remove(keys[0]);
                                    });
                            }
                            ...
                        });
                });

Все 27 Комментарий

Можете ли вы определить, находится ли пользователь в автономном режиме?

Если так, было бы невозможно собрать события и поставить их в очередь. Когда пользователь вернется в сеть, снова отправьте его через Raven.captureException .

Я, вероятно, смогу помочь с тем, как это будет работать, или добавлю крючок, чтобы помочь в этом.

Отлично, спасибо за сотрудничество. Я мог обнаружить, что пользователь находится в сети, даже просто проверяя доступность Sentry. Для этого я мог бы прослушать события сбоя передачи, но как тогда повторить попытку?

Что касается использования captureException , это было бы хорошо, но я хотел бы сохранить отличный обработчик, который raven предоставляет для необработанных исключений. Мне нужно было бы добавить некоторую среднюю логику между обнаружением ошибок ворона и передачей ошибок

Да, дай мне подумать об этом. Я думаю, что есть хороший способ, которым мы можем либо просто поддерживать это автоматически в raven-js, либо предоставить для этого ловушку. Я считаю это справедливым.

Я ищу такую ​​же функциональность. После изучения документации кажется, что можно было бы использовать shouldSendCallback , что-то вроде этого:

shouldSendCallback: function(data) {
  localStorage['queued-errors'] = (localStorage['queued-errors'] || []).push(data);
  return false;
}

А затем прослушайте сетевое подключение и обработайте очередь с помощью Raven.captureException :

window.addEventListener('online', checkAndProcessQueue);

Это немного совмещает, но у меня похожая проблема. Мы не можем сообщать об ошибках, когда клиент теряет соединение с хостом (хотя они не обязательно находятся в автономном режиме). Троллируя вокруг, я вижу, что в окне запускается событие ravenFailure , но я не могу получить достаточно данных из этого события, чтобы выполнить то, что я пытаюсь сделать: повторите попытку отправки ошибки в случае сбоя.

Я вижу несколько возможных подходов к этому:

  1. Параметр retry каждого экземпляра или сообщения, который может указывать, как часто следует повторять отправку событий, сколько раз пытаться, прежде чем отказаться, и т. Д.
  2. Обратный вызов / обратный вызов (ы) для методов captureException(), sendMessage () `и т. Д., Которые запускаются / запускаются при успехе / неудаче
  3. Обещание этих методов (м-м)
  4. Запуск событий (где?) При сбое и предоставление достаточного контекста в данных события, чтобы попытаться повторно отправить это событие

Вероятно, у вас должно быть автономное хранилище, чтобы сообщения об ошибках можно было отправлять позже. Возможно, даже после того, как пользователь закроет приложение, а затем снова откроет его, находясь в сети. Подобно подходу «сначала офлайн»:
http://offlinefirst.org/

Я столкнулся с той же проблемой. Сначала я хотел решить это аналогично тому, как я решаю проблему офлайн-аналитики с помощью сервис-воркера . Этот подход хорошо объясняется здесь Google.

Однако при нацеливании на Кордову Service Worker может быть недоступен.
И необходимо "хакерское" решение . Я придумал это:

https://gist.github.com/oliviertassinari/73389727fe58373eef7b63d2d2c5ce5d

import raven from 'raven-js';
import config from 'config';

const SENTRY_DSN = 'https://[email protected]/YYYY';

function sendQueue() {
  const sentryOffline = JSON.parse(window.localStorage.sentryOffline);

  if (sentryOffline.length > 0) {
    raven._send(sentryOffline[0]);
  }
}

// ... 

Я согласен с @webberig. На самом деле я был немного удивлен, что это еще не часть raven, так как это довольно впечатляюще во многих других интересных аспектах. В зависимости от архитектуры приложения потенциально может быть нетривиальный процент ошибок, которые являются РЕЗУЛЬТАТОМ нахождения в автономном режиме. Возможность сообщить об этом очень важна во многих реализациях.

Итак, я голосую за то, чтобы это происходило автоматически. Когда возникает ошибка при отправке сообщения часовой, сообщение следует сохранить и повторить попытку позже (либо по таймеру, либо по событию, либо даже просто при следующей передаче сообщения, если вы хотите, чтобы это было просто).

Кроме того, что означает ярлык "DDN"?

На самом деле я был немного удивлен, что это еще не часть raven, так как это довольно впечатляюще во многих других интересных аспектах. В зависимости от архитектуры приложения потенциально может быть нетривиальный процент ошибок, которые являются РЕЗУЛЬТАТОМ нахождения в автономном режиме.

Совершенно справедливо. Но я не уверен, что это нужно делать по умолчанию. Существует множество сценариев, в которых, если скрипт не загружается, приложение не будет работать, несмотря ни на что. И я бы сказал, что большинство приложений просто не работают в автономном режиме и не ожидают этого. Другое дело, хорошая это практика или нет.

Вот почему мы не регистрируем ошибки AJAX по умолчанию, даже несмотря на то, что значительная часть пользователей Raven написала для этого код. Но мы постараемся упростить это, _ если вы захотите_. И я хотел бы сделать здесь то же самое.

Кроме того, что означает ярлык "DDN"?

Точно сказать не могу. @mattrobenolt?

Требуется дизайнерское решение. :)

Я не уверен, что это нужно делать по умолчанию.

Да, это имеет смысл.

Но мы постараемся упростить это, если хотите. И я хотел бы сделать здесь то же самое.

Итак, чтобы помочь принять дизайнерское решение, вот некоторые мысли:

Если я правильно понимаю документацию , опция transport config позволяет в основном взять под контроль последнюю часть конвейера, где Sentry отправляет данные на сервер, и становится ответственным за выполнение этой передачи. В этом случае это кажется лучшим местом для подключения автономной очереди. Вместо того, чтобы отправлять данные на сервер, отправьте их в очередь, которая загружается на сервер в фоновом режиме. Это было бы, если бы кто-то писал свой собственный код, чтобы это произошло.

В том же духе, будет ли достаточно просто также предоставить параметр конфигурации ( includeOffline ?), Который заменил бы HTTP-транспорт по умолчанию на официальную автономную очередь с поддержкой Raven?

  • Для совместимости с браузером, возможно, сохраните очередь в localStorage и попросите ее проверять соединение по таймауту.
  • Для повышения производительности и стабильности можно использовать сервис-воркеров для управления очередью, чтобы ошибки могли загружаться даже после закрытия страницы. Но разве для библиотеки утилит сейчас немного самонадеянно создавать собственных сервис-воркеров?

эта функциональность теперь как-то встроена в raven?

@Freundschaft Нет, еще нет. Насколько я понимаю, сейчас вам придется переопределить параметр transport или использовать shouldSendCallback для создания очереди для отправки позже.

@cudasteve, спасибо!
у кого-то есть рабочий образец реализации? если нет, я попробую написать и выложить здесь

@Freundschaft, это было бы очень полезно. мы сталкиваемся с той же проблемой

++ 1 пожалуйста

+1

+1

Наше решение:

Передать shouldSendCallback в Raven init

Если соединения нет, out logStorageService сохранит данные о событии.

var options = {
    ...
    shouldSendCallback: function(data) {
        if (connectionStatus.check() && Raven.isSetup()) {
            return true;
        } else {
            // store log data somewhere
            logStorageService.set(data);
            return false;
        }
    }
    ...
};

Raven.config(SENTRY_KEY, options).install();

Очередь пытается отправить журналы

Queue запускает этот код каждые 25 секунд, в конечном итоге доставляя все события в Sentry.

queue.enqueue(function () {
                    logStorageService
                        .getKeys()
                        .then(function (keys) {
                            if (keys && keys[0]) {
                                logStorageService
                                    .get(keys[0])
                                    .then(function (log) {
                                        Raven.captureMessage('', log);
                                        logStorageService.remove(keys[0]);
                                    });
                            }
                            ...
                        });
                });

В некоторых приведенных выше примерах показан вызов «частной» функции. Однако я не могу вызвать Raven._sendProcessedPayload или Raven._send .

Глядя на ваш исходный код, я даже не понимаю, как Raven () создается как объект. Я нигде не вижу "new Raven ()".

Как я могу вызвать эти функции?

Неважно, проблема возникла только тогда, когда raven.min.js а не raven.js так что это отвечает на этот вопрос.

Итак, я выследил минифицированное имя для функции _sendProcessedPayload и вот что я получил в своем коде (на данный момент):

  /**
   * HACK: Using a private function that gets minified!
   * Pinned Raven-js to version 3.8.1.
   */
  Raven._sendProcessedPayload = Raven._sendProcessedPayload || Raven.Y;

  ...

  function processQueue(items) {
    // Stop if we're not online.
    if (!canSend())
      return;
    // Process the given items or get them from the queue.
    items = items || queue.getItems();
    if (!items || items.length < 1)
      return;
    // First in, first out.
    var next = items.shift();
    // Send the next item.
    Raven._sendProcessedPayload(next, function processed(error) {
      // If no errors, save the queue and process more items.
      if (!error) {
        queue.save(items);
        processQueue(items);
      }
    });
  }

  function shouldSend(data) {
    if (canSend())
      return true;
    if (data.extra.retry)
      return false;
    data.extra.retry = true;
    queue.add(data);
    return false;
  }

  ...

  setInterval(processQueue, OFFLINE_QUEUE_TIMEOUT);

Это далеко от идеала из-за ужасного HACK, а также из-за того, что во время обработки этой очереди может быть зафиксировано больше ошибок, поэтому они будут отправлены не по порядку ...

Последнее замечание по этому поводу на сегодня: я думаю, вам следует сделать _sendProcessedPayload общедоступным. Он запускается прямо там, где _send выходит, когда shouldSendCallback возвращает false, поэтому это очевидный выбор для вызова, если вы хотите повторить отправку ...

Однако мне не нравится, что он изменяет полезную нагрузку. Так что это не идеальный метод.

Добавлена ​​ли эта функция в библиотеку?

Я столкнулся с необходимостью в этом сегодня, так как у меня есть функция с поддержкой автономного режима. Я храню все свои данные с помощью indexdb, но было бы неплохо иметь готовую офлайн-функциональность для Sentry. Если бы он мог использовать свою собственную локальную базу данных для хранения событий и периодически / при сетевых изменениях, пытаться отправить и очистить базу данных, что было бы очень полезно.

Адресовано здесь https://github.com/getsentry/raven-js/pull/1165

Если я сохраняю исключения для отправки позже, когда я подключаюсь к сети, могу ли я установить метку времени для исключений, чтобы указать, что они не произошли сейчас, когда я отправляю их на стражу, но в какой-то момент мимо? Думаю, я мог бы просто добавить его дополнительно, но было бы неплохо иметь возможность установить фактическую метку времени.

Я не вижу такой опции в captureException

Была ли эта страница полезной?
0 / 5 - 0 рейтинги