我在NodeJS中使用Web应用程序支持结束,logstash/elasticsearch/kibana
处理系统日志,如(access_error.log, messages.log etc)
。
现在我需要将所有JavaScript客户端错误记录到kibana中。这样做的最佳方式是什么?
编辑:我必须在此问题中添加其他信息。由于@Jackie Xu为我的问题提供了部分解决方案,我的评论如下:
我最感兴趣的是实现服务器端错误处理。我认为将每个错误写入文件是没有效果的。我正在寻找如何提高性能的最佳实践。
我需要处理服务器端的js错误记录比写入文件更有效。您是否可以提供一些方案如何提高服务器端日志记录性能?
答案 0 :(得分:36)
当您说客户端时,我在此假设您指的是日志记录客户端而不是 Web客户端。
首先,养成以常见格式记录错误的习惯。 Logstash喜欢一致性,因此如果您将文本和JSON放在同一输出日志中,您将遇到问题。提示:登录JSON。它非常棒且非常灵活。
整个过程将如下:
在您的应用中,尝试使用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套接字上阅读也是可能的,甚至还可以添加自己的。