2014-07-01 6 views
17

Ich habe Web-Anwendung unterstützt Ende in NodeJS und logstash/elasticsearch/kibana, um System-Logs wie (access_error.log, messages.log etc) zu behandeln.Wie JS-Fehler von einem Client in Kibana protokolliert werden?

Jetzt muss ich alle JavaScript-Client-Seite Fehler in Kibana auch aufzeichnen. Was ist der beste Weg, dies zu tun?

EDIT: Ich muss zusätzliche Informationen zu dieser Frage hinzufügen. Als @Jackie Xu bieten teilweise Lösung für mein Problem und wie folgt aus meinem Kommentar:

Ich bin am meisten interessiert, serverseitige Fehlerbehandlung zu realisieren. Ich denke, es ist nicht effektiv, jeden Fehler in die Datei zu schreiben. Ich suche nach Best Practices, um mehr Leistung zu erzielen.

Ich muss js Fehler Datensätze auf der Serverseite effektiver als nur in Datei schreiben behandeln. Können Sie einige Szenarien bereitstellen, wie kann ich die serverseitige Protokollierungsleistung erhöhen?

+0

Hey Leute helfen mir. Braucht meine Frage Erklärungen? – Erik

+0

Welche Version von Knoten? Welche Art von App (Express? Andere MVC?) Was versuchen Sie auf der Serverseite mit diesen clientseitigen Fehlern zu erreichen? – methai

+0

Ich benutze die neueste Version von Node JS mit Express js 4.0. Ich muss nur js Fehler in meiner elasticsearch Instanz speichern und in meinem kibana Dashboard sehen. – Erik

Antwort

34

Wenn Sie Client sagen, nehme ich hier an, dass Sie einen Protokollierungsclient meinen und keinen Webclient.

Machen Sie es sich zunächst zur Gewohnheit, Ihre Fehler in einem gemeinsamen Format zu protokollieren. Logstash mag Konsistenz. Wenn Sie also Text und JSON in dasselbe Ausgabeprotokoll einfügen, treten Probleme auf. Tipp: Melden Sie sich bei JSON an. Es ist großartig und unglaublich flexibel.

Der gesamte Prozess weitergehen wird:

  1. Fehler tritt in der App
  2. Log der Fehler in Datei, Steckdose oder über ein Netzwerk
  3. Sagen logstash, wie man (Eingang), dass Fehler (dh aus einer Datei, hören über das Netzwerk, etc.)
  4. Sagen logstash (Ausgang), den Fehler zu Elasticsearch senden (die auf derselben Maschine ausgeführt werden können)

In Ihrer App, versuchen Sie die bunyan Logger für Knoten verwenden. https://github.com/trentm/node-bunyan

Knoten App index.js

var bunyan = require('bunyan'); 
var log = bunyan.createLogger({ 
    name: 'myapp', 
    streams: [{ 
    level: 'info', 
    stream: process.stdout // log INFO and above to stdout 
    }, { 
    level: 'error', 
    path: '/var/log/myapp-error.log' // log ERROR and above to a file 
    }] 
}); 

// Log stuff like this 
log.info({status: 'started'}, 'foo bar message'); 

// Also, in express you can catch all errors like this 
app.use(function(err, req, res, next) { 
    log.error(err); 
    res.send(500, 'An error occurred'); 
}); 

Dann müssen Sie logstash konfigurieren, dass diese JSON-Log-Dateien zu lesen und zu Elasticsearch/Kibana senden. Erstellen Sie eine Datei mit dem Namen myapp.conf und versuchen Sie Folgendes:

logstash Config myapp.conf

# Input can read from many places, but here we're just reading the app error log 
input { 
    file { 
     type => "my-app" 
     path => [ "/var/log/myapp/*.log" ] 
     codec => "json" 
    } 
} 

# Output can go many places, here we send to elasticsearch (pick one below) 
output { 

    elasticsearch { 
    # Do this if elasticsearch is running somewhere else 
    host => "your.elasticsearch.hostname" 
    # Do this if elasticsearch is running on the same machine 
    host => "localhost" 
    # Do this if you want to run an embedded elastic search in logstash 
    embedded => true 
    } 

} 

