• 21. Fluentd输出插件:rewrite_tag_filter用法详解


    我们在做日志处理时,往往会从多个源服务器收集日志,然后在一个(或一组)中心服务器做日志聚合分析。
    源服务器上的日志可能属于同一应用类型,也可能属于不同应用类型。我们可能需要在聚合服务器上对这些不同类型的日志分类处理,一个实现方法就是在Fluentd内部重新给这些日志打tag,然后重新路由到合适的output插件进行输出。
    rewrite_tag_filter就是一个提供这种给日志重新打tag的插件。需要说明的是,从其命名来看,rewrite_tag_filter是一个filter,而实际上它是一个output插件。因为Fluentd的filter插件并不允许重写tag。

    1. 基本原理
      rewrite_tag_filter可通过定义一系列的规则(rule)来实现日志的匹配和tag重写。
      这些规则会按照其定义顺序逐一对日志进行匹配,一旦日志符合某个规则,插件会使用该规则定义的方法重写日志的tag,并将重写后的日志事件再次发送到Fluentd路由中,从而实现对输入日志的分类处理。

    举一个简单的例子:

    # Configuration
    <match app.component>
      @type rewrite_tag_filter
      <rule>
        key message
        pattern /^(w+)$/
        tag $1.${tag}
      </rule>
    </match>
    

    在这个例子中,日志的原tag为app.component。
    rewrite_tag_filter会对日志记录的message字段进行匹配测试,pattern定义了匹配规则,这里是匹配message中的每个单词,然后去第一个单词,将其插入到原tag之前。

    重写效果如下所示:

    +------------------------------------------+        +------------------------------------------------+
    | original record                          |        | rewritten tag record                           |
    |------------------------------------------|        |------------------------------------------------|
    | app.component {"message":"[info]: ..."}  | +----> | info.app.component {"message":"[info]: ..."}   |
    | app.component {"message":"[warn]: ..."}  | +----> | warn.app.component {"message":"[warn]: ..."}   |
    | app.component {"message":"[crit]: ..."}  | +----> | crit.app.component {"message":"[crit]: ..."}   |
    | app.component {"message":"[alert]: ..."} | +----> | alert.app.component {"message":"[alert]: ..."} |
    +------------------------------------------+        +------------------------------------------------+
    
    1. 安装说明
      td-agent v3.0.1或更高版本已经内置了rewrite_tag_filter。
      较低版本的td-agent可以通过以下命令进行安装:
    # for td-agent2 (with fluentd v0.12)
    $ sudo td-agent-gem install fluent-plugin-rewrite-tag-filter -v 1.6.0
    
    # for td-agent3 (with fluentd v0.14)
    $ sudo td-agent-gem install fluent-plugin-rewrite-tag-filter
    
    1. 配置示例
      一个好的配置设计原则是:先过滤掉不需要的日志,然后再处理需要重写的日志。
    <source>
      @type tail
      path /var/log/httpd/access_log
      <parse>
        @type apache2
      </parse>
      tag td.apache.access
      pos_file /var/log/td-agent/apache_access.pos
    </source>
    
    <match td.apache.access>
      @type rewrite_tag_filter
      capitalize_regex_backreference yes
      <rule>
        key     path
        pattern /.(gif|jpe?g|png|pdf|zip)$/
        tag     clear
      </rule>
      <rule>
        key     status
        pattern /^200$/
        tag     clear
        invert  true
      </rule>
      <rule>
        key     domain
        pattern /^.+.com$/
        tag     clear
        invert  true
      </rule>
      <rule>
        key     domain
        pattern /^maps.example.com$/
        tag     site.ExampleMaps
      </rule>
      <rule>
        key     domain
        pattern /^news.example.com$/
        tag     site.ExampleNews
      </rule>
      # it is also supported regexp back reference.
      <rule>
        key     domain
        pattern /^(mail).(example).com$/
        tag     site.$2$1
      </rule>
      <rule>
        key     domain
        pattern /.+/
        tag     site.unmatched
      </rule>
    </match>
    
    <match site.*>
      @type mongo
      host localhost
      database apache_access
      remove_tag_prefix site
      tag_mapped
      capped
      capped_size 100m
    </match>
    
    <match clear>
      @type null
    </match>
    

    这个例子中,rewrite_tag_filter首先过滤掉了Apache中图片、压缩包等静态文件的请求日志,然后对日志中的path、status、domain这些字段依次进行正则匹配:
    第二个rule用于匹配响应代码为200的记录,通过invert将非200的请求记录过滤掉;
    第三个rule用于匹配.com结尾的域名,通过invert将非.com域名请求记录过滤掉;
    第四五六个rule用于分类处理不同前缀的域名,分别重写其tag为site.ExampleMaps、site.ExampleNews、site.ExampleMail;
    最后一个rule用于处理其他域名,统一重写tag为site.unmatched。

    被过滤掉的日志,其tag被重写为clear,并最后丢弃(输出到null)。
    其他被重写tag的日志会按照其tag名称被分别写入MongoDB的不同collections中。

    1. 参数说明
    • capitalize_regex_backreference 是否大写正则匹配后项引用项的首字母。默认false,不大写。
    • <rule>配置项 设置匹配及重写规则。
      key:指定日志记录中的匹配字段
      pattern:匹配规则使用的正则表达式
      tag:新的tag。
      支持正则表达式的后向引用,参加上例中第六个rule。
      支持以下占位符:
      • ${tag}__TAG__:原tag
      • ${tag_parts[n]}__TAG_PARTS[n]__:取原tag的第n个字段
      • ${hostname}__HOSTNAME__:主机名
        invert:默认为false。
      • true表示若匹配失败,则重写tag;
      • false表示匹配成功时才重写tag。
        占位符参数:
        • remove_tag_prefix:移除原tag中的前缀
        • remove_tag_regexp:移除原tag中的正则匹配部分
        • hostname_command:设置hostname使用的命令。
          默认使用hostname获取完整的主机名。
          可使用hostname -s获取较短的主机名。
    1. 场景举例
    # built-in TCP input
    <source>
      @type forward
    </source>
    
    # Filter record like mod_rewrite with fluent-plugin-rewrite-tag-filter
    <match apache.access>
      @type rewrite_tag_filter
      <rule>
        key     status
        pattern /^(?!404)$/
        tag     clear
      </rule>
      <rule>
        key     path
        pattern /.+/
        tag     mongo.apache.access.error404
      </rule>
    </match>
    
    # Store deadlinks log into mongoDB
    <match mongo.apache.access.error404>
      @type        mongo
      host        10.100.1.30
      database    apache
      collection  deadlinks
      capped
      capped_size 50m
    </match>
    
    # Clear tag
    <match clear>
      @type null
    </match>
    

    这个配置使用in_forward收集Apache的访问日志。通过设置两个rule,提取日志中的http 404请求记录,将这些请求的url写入MongoDB,这样就可以方便地统计网站中存在的死链。

    1. 常见问题
      使用rewrite_tag_filter经常遇到的情况是,重写tag导致日志无法输出。
      比如:
    <match app.**>
      @type rewrite_tag_filter
      <rule>
        key     level
        pattern /(.+)/
        tag     app.$1
      </rule>
    </match>
    
    <match app.**>
      @type forward
      # ...
    </match>
    

    这个片段就会导致日志无法输出。
    仔细看重写规则可以发现,以app开头的tag被重写后仍然是以app为开头。这导致了新事件重新进入第一个<match>,发生了死循环。
    所以重新tag时需要谨慎一些,避免发生此类情况。

  • 相关阅读:
    Android Studio 2.2以上支持了Cmake的配置JNI的相关参数
    Unable to instantiate receiver xxx.receiver.NetworkReceiver异常
    关于imageview matrix
    Android NDK开发 JNI操作java构造方法,普通方法,静态方法(七)
    COOKIE和SESSION的区别
    Android NetworkInterface 的 name
    Android ROM资源文件存放位置
    selinux
    当WebView运行在特权进程时抛出安全异常,Hook方式解决方案(包含对Android 8.0的处理)
    Android判断当前是否在主线程
  • 原文地址:https://www.cnblogs.com/sanduzxcvbnm/p/13925901.html
Copyright © 2020-2023  润新知