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

时间:2014-07-01 03:50:22

标签: javascript node.js logstash kibana

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

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

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

  

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

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

4 个答案:

答案 0 :(得分:36)

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

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

整个过程将如下:

  1. 您的应用中出现错误
  2. 将错误记录到文件,套接字或通过网络
  3. 告诉logstash如何获取(输入)该错误(即从文件,通过网络收听等)
  4. 告诉logstash将错误发送(输出)到Elasticsearch(可以在同一台机器上运行)
  5. 在您的应用中,尝试使用bunyan logger for node。 https://github.com/trentm/node-bunyan

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

    然后,您需要配置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   
      }
    
    }
    

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

    转到http://your-elasticsearch-host:9292上的elasticsearch,查看日志。

答案 1 :(得分:3)

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

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进行可视化。

请注意,according to Mozilla window.onerror似乎不适用于每个错误。您可能希望切换到Sentry之类的内容(如果您不想付费,可以直接从GitHub获取来源。)

答案 2 :(得分:1)

通过默认的内置文件日志记录记录错误可以保留错误,并且还允许内核为您优化写入。

如果你真的认为它不够快(你得到那么多错误?)你可以把它们放到redis中。

Logstash有一个redis pub / sub输入,因此您可以将错误存储在redis中,logstash会将它们拉出来并将它们存储在elasticsearch中。

我假设logstash / es在另一台服务器上,否则实际上没有必要这样做,es也必须将数据存储在光盘上,并且它的效率不如编写日志文件。

无论您采用何种解决方案,您都希望存储数据,例如:把它写到光盘上。仅附加到单个(日志)文件是非常有效的,并且在保留数据时,您可以处理更多的唯一方法是在多个光盘/节点上对其进行分片。

答案 3 :(得分:1)

如果我理解正确,您遇到的问题不是将日志发送回服务器(或者如果@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));

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

如果您绝对想使用Logstash,则不必使用文件输入
如果为了协调,为每个人做同样的事情,或者为了使用高级logstash解析配置,你想坚持使用Logstash,你应该看一下基本文件输入的所有alternative inputs。例如,我过去常常使用管道,负责收集日志并将其输出到标准输出。在开放的tcp套接字上阅读也是可能的,甚至还可以添加自己的。