如何将来自客户端的JS错误logging到kibana?

我有Web应用程序支持结束在logstash/elasticsearch/kibanalogstash/elasticsearch/kibana处理系统日志,如(access_error.log, messages.log etc)

现在我需要将所有JavaScript客户端错误logging到kibana中。 做这个的最好方式是什么?

编辑:我必须添加额外的信息,这个问题。 正如@Jackie Xu提供了我的问题的部分解决scheme,并从我的评论如下:

我最感兴趣的是实现服务器端error handling。 我认为这不是有效的写入每个错误的文件。 我正在寻找最佳实践如何使其更具性能。

我需要处理服务器端的js错误logging比写入文件更有效。 你可以提供一些场景,我怎样才能提高服务器端的日志logging性能?

当你说客户端,我假设你是指一个日志客户端,而不是一个Web客户端

首先,把它作为一个习惯来logging你的错误在一个共同的格式。 Logstash喜欢一致性,所以如果将文本和JSON放在同一个输出日志中,就会遇到问题。 提示:loginJSON。 这真棒,令人难以置信的灵活性。

整个过程将如下所示:

  1. 您的应用程序发生错误
  2. 将错误logging到文件,套接字或通过networking
  3. 告诉logstash如何获得(input)该错误(即从文件,networking监听等)
  4. 告诉logstash将错误发送(输出)到Elasticsearch(可以在同一台机器上运行)

在你的应用程序中,尝试使用bunyanlogging器作为节点。 https://github.com/trentm/node-bunyan

节点应用程序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'); }); 

然后,您需要configurationlogstash来读取这些JSON日志文件并发送到Elasticsearch / Kibana。 创build一个名为myapp.conf的文件并尝试以下操作:

logstashconfigurationmyapp.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进行http://your-elasticsearch-host:9292查看日志进入。

您将不得不首先捕获所有客户端错误(并将这些错误发送到您的服务器):

 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获取源代码)。

通过默认的内置文件日志logginglogging错误,可以保留错误,还可以让您的内核为您优化写入。

如果你真的认为速度不够快(你会得到很多错误?),你可以把它们放到redis中。

Logstash有一个redis发布/订阅的input,所以你可以将错误存储在redis中,logstash会把它们拉出来,并将它们存储在你的案例中进行elasticsearchsearch。

我假设logstash / es是在另一台服务器上,否则真的没有必要这样做,es也必须将数据存储在光盘上,而且几乎没有写入日志文件那样高效。

无论你使用什么解决scheme,你都想要存储数据,例如。 写入光盘。 只追加到单个(日志)文件是非常有效的,保存数据时唯一可以处理的方式是将其分割成多个光盘/节点。

如果我理解正确,那么你的问题不在于把日志发送回服务器(或者是@ Jackie-xu提供了一些提示),而是关于如何最有效地发送日志到弹性search。

实际上,经典堆栈Logstash/Elasticsearch/Kibana的绝大多数用户习惯于拥有一个login到文件的应用程序,然后使用Logstash的插件读取文件来parsing该文件并将结果发送到ElasticSearch。 由于@methai给出了一个很好的解释,我不会再这样做了。

但是我想提出的是:

你不是被迫使用Logstash。
实际上,Logstash的主要作用是收集日志,parsing它们以识别其结构和经常性字段,最后以JSON格式输出它们,以便将它们发送到ElasticSearch。 但是由于您已经在客户端操作了JavaScript,所以很容易想象您会直接与Elasticsearch服务器通信。 例如,一旦你捕捉到一个JavaScriptexception,你可以做以下的事情:

 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服务器通信。 我无法想象一个更简单,更快速的方法来做到这一点(但请注意,这只是理论,我从来没有尝试过自己,所以现实可能会更复杂,特别是如果你想生成特殊的领域,如date时间戳)。 在生产环境中,您可能会遇到安全问题,可能是客户端和ES服务器之间的代理服务器,但原则就在那里。

如果您绝对要使用Logstash,则不必强制使用文件input
如果出于协调,与所有人一样的目的,或者使用高级logstashparsingconfiguration,您希望坚持Logstash,则应该查看基本文件input的所有替代input。 例如,我曾经自己使用pipe道,负责收集日志并将其输出到标准输出。 也有可能阅读一个开放的TCP套接字,还有更多,你甚至可以添加自己的。