如何将JS错误从客户端记录到kibana?

Eri*_*rik 27 javascript node.js logstash kibana

我在NodeJS中支持Web应用程序,并logstash/elasticsearch/kibana处理系统日志(access_error.log, messages.log etc).

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

编辑:我必须在此问题中添加其他信息.由于@Jackie Xu为我的问题提供了部分解决方案,我的评论如下:

我最感兴趣的是实现服务器端错误处理.我认为将每个错误写入文件是没有效果的.我正在寻找如何使其更具性能的最佳实践.

我需要处理服务器端的js错误记录比写入文件更有效.您是否可以提供一些方案如何提高服务器端日志记录性能?

met*_*hai 40

当你说客户端时,我假设你指的是日志记录客户端而不是Web客户端.

首先,养成以常见格式记录错误的习惯.Logstash喜欢一致性,因此如果您将文本和JSON放在同一输出日志中,您将遇到问题.提示:登录JSON.它非常棒且非常灵活.

整个过程将如下所示:

  1. 您的应用中出现错误
  2. 将错误记录到文件,套接字或网络上
  3. 告诉logstash如何获取(输入)该错误(即从文件,通过网络监听等)
  4. 告诉logstash将错误发送(输出)到Elasticsearch(可以在同一台机器上运行)

在您的应用中,尝试使用bunyan logger for node.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');
});
Run Code Online (Sandbox Code Playgroud)

然后,您需要配置logstash以读取这些JSON日志文件并发送到Elasticsearch/Kibana.创建一个名为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   
  }

}
Run Code Online (Sandbox Code Playgroud)

然后启动/重启logstash: bin/logstash agent -f myapp.conf web

转到elasticsearch http://your-elasticsearch-host:9292,查看日志.


Aev*_*eus 5

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

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

}
Run Code Online (Sandbox Code Playgroud)

之后,您可以使用 NodeJS 将这些错误消息写入日志。Logstash 可以收集这些,然后您可以使用 Kibana 进行可视化。

请注意,根据 Mozilla window.onerror 似乎并不适用于每个错误。你可能想切换到Sentry 之类的东西(如果你不想付费,可以直接从GitHub获取源码)。

  • 在这种情况下,您应该重新表述您的问题。您当前的问题是关于在 Kibana 中显示客户端错误。至于NodeJS中的文件写入性能,我没有具体说明。我想您可以使用 NodeJS 的 fs.WriteStream 类,这似乎是将数据写入文件的最快(且占用内存最少)的方式。您可以通过使用 child.stdin 并写入用具有更快磁盘 IO 的语言编写的进程来跳过这个瓶颈,但我可能错了,因为我还没有尝试过这样的事情。不过,您会通过新的(相关)问题获得更好的答案! (2认同)

Ald*_*ian 5

如果我理解正确,那么您遇到的问题不在于将日志发送回服务器(或者如果@ Jackie-xu提供了一些提示),而是关于如何最有效地将其发送到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));
Run Code Online (Sandbox Code Playgroud)

这样,您就可以直接从客户端与ElasticSearch服务器进行通信。我无法想象有一种更简单,更快捷的方法(但是请注意,这只是理论,我从没有尝试过,所以现实可能会更加复杂,尤其是如果您想生成日期时间戳等特殊字段;)。在生产环境中,您可能会遇到安全问题,可能是客户端和ES服务器之间的代理服务器,但是原理就在那里。

如果您绝对要使用Logstash,则不必强制使用文件输入。
如果出于协调目的,与每个人都一样,或者为了使用Logstash进行高级Logstash解析配置,则应查看一下基本文件输入的所有替代输入。例如,我曾经亲自使用管道,负责收集日志并将其输出到标准输出的过程。还可以在打开的tcp套接字上进行读取,甚至更多,甚至可以添加自己的tcp套接字。