Dann Start/Neustart logstash als solche: bin/logstash agent -f myapp.conf web

Zum Elasticsearch auf http://your-elasticsearch-host:9292 die Protokolle kommen in.

+0

Danke für die Antwort. Ich werde versuchen, Ihren Ansatz auf meinen Code anzuwenden. Ist es möglich, Fehler zu behandeln, indem Sie nginx verwenden und nur nodejs nicht berühren? – Erik

+0

Ihre Logstash-Conf-Datei kann beliebig viele Dateieingaben enthalten. Sie würden also einfach einen Eingabebereich für die nginx-Fehlerprotokolldateien hinzufügen, z. '' 'Pfad => [" /var/log/nginx/nginx-error.log "]' ''. Wenn Sie nun Web-Client-Fehler über XHR möchten, sollten Sie diese in Ihrer Knoten-App besser protokollieren, da Sie den Fehler wie gewünscht formatieren können. Es kann schwierig sein, nginx mitzuteilen, die Nutzlast eines Clientfehlers zu lesen und diese dynamisch in einer Datei zu protokollieren. Auch warum? Programmiere diese Art von Sachen in deiner App anstatt auf dem Webserver. – methai

+0

Danke für die Hilfe – Erik

3

Sie müssten alle Client-Seite Fehler abzufangen ersten (und diese an den Server senden):

window.onerror = function (message, url, lineNumber) { 

    // Send error to server for storage 
    yourAjaxImplementation('http://domain.com/error-logger/', { 
     lineNumber: lineNumber, 
     message: message, 
     url: url 
    }) 

    // Allow default error handling, set to true to disable 
    return false 

} 

Danach können Sie NodeJS verwenden, um diese Fehlermeldungen in ein Protokoll zu schreiben. Logstash kann diese sammeln und dann können Sie Kibana zur Visualisierung verwenden.

Beachten Sie, dass according to Mozilla window.onerror scheint nicht für jeden Fehler zu funktionieren. Vielleicht möchten Sie zu etwas wie Sentry wechseln (wenn Sie nicht zahlen möchten, können Sie direkt die Quelle von GitHub erhalten).

+0

Danke für die Antwort, aber ich bin am meisten daran interessiert, serverseitige Fehlerbehandlung zu realisieren. Ich denke, es ist nicht effektiv, jeden Fehler in die Datei zu schreiben. Ich suche nach Best Practices, um mehr Leistung zu erzielen. – Erik

+1

In diesem Fall sollten Sie Ihre Frage neu formulieren. Ihre aktuelle Frage betrifft die Anzeige von clientseitigen Fehlern in Kibana. Was die Dateischreibleistung in NodeJS betrifft, habe ich nicht die Einzelheiten. Ich nehme an, Sie könnten die fs.WriteStream-Klasse von NodeJS verwenden, die die schnellste (und am wenigsten speicherintensive) Art zu sein scheint, Daten in eine Datei zu schreiben. Möglicherweise können Sie diesen Engpass überspringen, indem Sie child.stdin verwenden und in einen Prozess schreiben, der in einer Sprache mit schnellerem Datenträger-IO geschrieben ist, aber da könnte ich falsch liegen, da ich so etwas noch nicht probiert habe. Sie erhalten jedoch bessere Antworten mit einer neuen (relevanten) Frage! – Aeveus

+0

Ich habe diesen Beitrag aktualisiert – Erik

1

Das Protokollieren von Fehlern durch die integrierte Standard-Dateiprotokollierung ermöglicht die Beibehaltung Ihrer Fehler und ermöglicht Ihrem Kernel, die Schreibvorgänge für Sie zu optimieren.

Wenn Sie wirklich denken, dass es nicht schnell genug ist (Sie erhalten so viele Fehler?), Könnten Sie sie einfach in redis setzen.

