web-dev-qa-db-ja.com

クライアントからのJSエラーをkibanaに記録する方法は?

NodeJSにバックエンドのWebアプリケーションがあり、logstash/elasticsearch/kibanaのようなシステムログを処理するには(access_error.log, messages.log etc)

今は、JavaScriptクライアント側のすべてのエラーもkibanaに記録する必要があります。これを行う最良の方法は何ですか?

編集:この質問に追加情報を追加する必要があります。 @Jackie Xuが私の問題の部分的な解決策を提供し、私のコメントから次のようになります:

サーバー側のエラー処理を実現することに最も興味があります。各エラーをファイルに書き込むのは効果的ではないと思います。パフォーマンスを向上させるためのベストプラクティスを探しています。

ファイルに書き込むだけでなく、サーバー側でjsエラーレコードをより効果的に処理する必要があります。サーバー側のログパフォーマンスを向上させる方法をいくつかシナリオを提供できますか?

24
Erik

クライアントと言うとき、ここではweb clientではなくロギングクライアントを意味すると仮定します。

まず、一般的な形式でエラーを記録することを習慣にします。 Logstashは一貫性を好むため、テキストとJSONを同じ出力ログに入れると、問題が発生します。ヒント:JSONにログインします。驚くほど柔軟です。

全体的なプロセスは次のようになります。

  1. アプリでエラーが発生しました
  2. ファイル、ソケット、またはネットワーク経由でエラーを記録します
  3. Logstashにそのエラーを取得(入力)する方法を指示します(ファイルから、ネットワーク経由でリッスンするなど)
  4. エラーをElasticsearch(同じマシンで実行可能)に送信(出力)するようにlogstashに指示します

アプリで、ノードのbunyanロガーを使用してみてください。 https://github.com/trentm/node-bunyan

node 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');
});

次に、これらのJSONログファイルを読み取り、Elasticsearch/Kibanaに送信するようにlogstashを構成する必要があります。 myapp.confというファイルを作成し、次のことを試してください。

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   
  }

}

次に、logstashを次のように開始/再起動します:bin/logstash agent -f myapp.conf web

http://your-elasticsearch-Host:9292のelasticsearchにアクセスして、入ってくるログを確認します。

39
methai

私が正しく理解している場合、あなたが抱えている問題は、サーバーにログを送り返すことではなく(または @ Jackie-x がいくつかのヒントを提供した場合)、むしろそれらをelastiscsearchに送信する方法に関するものです最も効率的。

実際、クラシックスタックのユーザーの大半はLogstash/Elasticsearch/Kibanaは、ファイルにログインするアプリケーションを持つために使用され、Logstashのプラグインを使用してファイルを読み取り、そのファイルを解析して結果をElasticSearchに送信します。 @ methai がそれについて良い説明を与えたので、私はこれ以上これ以上は進めません。

しかし、私が持ちたいのはそれです:

Logstashの使用を強制されることはありません。
実際には、Logstashの主な役割はログを収集し、それらを解析して構造と繰り返しフィールドを特定し、最終的にJSON形式で出力してElasticSearchに送信できるようにすることです。ただし、クライアント側ですでにJavaScriptを操作しているため、Elasticsearchサーバーと直接対話することは容易に想像できます。たとえば、javascript例外をキャッチしたら、次のことができます。

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

これを行うことにより、クライアントからElasticSearchサーバーに直接話します。それを行うためのより簡単で速い方法を想像することはできません(ただし、これは単なる理論であり、私は自分自身を試したことがないため、特に日付のタイムスタンプなどの特別なフィールドを生成したい場合は、現実はより複雑になる可能性があります;))。本番環境では、おそらくセキュリティの問題、おそらくクライアントとESサーバー間のプロキシサーバーがありますが、原則はそこにあります。

Logstashを絶対に使用したい場合、ファイル入力を使用することを強制されません
調和を図り、全員と同じことをするため、または高度なlogstash解析設定を使用するためにLogstashに固執したい場合は、すべての 代替入力 基本的なファイル入力に。たとえば、私は自分でパイプを使用し、ログを収集して標準出力に出力するプロセスを使用していました。また、開いているtcpソケットで読み取る可能性もあります。さらに、独自のソケットを追加することもできます。

4
Aldian

最初にすべてのクライアント側エラーをキャッチする必要があります(そしてこれらをサーバーに送信します)。

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

}

その後、NodeJSを使用してこれらのエラーメッセージをログに書き込むことができます。 Logstashはこれらを収集し、Kibanaを使用して視覚化できます。

Mozillaによる window.onerrorは、すべてのエラーに対して機能するとは限らないことに注意してください。 Sentry のようなものに切り替えたい場合があります(支払いを希望しない場合は、 GitHub から直接ソースを取得できます)。

3
Aeveus

デフォルトの組み込みファイルロギングによるエラーのロギングにより、エラーを保存でき、カーネルが書き込みを最適化することもできます。

本当に十分に速いとは思わない場合(多くのエラーが発生しますか?)、それらをredisに入れることができます。

Logstashにはredis pub/sub入力があるので、エラーをredisに保存でき、logstashはそれらを引き出してElasticsearchのケースに保存します。

私はlogstash/esが別のサーバー上にあると仮定していますが、そうしないと本当に意味がありません。esもディスクにデータを保存する必要があり、ログファイルを書き込むほど効率的ではありません。

どのソリューションを使用する場合でも、データを保存する必要があります。ディスクに書き込みます。単一の(ログ)ファイルへの追加のみが非常に効率的であり、データを保存する場合、より多くのデータを処理できる唯一の方法は、複数のディスク/ノードに分割することです。

1
Paul Scheltema