关于fluentd:轻松上手Fluentd结合-Rainbond-插件市场日志收集更快捷

以往有篇文章介绍 EFK(Kibana + ElasticSearch + Filebeat)的插件日志收集。Filebeat 插件用于转发和集中日志数据,并将它们转发到 Elasticsearch 或 Logstash 以进行索引,但 Filebeat 作为 Elastic 的一员,只能在 Elastic 整个体系中应用。 FluentdFluentd是一个开源的,分布式日志采集零碎,能够从不同的服务,数据源采集日志,对日志进行过滤加工,分发给多种存储和解决零碎。反对各种插件,数据缓存机制,且自身所需的资源很少,内置可靠性,联合其余服务,能够造成高效直观的日志收集平台。 本文介绍在 Rainbond 中应用 Fluentd 插件,收集业务日志,输入到多个不同的服务。 一、整合架构在收集组件日志时,只需在组件中开明 Fluentd 插件,本文将演示以下两种形式: Kibana + ElasticSearch + FluentdMinio + Fluentd咱们将 Fluentd 制作成 Rainbond 的 个别类型插件 ,在利用启动之后,插件也随之启动并主动收集日志输入到多个服务源,整个过程对利用容器无侵入,且拓展性强。 二、插件原理剖析Rainbond V5.7.0 版本中新增了:从开源利用商店装置插件,本文中的插件已公布到开源利用商店,当咱们应用时一键装置即可,依据需要批改配置文件。 Rainbond 插件体系是绝对于 Rainbond 利用模型的一部分,插件次要用来实现利用容器扩大运维能力。因为运维工具的实现有较大的共性,因而插件自身能够被复用。插件必须绑定到利用容器时才具备运行时状态,用以实现一种运维能力,比方性能剖析插件、网络治理插件、初始化类型插件。 在制作 Fluentd 插件的过程中,应用到了 个别类型插件,能够了解为一个POD启动两个 Container,Kubernetes原生反对一个POD中启动多个 Container,但配置起来绝对简单,在 Rainbond 中通过插件实现使用户操作更加简略。 三、EFK 日志收集实际Fluentd-ElasticSearch7 输入插件将日志记录写入 Elasticsearch。默认状况下,它应用批量 API创立记录,该 API 在单个 API 调用中执行多个索引操作。这缩小了开销并能够大大提高索引速度。 3.1 操作步骤利用 (Kibana + ElasticSearch)和插件(Fluentd)都能够通过开源利用商店一键部署。 ...

June 22, 2022 · 2 min · jiezi

恭喜 Fluentd 从 CNCF 毕业

今年新闻不断,多数早期进入 CNCF 的项目都相继宣布毕业。CNCF(云原生计算基金会)在美国时间 2019 年 4 月 11 日宣布 fluentd 今天正式毕业了。这是 CNCF 中毕业的第 6 个项目,之前已经毕业的项目为 Kubernetes、Prometheus、Envoy 、CoreDNS 和 containerd 。fluentd 自 2011 年由 Treasure Data 公司的联合创始人 Sadayuki “Sada” Furuhashi 创建,作为构建统一记录层的开源数据收集器,统一记录层统一收集采集和消费,以便更好的使用和理解数据。在 2016 年 11 月,fluentd 也是第 6 个成为 CNCF 托管项目的。fluentd 可以从多种数据源采集事件,并将它写入文件, RDBMS, NoSQL, IaaS, SaaS, Hadoop等等各类的目标地址。截至目前,fluentd 在 GitHub 上有 7629 个 star ,895 个 fork,以及 166 位贡献者,超过 4k+ commit 。做日志相关的小伙伴基本都玩过 ELK ,我们都知道在大规模使用 Logstash 时的痛苦(还记得被 Logstash 配置文件支配的恐惧吗? 2333) 而 fluentd 的事件路由是通过 tag 来做,相比 Logstash 使用管道将所有数据路由到单个流里再通过配置将它发送到对应的目标而言这将大大简化配置的复杂度。(是的,这里是吐槽)再一个,便是需要考虑部署和插件生态,首先来说部署:fluentd 使用 C + Ruby 编写(Ruby 写起来蛮舒服的,早先写过一段时间),只要有 Ruby 的环境,可以很方便的进行部署。而大多数的 Linux 发行版是默认带着 Ruby 环境的,这也非常方便。Logstash 使用 JRuby 编写(JRuby 就是使用 Java 实现的 Ruby 解释器),部署时需要有 JDK 和 JRuby 的环境。这里只做陈述,不再展开。回到插件生态上:两者都有丰富的插件,并且编写插件也很简单。不过插件这种东西,按需使用,日常需要的基本都能找的到。唯一需要注意的就是选择插件时,需要仔细甄别。“Fluentd has earned its place as the industry standard for log collection and shipping, and I am excited to see it as a graduated CNCF project,” said Gabe Monroy, Lead Program Manager for Containers, Microsoft Azure. “At Microsoft, we are proud to use Fluentd to power our cloud native logging subsystems and we look forward to working with the growing the open source community around Fluentd.”引用一段话,fluentd 是否成为整个日志收集的行业标准,这个我不确定, 但在它托管至 CNCF 后,在云原生领域它确实发展迅速,多数公司都会采用 EFK 的方式进行云原生时代下的日志方案。附一张 fluentd 的图,有空会写下 fluentd 的使用姿势 (flag++)再次恭喜 fluentd 毕业。可以通过下面二维码订阅我的文章公众号【MoeLove】 ...

