Fluentd初探(3)——实战:Python + MongoDB

写在前面

本文主要介绍Fluentd在Python Application中的应用,将Python程序在运行时输出的log输入到Fluentd,并最终持久化到MongoDB中。

把Python程序的log输出到Fluentd中很简单,Fluentd已经为你写好了lib——fluent-logger-python。从Fluentd中把数据存到MongoDB也不是很困难,因为我们安装的是稳定版本的Fluentd——td-agent,其已经自带了把数据从Fluentd输出到MongoDB的输出插件——out_mongo,我们要做的就是简单做一些简单的配置。

在动手操作之前,我们还需要明白一些事情,就是通过Fluentd,把log保存到MongoDB中相比直接在程序中输出到MongoDB,有哪些好处?

一般一个程序会频繁地大量地输出log,如果直接将log写到MongoDB中,可能会引起性能问题的是数据库的锁。虽然MongoDB的锁(更多参见官方文档)比较轻量级,甚至有人提出了叫它“栓”更合适,但是频繁的insert也会引起资源竞争,并排斥其他读操作。而使用Fluentd等日志收集框架,它们会将logs缓存,并异步地以bulk inserts的方式写入MongoDB,比直接写入高效很多,而且对程序的性能影响很低。而且就Fluentd来说,它的数据记录是JSON形式,与MongoDB的数据格式BSON融合搭配非常完美,因此用Fluentd来收集并写入MongoDB是较为理想的解决方案。

架构图如下:

准备工作安装fluent-logger-python

$ sudo pip install fluent-logger

为Fluentd配置输入插件

要求Fluentd的输入插件必须做出如下配置:

<source>  type tcp  port 24224</source>

为Fluentd配置输出插件

一个样例的输出插件配置如下:

<match mongo.*>    # plugin type, must be mongo    type mongo    # mongodb host + port    host 127.0.0.1    port 27017    # mongodb db + collection    database grlog    collection log    # for capped collection    capped    capped_size 1024m    # authentication    user liushuaikobe    password secret    # flush interval    flush_interval 10s</match>

几个点说一下,其他的不言而喻。

capped

即MongoDB固定大小的集合(Capped Collections)。非常适合用来存储log信息。如果你不知道,建议先去学学基础的MongoDB的知识。

flush_interval

这个参数指定了多长时间数据被写入MongoDB一次。默认是60s。支持“s”(seconds),“m”(minutes),“h”(hours) 后缀。

collection

这个参数指定了数据存入MongoDB的哪个集合。这个参数是必须的,除非设置了tag_mapped

tag_mapped告诉Fluentd根据数据记录的tag信息把数据记录放入不同的MongoDB集合。

例如:

<match mongo.*>    ...    # Set 'tag_mapped' if you want to use tag mapped mode.    tag_mapped    # If the tag is "mongo.foo", then the prefix "mongo." is removed.    # The inserted collection name is "foo".    remove_tag_prefix mongo.    ...</match>

更多高级的配置

还有很多更具体的配置,比如buffer相关等,数据写入MongoDB时使用的线程数等,详情查看这里。

重启td-agent

$ sudo service td-agent restart

代码编写

接下来就是实际编写代码了,也非常简单。

from fluent import senderfrom fluent import eventsender.setup('app', host='127.0.0.1', port=24224)event.Event('follow', {    'msg_1': 'msg 1',    'msg_2': 'msg 2'})

上面的代码就将一条数据记录(被称为event)发给了Fluentd,剩下的就是Fluentd根据你的配置把这些信息写入MongoDB了。

当然,在实际的项目中,可以采取一些灵活的手段。比如,可以根据上面所述的tag_mapped将不同LEVEL的log输出到不同的集合中。

附上我的代码,仅供参考,如有错误,恳请指正。

import loggingfrom fluent import senderfrom fluent import eventimport config__author__ = 'liushuai'DEBUG = logging.DEBUGINFO = logging.INFOWARNING = logging.WARNINGERROR = logging.ERRORCRITICAL = logging.CRITICAL_level_tag_name = {    DEBUG: "debug",    INFO: "info",    WARNING: "warning",    ERROR: "error",    CRITICAL: "critical"}sender.setup(config.FLUENTD_TAG, host=config.FLUENTD_HOST, port=config.FLUENTD_PORT)def log(level, msg):    event.Event(_level_tag_name.get(level, "unknown"), {        "msg": msg,        "level": _level_tag_name.get(level, "unknown")    })

单元测试:

from unittest import TestCaseimport log__author__ = 'liushuai'class TestLog(TestCase):    def test_log(self):        msg = "This log is just for testing."        for _ in range(100):            log.log(log.CRITICAL, msg)            log.log(log.ERROR, msg)            log.log(log.WARNING, msg)            log.log(log.INFO, msg)            log.log(log.DEBUG, msg)

可以见到log已经被成功写入了MongoDB(可能会有一些延迟):

后记

以上就是我使用Fluentd + Python + MongoDB进行项目log信息的集中处理的探索全过程,希望对你有帮助。如有错误,恳请留言指正。

写在前面

本文主要介绍Fluentd在Python Application中的应用,将Python程序在运行时输出的log输入到Fluentd,并最终持久化到MongoDB中。

Fluentd初探(3)——实战:Python + MongoDB

相关文章:

你感兴趣的文章:

标签云: