Sentry-javascript: オフラインレポートの方向性は?

作成日 2014年10月31日  ·  27コメント  ·  ソース: getsentry/sentry-javascript

こんにちは。オフライン機能がデプロイされたWebアプリがあります。アプリケーションの監視に、Sentryを使用すると便利です。 私たちはすでにバックエンドにそれを使用していて、それは素晴らしい働きをします!

残念ながら、これに対するraven jsのサポートは見当たらないので、独自のソリューションを展開することを余儀なくされると思います。 これを確認できますか? 進め方についてのあなたの提案は何ですか? raven jsのロジックを再利用することをお勧めしますか?

最も参考になるコメント

私たちのソリューション:

shouldSendCallbackをRaveninitに渡します

接続がない場合、outlogStorageServiceはイベントのデータを保存します

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();

ログを送信しようとしているキュー

キューはこのコードを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使用については問題ありませんが、レイヴンが未処理の例外に対して提供する優れたハンドラーを維持したいと思います。 レイヴンエラー検出とエラー送信の間にいくつかの中間ロジックを追加する必要があります

ええ、lemmeはこれについて考えます。これを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. それらの方法を約束する(meh)
  4. 失敗時にイベントをトリガーし(どこで?)、イベントデータにそのイベントの再送信を試みるのに十分なコンテキストを提供します

エラーメッセージを後で送信できるように、おそらくオフラインストレージ機能が必要です。 おそらく、ユーザーがアプリを閉じて、後でオンライン中にアプリを再度開いた後でも。 「オフラインファースト」アプローチに似ています。
http://offlinefirst.org/

私は同じ問題に直面しました。 最初は、サービスワーカーを使ってオフラインのグーグルアナリティクスの問題を解決するのと同じように解決したかったのです。 このアプローチは、ここでグーグルによってよく説明されてい

ただし、Cordovaを対象とする場合、ServiceWorkerが利用できない場合があります。
そして、_hacky_ソリューションが必要です。 私はこれを思いついた:

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に同意します。 他の多くのクールな方法でかなり印象的であるため、これがまだレイヴンの一部ではないことに少し驚いていました。 アプリのアーキテクチャによっては、オフラインになった結果であるエラーの割合が重要になる可能性があります。 それらについて報告できることは、多くの実装において非常に重要です。

だから私の投票は、これは焼き付けられて自動的に行われるべきだということです。 歩哨へのメッセージの送信でエラーが発生した場合は、メッセージを保存して、後で再試行する必要があります(タイマー、イベント、または単純にしたい場合は次のメッセージ送信のいずれかで)。

また、「DDN」ラベルとはどういう意味ですか?

他の多くのクールな方法でかなり印象的であるため、これがまだレイヴンの一部ではないことに少し驚いていました。 アプリのアーキテクチャによっては、オフラインになった結果であるエラーの割合が重要になる可能性があります。

完全に公平。 しかし、デフォルトで実行する必要があるかどうかはわかりません。 スクリプトが読み込まれない場合、アプリが何があっても機能しないというシナリオはたくさんあります。 そして、ほとんどのアプリはオフラインでは機能せず、期待もしていません。 それが良い習慣であるかどうかは別のことです。

これが、Ravenユーザーのかなりの部分がそうするためのコードを書いたとしても、デフォルトでAJAXエラーをログに記録しない理由の一種です。 ただし、_必要に応じて_簡単に実行できるようにします。 そして、ここでも同じことをしたいと思います。

また、「DDN」ラベルとはどういう意味ですか?

わからない。 @mattrobenolt?

設計上の決定が必要です。 :)

デフォルトで実行する必要があるかどうかはわかりません。

理にかなっているや。

ただし、必要に応じて、簡単に実行できるようにします。 そして、ここでも同じことをしたいと思います。

したがって、設計上の決定を支援するために、ここにいくつかの考えがあります。

ドキュメントを正しく理解しtransport configオプションを使用すると、基本的に、Sentryがデータをサーバーに送信するパイプラインの最後の部分を制御し、その送信を実行する責任を負うことができます。 その場合、それはオフラインキューをプラグインするのに最適な場所のようです。 データをサーバーに送信する代わりに、バックグラウンドでサーバーにアップロードするキューにデータを送信します。 それは、誰かがそれを実現するために独自のコードを書いている場合です。

同様に、デフォルトのHTTPトランスポートをRavenでロールされた公式のオフライン対応キューに置き換える構成オプション( includeOffline ?)も公開するのは簡単ですか?

  • ブラウザの互換性のために、キューをlocalStorageに保存し、タイムアウト時に接続をチェックするようにします。
  • パフォーマンスと安定性を向上させるには、サービスワーカーを活用してキューを管理し、ページを閉じた後にエラーをアップロードすることもできます。 しかし、この時点でユーティリティライブラリが独自のサービスワーカーをスピンアップするのは少し思いがけないことでしょうか。

この機能は今、どういうわけかレイヴンに組み込まれていますか?

@Freundschaftいいえ、まだです。 私が理解しているように、今のところ、 transportオプションをオーバーライドするか、 shouldSendCallbackを使用して後で送信するためのキューを作成する必要があります。

@cudasteveありがとう!
誰かが実用的なサンプル実装を手に入れましたか? そうでなければ、私はそれを書いてここに投稿しようとします

@Freundschaftこれは非常に役立ちます。 私たちは同じ問題に直面しています

+ +1お願いします

+1

+1

私たちのソリューション:

shouldSendCallbackをRaveninitに渡します

接続がない場合、outlogStorageServiceはイベントのデータを保存します

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();

ログを送信しようとしているキュー

キューはこのコードを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()がオブジェクトとしてどのように構築されているのかさえわかりません。 「newRaven()」はどこにも見当たりません。

これらの関数を呼び出すにはどうすればよいですか?

ネヴァーマインド、問題が起こったとき、 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公開する必要があると思います。 shouldSendCallbackがfalseを返すと、 _sendが終了する場所を正しくピックアップするため、送信を再試行する場合は、呼び出すのが当然の選択です...

しかし、それがペイロードを変更するのは好きではありません。 したがって、これは理想的な方法ではありません。

この機能はまだライブラリに追加されていますか。

私はオフライン対応の機能を持っているので、今日これが必要になりました。 私はindexdbを使用してすべての独自のデータを保存していますが、Sentry用のすぐに使用できるオフライン機能があると便利です。 独自のローカルデータベースを使用してイベントを保存でき、定期的/ネットワーク上の変更により、非常に便利なデータベースを送信してクリアしようとします。

後でオンラインになったときに送信するために例外を保存する場合、例外にタイムスタンプを設定して、歩哨に送信するときに例外が発生しなかったことを示す方法はありますが、過去? 余分に追加することもできると思いますが、実際のタイムスタンプを設定できると便利です。

captureExceptionはそのようなオプションはありません

このページは役に立ちましたか?
0 / 5 - 0 評価