April 12, 2019 · 1 min · jiezi

使用Fluentd收集Docker容器日志

本文介绍使用Fluentd收集standalone容器日志的方法。Docker提供了很多logging driver,默认情况下使用的json-file,它会把容器打到stdout/stderr的日志收集起来存到json文件中,docker logs所看到的日志就是来自于这些json文件。当有多个docker host的时候你会希望能够把日志汇集起来,集中存放到一处,本文讲的是如何通过fluentd logging driver配合fluentd来达成这一目标。目标:将standalone容器打到stdout/stderror的日志收集起来收集的日志根据容器名分开存储日志文件根据每天滚动第一步:配置Fluentd实例首先是配置文件fluent.conf:<source> @type forward</source><match *> @type file path /fluentd/log/${tag}/${tag} append true <format> @type single_value message_key log </format> <buffer tag,time> @type file timekey 1d timekey_wait 10m flush_mode interval flush_interval 30s </buffer></match>新建一个目录比如/home/ubuntu/container-logs,并赋予权限chmod 777 /home/ubuntu/container-logs。然后启动Fluentd实例,这里使用的Docker方式:docker run -it \ -d \ -p 24224:24224 \ -v /path/to/conf/fluent.conf:/fluentd/etc/fluent.conf \ -v /home/ubuntu/container-logs:/fluentd/log fluent/fluentd:v1.3第二步:指定容器的logging driver在启动容器的时候执行使用fluentd作为logging driver:docker run -d \ … –log-driver=fluentd \ –log-opt fluentd-address=<fluentdhost>:24224 \ –log-opt mode=non-blocking \ –log-opt tag={{.Name}} \ <image>第三步:观察日志到/home/ubuntu/container-logs目录下能够看到类似这样的目录结构:.└── <container-name> └── <container-name>.20190123.log参考文档Configure logging driversCustomize log driver outputUse Fluentd logging driverDocker CLI - runFluentdFluentd - out_fileFluentd - formatter_single_valueFluentd - buf_fileFluentd - buffer ...

January 24, 2019 · 1 min · jiezi

k8s与log--利用lua为fluent bit添加一个filter

