资讯专栏INFORMATION COLUMN

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

learn_shifeng / 3147人阅读

摘要:最近我们遇到奇葩的需求,不得不利用编写的,来满足需求。所以找到官方的代码仓库,下来,稍作更改。新的如下注意增加了。使用姿势使用比较简单的。遇到问题和使用一些不明白的地方,解决起来费力。官方文档写的也不够详细,只是描述了个大概。

前言

之前我们介绍过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, record
end
Function 输入参数 Function Arguments
name description
tag Name of the tag associated with the incoming record.
timestamp Unix timestamp with nanoseconds associated with the incoming record. The original format is a double (seconds.nanoseconds)
record Lua table with the record content
Return Values

Each callback must return three values:

name data type description
code integer The 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).
timestamp double If code equals 1, the original record timestamp will be replaced with this new value.
record table if 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.log

result[7]之所以出现这种及其容易出现bug的写法,一是由于我们这边有严格的日志规范,另外,只是给大家提供一种lua写filter的思路。

制作镜像

我们是基于fluent bit 1.0.2 。所以找到官方的代码仓库,git clone 下来,稍作更改。
新的dockerfile如下:

FROM debian:stretch as builder

# Fluent Bit version
ENV FLB_MAJOR 1
ENV FLB_MINOR 0
ENV FLB_PATCH 2
ENV FLB_VERSION 1.0.2

ENV DEBIAN_FRONTEND noninteractive

ENV FLB_TARBALL http://github.com/fluent/fluent-bit/archive/v$FLB_VERSION.zip
RUN 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 files
COPY 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/cc
MAINTAINER Eduardo Silva 
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 systemd
COPY --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 point
CMD ["/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                dissect

script lua脚本的存放路径。

call 即为lua函数名。

总结

通过写这个filter,有一下几个感悟吧。

官方的镜像基于谷歌的distroless镜像,没有shell,没有包管理,调试起来很费力。平时的业务容器化场景中,明显的不合适,与阿里的富容器思维南辕北辙。当然除非你公司的业务开发能力足够强。

fluent bit 相关的资料还是有点少。遇到问题和使用一些不明白的地方,解决起来费力。除非你是c专家。官方文档写的也不够详细,只是描述了个大概。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/32847.html

相关文章

  • k8slog--利用luafluent bit添加一个filter

    摘要:最近我们遇到奇葩的需求,不得不利用编写的,来满足需求。所以找到官方的代码仓库,下来,稍作更改。新的如下注意增加了。使用姿势使用比较简单的。遇到问题和使用一些不明白的地方,解决起来费力。官方文档写的也不够详细,只是描述了个大概。 前言 之前我们介绍过fluent bit这个日志收集神器。最近我们遇到奇葩的需求,不得不利用lua编写fluent bit的filter,来满足需求。 首先介绍...

    wing324 评论0 收藏0
  • k8slog--利用fluent bit收集k8s日志

    摘要:是一个开源和多平台的,它允许您从不同的来源收集数据日志,统一并将它们发送到多个目的地。例如日志收集日志分析主要讲部署的集群。日志主要有和的日志,一般采用部署,自然而然就是要支持格式日志的采集。业务落盘的日志。部署方案采取部署。 前言 收集日志的组件多不胜数,有ELK久负盛名组合中的logstash, 也有EFK组合中的filebeat,更有cncf新贵fluentd,另外还有大数据领域...

    betacat 评论0 收藏0
  • k8slog--利用fluent bit收集k8s日志

    摘要:是一个开源和多平台的,它允许您从不同的来源收集数据日志,统一并将它们发送到多个目的地。例如日志收集日志分析主要讲部署的集群。日志主要有和的日志,一般采用部署,自然而然就是要支持格式日志的采集。业务落盘的日志。部署方案采取部署。 前言 收集日志的组件多不胜数,有ELK久负盛名组合中的logstash, 也有EFK组合中的filebeat,更有cncf新贵fluentd,另外还有大数据领域...

    CoffeX 评论0 收藏0
  • k8s日志--采用golang实现Fluent Bit的output插件

    摘要:采用实现的插件前言目前社区日志采集和处理的组件不少,之前方案中的,社区中的,方案中的以及大数据用到比较多的。适合采用的方案,实现日志中心化收集的方案。主要负责采集,负责处理和传送。 采用golang实现Fluent Bit的output插件 前言 目前社区日志采集和处理的组件不少,之前elk方案中的logstash,cncf社区中的fluentd,efk方案中的filebeat,以及大...

    岳光 评论0 收藏0
  • k8s日志--采用golang实现Fluent Bit的output插件

    摘要:采用实现的插件前言目前社区日志采集和处理的组件不少,之前方案中的,社区中的,方案中的以及大数据用到比较多的。适合采用的方案,实现日志中心化收集的方案。主要负责采集,负责处理和传送。 采用golang实现Fluent Bit的output插件 前言 目前社区日志采集和处理的组件不少,之前elk方案中的logstash,cncf社区中的fluentd,efk方案中的filebeat,以及大...

    binta 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<