Hallo, wir haben eine Web-App mit Offline-Funktionen bereitgestellt, und es wäre großartig, Sentry für die Anwendungsüberwachung zu verwenden. Wir verwenden es bereits für unser Backend und es funktioniert großartig!
Leider sehe ich dafür keine Unterstützung in raven js, daher denke ich, dass wir gezwungen wären, unsere eigene Lösung einzuführen. Können Sie dies bestätigen? Was wären Ihre Vorschläge für das weitere Vorgehen? Würden Sie empfehlen, zu versuchen, etwas Logik von Raven js wiederzuverwenden?
Können Sie erkennen, ob der Benutzer offline ist?
Wenn ja, wäre es nicht unmöglich, Ereignisse zu sammeln und in eine Warteschlange einzureihen. Wenn der Benutzer wieder online ist, senden Sie ihn erneut über Raven.captureException
.
Ich kann wahrscheinlich helfen, wie das funktionieren würde, oder einen Haken hinzufügen, um dies zu unterstützen.
Super, danke für die Zusammenarbeit. Ich konnte feststellen, dass der Benutzer gerade online war, um die Erreichbarkeit von Sentry zu testen. Dafür könnte ich die Übertragungsfehlerereignisse abhören, aber wie kann ich es dann erneut versuchen?
Über die Verwendung von captureException
, das wäre in Ordnung, aber ich möchte den ausgezeichneten Handler, den raven für unbehandelte Ausnahmen bietet, beibehalten. Ich müsste eine mittlere Logik zwischen der Rabenfehlererkennung und der Fehlerübertragung hinzufügen
Ja, lass mich darüber nachdenken. Ich denke, es gibt eine gute Möglichkeit, dies entweder automatisch in raven-js zu unterstützen oder einen Hook dafür bereitzustellen. Ich denke, das ist gerecht.
Die gleiche Funktionalität suche ich auch. Nach Durchsicht der Dokumente scheint es, dass ein Workaround darin bestehen könnte, shouldSendCallback
, etwa so:
shouldSendCallback: function(data) {
localStorage['queued-errors'] = (localStorage['queued-errors'] || []).push(data);
return false;
}
Und dann auf Netzwerkkonnektivität warten und die Warteschlange mit Raven.captureException
:
window.addEventListener('online', checkAndProcessQueue);
Das ist ein bisschen huckepack, aber ich habe ein ähnliches Problem. Wir können keine Fehler melden, wenn der Client die Verbindung zum Host verliert (obwohl sie nicht unbedingt offline sind). Beim Herumtrollen sehe ich, dass ein ravenFailure
Ereignis im Fenster ausgelöst wird, aber ich kann nicht genügend Daten von diesem Ereignis abrufen, um das zu erreichen, was ich versuche: Wiederholen Sie das Senden des Fehlers bei einem Fehler.
Dafür sehe ich einige mögliche Ansätze:
retry
Option pro Instanz oder pro Nachricht, die angeben kann, wie oft das Senden von Ereignissen wiederholt, wie oft vor dem Aufgeben usw. versucht werden soll.captureException(),
sendMessage()`, etc. Methoden die bei Erfolg/Fehler ausgelöst werdenSie sollten wahrscheinlich einen Offline-Speicher haben, damit die Fehlermeldungen später gesendet werden können. Möglicherweise sogar, nachdem der Benutzer die App geschlossen und später im Online-Modus erneut geöffnet hat. Ähnlich einem "Offline First"-Ansatz:
http://offlinefirst.org/
Ich habe das gleiche Problem gehabt. Zuerst wollte ich es ähnlich lösen, wie ich das Offline-Google-Analytics-Problem mit einem Servicemitarbeiter löse. Der Ansatz wird von Google hier gut erklärt.
Wenn Sie jedoch auf Cordova abzielen, ist Service Worker möglicherweise nicht verfügbar.
Und eine _hacky_ Lösung wird benötigt. Ich habe mir diesen einfallen lassen:
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]);
}
}
// ...
Ich stimme @webberg zu. Ich war eigentlich ein wenig überrascht, dass dies noch nicht Teil von Rabe war, da es auf viele andere coole Arten ziemlich beeindruckend ist. Abhängig von der Architektur einer App kann es möglicherweise einen nicht trivialen Prozentsatz der Fehler geben, die das ERGEBNIS des Offline-Zustands sind. In der Lage zu sein, darüber zu berichten, ist in vielen Implementierungen ziemlich wichtig.
Also meine Stimme ist, dass dies eingebacken und automatisch sein sollte. Wenn beim Senden der Nachricht an den Sentry ein Fehler auftritt, sollte die Nachricht gespeichert und später erneut versucht werden (entweder bei einem Timer, bei einem Ereignis oder sogar nur bei der nächsten Nachrichtenübertragung, wenn Sie es einfach halten möchten).
Und was bedeutet das "DDN"-Label?
Ich war eigentlich ein wenig überrascht, dass dies noch nicht Teil von Rabe war, da es auf viele andere coole Arten ziemlich beeindruckend ist. Abhängig von der Architektur einer App kann es möglicherweise einen nicht trivialen Prozentsatz der Fehler geben, die das ERGEBNIS des Offline-Zustands sind.
Total gerecht. Aber ich bin mir nicht sicher, ob dies standardmäßig erfolgen sollte. Es gibt viele Szenarien, in denen die App auf keinen Fall funktioniert, wenn ein Skript nicht geladen wird. Und ich würde sagen, dass die meisten Apps einfach nicht offline funktionieren und dies auch nicht erwarten. Ob das eine gute Praxis ist oder nicht, ist eine andere Sache.
Aus diesem Grund protokollieren wir standardmäßig keine AJAX-Fehler, obwohl viele Raven-Benutzer Code dafür geschrieben haben. Aber wir werden versuchen, es einfach zu machen, _wenn Sie wollen_. Und das gleiche würde ich hier gerne machen.
Und was bedeutet das "DDN"-Label?
Nicht sicher. @mattrobenolt?
Designentscheidung erforderlich. :)
Ich bin mir nicht sicher, ob dies standardmäßig erfolgen sollte.
Ja das macht Sinn.
Aber wir werden versuchen, es einfach zu machen, wenn Sie möchten. Und das gleiche würde ich hier gerne machen.
Im Interesse, eine Designentscheidung zu treffen, hier einige Gedanken:
Wenn ich die Dokumente richtig verstehe, kann man mit der Konfigurationsoption transport
im Grunde die Kontrolle über den letzten Teil der Pipeline übernehmen, in dem Sentry die Daten an den Server sendet, und für die Durchführung dieser Übertragung verantwortlich sein. In diesem Fall scheint dies der beste Ort zu sein, um eine Offline-Warteschlange einzufügen. Anstatt die Daten an den Server zu senden, senden Sie sie an eine Warteschlange, die im Hintergrund auf den Server hochgeladen wird. Das wäre, wenn jemand seinen eigenen Code schreiben würde, um dies zu ermöglichen.
Wäre es in ähnlicher Weise einfach genug, auch eine Konfigurationsoption ( includeOffline
?) bereitzustellen, die den standardmäßigen HTTP-Transport durch eine offizielle Raven-rolled offline-fähige Warteschlange ersetzen würde?
ist diese funktion nun irgendwie in raven eingebaut worden?
@Freundschaft Nein, noch nicht. Soweit ich es verstanden habe, müssen Sie vorerst die Option transport
überschreiben oder die Option shouldSendCallback
, um eine Warteschlange für das spätere Senden zu erstellen.
@cudasteve danke!
Hat jemand eine funktionierende Beispielimplementierung? wenn nicht versuche ich mal einen zu schreiben und poste ihn hier
@Freundschaft das wäre sehr hilfreich. wir stehen vor dem gleichen problem
++1 bitte
+1
+1
Unsere Lösung:
shouldSendCallback
an Raven-InitWenn keine Verbindung besteht, speichert unser logStorageService die Daten des Ereignisses
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 löst diesen Code alle 25 Sekunden aus und liefert schließlich alle Ereignisse an 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]);
});
}
...
});
});
Einige Beispiele oben zeigten einen Aufruf einer "privaten" Funktion. Ich kann jedoch nicht Raven._sendProcessedPayload
oder Raven._send
anrufen.
Wenn ich mir Ihren Quellcode ansehe, bin ich mir nicht einmal sicher, wie Raven() als Objekt konstruiert wird. Ich sehe nirgendwo "new Raven()".
Wie kann ich diese Funktionen aufrufen?
Egal, das Problem trat nur auf, wenn raven.min.js
und nicht raven.js
passierten, also beantwortet dies diese Frage.
Also habe ich den minimierten Namen für die _sendProcessedPayload
Funktion gesucht und Folgendes ist in meinem Code (vorerst) gelandet:
/**
* 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);
Dies ist alles andere als ideal aufgrund des schrecklichen
Abschließende Anmerkung dazu für heute: Ich denke, Sie sollten _sendProcessedPayload
öffentlich machen. Es fängt genau dort an, wo _send
endet, wenn shouldSendCallback
false zurückgibt.
Allerdings gefällt mir nicht, dass es die Nutzlast verändert. Es ist also nicht die ideale Methode.
Wurde diese Funktion schon zur Bibliothek hinzugefügt.
Ich habe das heute gebraucht, da ich eine Offline-fähige Funktion habe. Ich speichere alle meine eigenen Daten mit indexdb, aber es wäre schön, eine sofort einsatzbereite Offline-Funktionalität für Sentry zu haben. Wenn es seine eigene lokale Datenbank verwenden könnte, um Ereignisse zu speichern und regelmäßig/bei Netzwerkänderungen zu versuchen, die Datenbank zu senden und zu löschen, wäre das sehr nützlich.
Hier angesprochen https://github.com/getsentry/raven-js/pull/1165
Wenn ich Ausnahmen speichere, um sie später zu senden, wenn ich online bin, kann ich dann den Zeitstempel für die Ausnahmen festlegen, um anzuzeigen, dass sie nicht jetzt aufgetreten sind, wenn ich sie an die Wache sende, sondern irgendwann in der Vergangenheit? Ich denke, ich könnte es einfach im Extra hinzufügen, aber es wäre schön, den tatsächlichen Zeitstempel setzen zu können.
Ich sehe keine solche Option in captureException
Hilfreichster Kommentar
Unsere Lösung:
Übergeben Sie
shouldSendCallback
an Raven-InitWenn keine Verbindung besteht, speichert unser logStorageService die Daten des Ereignisses
Warteschlange beim Versuch, Protokolle zu senden
Queue löst diesen Code alle 25 Sekunden aus und liefert schließlich alle Ereignisse an Sentry