前言之前我们介绍过fluent bit这个日志收集神器。最近我们遇到奇葩的需求,不得不利用lua编写fluent bit的filter,来满足需求。首先介绍一下需求:非容器的日志团队使用filebeat, 其配置文件部分如下:processors:- dissect: tokenizer: “/data/logs/%{appname}/%{filename}.log” field: “source” target_prefix: ““即需要从日志record的source filed 提取appname和filename两个filed。fluent bit 并没有如此的插件,所以不得不自己实现。实现lua编写filter规范官方给出的示例如下:function cb_print(tag, timestamp, record) return code, timestamp, recordendFunction 输入参数Function ArgumentsnamedescriptiontagName of the tag associated with the incoming record.timestampUnix timestamp with nanoseconds associated with the incoming record. The original format is a double (seconds.nanoseconds)recordLua table with the record contentReturn ValuesEach callback must return three values:namedata typedescriptioncodeintegerThe code return value represents the result and further action that may follows. If code equals -1, means that filter_lua must drop the record. If code equals 0 the record will not be modified, otherwise if code equals 1, means the original timestamp or record have been modified so it must be replaced by the returned values from timestamp (second return value) and record (third return value).timestampdoubleIf code equals 1, the original record timestamp will be replaced with this new value.recordtableif code equals 1, the original record information will be replaced with this new value. Note that the format of this value must be a valid Lua table.理解上面的规范可以结合下面的写法。注意返回值的code。代码实现编写实现类似功能的lua文件,如下:function dissect(tag, timestamp, record) source = record[“source”] if (source == nil) then return 0, 0, 0 else new_record = record local result = { } local from = 1 local delim_from, delim_to = string.find( source, “/”, from ) while delim_from do table.insert( result, string.sub( source, from , delim_from-1 ) ) from = delim_to + 1 delim_from, delim_to = string.find( source, “/”, from ) end table.insert( result, string.sub( source, from ) ) new_record[“appname”] = result[7] new_record[“filename”] = string.sub( result[8], 1, -5 ) return 1, timestamp, new_record end end备注:在我们k8s环境下,业务日志挂盘路径类似于下面的格式:source = /data/logs/default/tomcat/742473c7-17dc-11e9-afc5-0a07a5c4fbe2/appname/filename.logresult[7]之所以出现这种及其容易出现bug的写法,一是由于我们这边有严格的日志规范,另外,只是给大家提供一种lua写filter的思路。制作镜像我们是基于fluent bit 1.0.2 。所以找到官方的代码仓库,git clone 下来,稍作更改。新的dockerfile如下:FROM debian:stretch as builder# Fluent Bit versionENV FLB_MAJOR 1ENV FLB_MINOR 0ENV FLB_PATCH 2ENV FLB_VERSION 1.0.2ENV DEBIAN_FRONTEND noninteractiveENV FLB_TARBALL http://github.com/fluent/fluent-bit/archive/v$FLB_VERSION.zipRUN mkdir -p /fluent-bit/bin /fluent-bit/etc /fluent-bit/log /tmp/fluent-bit-master/RUN apt-get update && \ apt-get install -y –no-install-recommends \ build-essential \ cmake \ make \ wget \ unzip \ libssl1.0-dev \ libasl-dev \ libsasl2-dev \ pkg-config \ libsystemd-dev \ zlib1g-dev \ ca-certificates \ && wget -O “/tmp/fluent-bit-${FLB_VERSION}.zip” ${FLB_TARBALL} \ && cd /tmp && unzip “fluent-bit-$FLB_VERSION.zip” \ && cd “fluent-bit-$FLB_VERSION”/build/ \ && rm -rf /tmp/fluent-bit-$FLB_VERSION/build/WORKDIR /tmp/fluent-bit-$FLB_VERSION/build/RUN cmake -DFLB_DEBUG=On \ -DFLB_TRACE=Off \ -DFLB_JEMALLOC=On \ -DFLB_TLS=On \ -DFLB_SHARED_LIB=Off \ -DFLB_EXAMPLES=Off \ -DFLB_HTTP_SERVER=On \ -DFLB_IN_SYSTEMD=On \ -DFLB_OUT_KAFKA=On ..RUN make -j $(getconf _NPROCESSORS_ONLN)RUN install bin/fluent-bit /fluent-bit/bin/# Configuration filesCOPY fluent-bit.conf \ parsers.conf \ parsers_java.conf \ parsers_extra.conf \ parsers_openstack.conf \ parsers_cinder.conf \ plugins.conf \ /fluent-bit/etc/COPY dissect.lua /fluent-bit/bin/FROM gcr.io/distroless/ccMAINTAINER Eduardo Silva <eduardo@treasure-data.com>LABEL Description=“Fluent Bit docker image” Vendor=“Fluent Organization” Version=“1.1"COPY –from=builder /usr/lib/x86_64-linux-gnu/sasl /usr/lib/x86_64-linux-gnu/COPY –from=builder /usr/lib/x86_64-linux-gnu/libz /usr/lib/x86_64-linux-gnu/COPY –from=builder /lib/x86_64-linux-gnu/libz* /lib/x86_64-linux-gnu/COPY –from=builder /usr/lib/x86_64-linux-gnu/libssl.so* /usr/lib/x86_64-linux-gnu/COPY –from=builder /usr/lib/x86_64-linux-gnu/libcrypto.so* /usr/lib/x86_64-linux-gnu/# These below are all needed for systemdCOPY –from=builder /lib/x86_64-linux-gnu/libsystemd* /lib/x86_64-linux-gnu/COPY –from=builder /lib/x86_64-linux-gnu/libselinux.so* /lib/x86_64-linux-gnu/COPY –from=builder /lib/x86_64-linux-gnu/liblzma.so* /lib/x86_64-linux-gnu/COPY –from=builder /usr/lib/x86_64-linux-gnu/liblz4.so* /usr/lib/x86_64-linux-gnu/COPY –from=builder /lib/x86_64-linux-gnu/libgcrypt.so* /lib/x86_64-linux-gnu/COPY –from=builder /lib/x86_64-linux-gnu/libpcre.so* /lib/x86_64-linux-gnu/COPY –from=builder /lib/x86_64-linux-gnu/libgpg-error.so* /lib/x86_64-linux-gnu/COPY –from=builder /fluent-bit /fluent-bit#EXPOSE 2020# Entry pointCMD ["/fluent-bit/bin/fluent-bit”, “-c”, “/fluent-bit/etc/fluent-bit.conf”]注意增加了 COPY dissect.lua /fluent-bit/bin/ 。然后就build镜像即可。使用姿势使用比较简单的。demo如下: [FILTER] Name lua Match app.* script /fluent-bit/bin/dissect.lua call dissectscript lua脚本的存放路径。call 即为lua函数名。总结通过写这个filter,有一下几个感悟吧。官方的镜像基于谷歌的distroless镜像,没有shell,没有包管理,调试起来很费力。平时的业务容器化场景中,明显的不合适,与阿里的富容器思维南辕北辙。当然除非你公司的业务开发能力足够强。fluent bit 相关的资料还是有点少。遇到问题和使用一些不明白的地方,解决起来费力。除非你是c专家。官方文档写的也不够详细,只是描述了个大概。 ...

January 14, 2019 · 3 min · jiezi