Logstash hat eine Redispub/Sub-Eingabe, so dass Sie die Fehler in redis speichern können und logstash sie herauszieht und in Ihrem Fall in elasticsearch speichert.

Ich nehme an, logstash/es sind auf einem anderen Server, sonst gibt es wirklich keinen Sinn dies zu tun, es muss die Daten auf der Festplatte auch speichern, und es ist nicht annähernd so effizient wie das Schreiben einer Logdatei.

Mit welcher Lösung Sie auch gehen, Sie möchten die Daten speichern, z. Schreiben auf CD. Das Anhängen an eine einzelne (Protokoll-) Datei ist äußerst effizient. Wenn Sie Daten aufbewahren, können Sie nur mehr mit mehreren Disks/Nodes arbeiten.

+0

Danke für die Antwort. Können Sie mir Beispiel geben, wie könnte ich Fehler über Dateien behandeln oder auf entsprechende Tutorials verweisen? – Erik

1

zu sehen, ob ich es richtig verstehe, das Problem, das Sie haben, ist nicht etwa y Senden unsere Protokolle zurück an den Server (oder wenn es @Jackie-xu einige Hinweise zur Verfügung gestellt), sondern darüber, wie sie senden die am effizientesten elastiscsearch.

Eigentlich ist die große Mehrheit der Benutzer des klassischen Stacks Logstash/Elasticsearch/Kibana daran gewöhnt, eine Anwendung zu haben, die sich in einer Datei anmeldet, dann Logstashs Plugin zum Lesen von Dateien verwendet, um diese Datei zu parsen und das Ergebnis an ElasticSearch zu senden. Da @methai eine gute Erklärung darüber gab ich nicht weiter gehen auf diese Weise.

Aber was ich möchte bringen ist, dass:

Sie sind nicht verwendet Logstash gezwungen.
Eigentlich Hauptrolle des Logstash ist die Protokolle zu sammeln, zu analysieren, ihre Struktur und rezidivierendes Feld, zu identifizieren und schließlich gibt sie in einem JSON-Format, so dass sie zu Elasticsearch versandt werden können. Aber da Sie Javascript bereits auf der Client-Seite manipulieren, kann man sich leicht vorstellen, dass Sie direkt mit dem Elasticsearch-Server sprechen würden. Zum Beispiel, wenn Sie eine JavaScript-Ausnahme gefangen haben, könnten Sie das Folowing tun:

var xhr = new XMLHttpRequest(); 
xhr.open("PUT", http://your-elasticsearch-host:9292, true); 
var data = { 
    lineNumber: lineNumber, 
    message: message, 
    url: url 
} 
xhr.send(JSON.stringify(data)); 

Auf diese Weise werden Sie direkt vom Client zum Server Elasticsearch sprechen. Ich kann nicht eine einfachere und schnellere Art und Weise vorstellen, das zu tun (Beachten Sie jedoch, dass dies nur Theorie ist, dass ich mich nie versucht, so Realität komplexer sein könnte, vor allem wenn man wie Datum Zeitstempeln spezielle Felder generiert werden sollen;)). In einem Produktionskontext werden Sie wahrscheinlich Sicherheitsprobleme haben, wahrscheinlich einen Proxy-Server zwischen dem Client und dem ES-Server, aber das Prinzip ist da.

Wenn Sie unbedingt wollen Logstash verwenden Sie
zum Zweck, wie jeder zu harmonisieren, tun das gleiche Wenn nicht gezwungen sind,
eine Datei-Eingabe zu verwenden, oder für fortgeschrittene logstash Parsing confifuration mit Ihnen halten wollen Logstash, sollten Sie einen Blick auf alle alternative inputs auf die grundlegende Dateieingabe. Zum Beispiel habe ich selbst ein Rohr verwendet, mit einem Prozess, der dafür zuständig ist, die Protokolle zu sammeln und diese an die Standardausgabe auszugeben. Es gibt auch die Möglichkeit, auf einem offenen TCP-Sockel zu lesen, und vieles mehr, Sie können sogar Ihre eigenen hinzufügen.