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時需要謹慎一些,避免發生此類情況。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM