我正在构建一个日志系统,用来记录分布在多个应用程序节点的Web服务的请求和响应。我考虑使用MongoDB作为存储库,并实时记录日志,或更现实地说,在x个请求后将日志转储到数据库中。该应用程序旨在处理相当高的数据量,并且是用Perl构建的。有没有人做过类似的事情?有什么建议吗?还是说这是不可行的?
我通过Log::Dispatch::MongoDB在几个应用程序中使用它;非常好用!
# Declaration
use Log::Dispatch;
use Log::Dispatch::MongoDB;
use Log::Dispatch::Screen;
use Moose;
has log => (is => 'ro', isa => 'Log::Dispatch', default => sub { Log::Dispatch->new }, lazy => 1)
...
# Configuration
$self->log->add(
Log::Dispatch::Screen->new(
min_level => 'debug',
name => 'screen',
newline => 1,
)
);
$self->log->add(
Log::Dispatch::MongoDB->new(
collection => MongoDB::Connection->new(
host => $self->config->mongodb
)->saveme->log,
min_level => 'debug',
name => 'crawler',
)
);
...
# The logging facility
$self->log->log(
level => 'info',
message => 'Crawler finished',
info => {
origin => $self->origin,
country => $self->country,
counter => $self->counter,
start => $self->start,
finish => time,
}
);
以下是来自固定集合的示例记录:
{
"_id" : ObjectId("50c453421329307e4f000007"),
"info" : {
"country" : "sa",
"finish" : NumberLong(1355043650),
"origin" : "onedayonly_sa",
"counter" : NumberLong(2),
"start" : NumberLong(1355043646)
},
"level" : "info",
"name" : "crawler",
"message" : "Crawler finished"
}
我已经在运行于两个应用服务器的Web应用程序上完成了这项工作。 MongoDB的写入默认情况下是非阻塞的(Java驱动程序只会为您获取请求并立即返回,我认为Perl也是如此,但您最好检查一下),这对于此用例非常完美,因为您不希望用户等待记录日志。
这样做的缺点是,在某些故障场景下,您可能会丢失一些日志(例如,在Mongo接收数据之前,您的应用程序崩溃)。
如果你还没有的话,我推荐你看一下Graylog2,这是一些关于你的应用程序有趣思路的建议。他们非常有效地使用了MongoDB和Elasticsearch的组合。将强大的搜索引擎融入其中可以为您提供一些有趣的查询和分析选项。
供你参考,这里是一个Elasticsearch页面专门用于日志处理工具和技术。
如果您计划在处理之前排队日志条目(我建议这样做),我建议您选择一个可靠的消息队列选项Kestrel。这就是Gaug.es所使用的,我最近一直在测试它。这是一个Java应用程序,非常快速和原子性,并且方便地支持Memcache协议。这是横向扩展的好方法,内存缓存备份到一个日志文件中,以实现速度和耐久性的良好平衡。