FluentdでPythonのログをTeamsに通知する
Fluentd では Python のログを収集していますので、 ログレベルが WARNING 以上のログを抽出して、Teams に送信したいです。
Teams のプラグイン
は既にありますが、Python のログを送信するために、ちょっと変更しました。
変更した後のコードを out_teams.rb として保存し、/etc/fluent/plugin
にコピーすれば、プラグインとして使えます。
パラメータについて、
webhook_url
(必須):Teams の Webhook URLtitle
(オプション):メッセージのタイトルtext
(オプション):メッセージの本文
require 'rest-client'
require 'fluent/plugin/output'
module Fluent
module Plugin
class TeamsOutput < Output
Fluent::Plugin.register_output('teams', self)
DEFAULT_BUFFER_TYPE = 'memory'.freeze
desc 'Webhook URL'
config_param :webhook_url, :string
desc 'Title'
config_param :title, :string, default: nil
desc 'Message content. Supported erb format and newline character.'
config_param :text, :string, default: nil
...
def post_message(args = {})
payload = build_payload(args)
RestClient.post(@webhook_url, payload.to_json, content_type: :json)
end
def build_payload(args = {})
tag = args[:tag]
time = args[:time]
record = args[:record]
log_level = record['level']
if log_level == 'WARNING'
color = 'ffc986'
else
color = 'ff4e4e'
end
sections = [{
"activityTitle" => build_title(record),
"facts" => build_facts(record)}, {
"text" => build_text(record),
"markdown" => true
}]
{ themeColor: color, summary: title, sections: sections }
end
def build_title(record)
return @title unless @title.nil?
record['title']
end
def build_text(record)
text = "`#{record['message']}`"
return text if @text.nil?
ERB.new(@text).result(binding).gsub('\\n', "\n")
end
def build_facts(record)
keys = record.keys
facts = []
keys.each do |key|
next if (key == 'message' || key == 'title')
facts << {"name" => key, "value" => record[key]}
end
facts
end
end
end
end
Teams プラグイン以外に使用しているプラグインは、
filter_grep
: ログレベルが WARNING / ERROR のログを抽出します。filter_record_transformer
: 新しいフィールド title を追加します。
Fluentd の設定例:
<match test.*>
@type copy
<store>
@type relabel
@label @teams_notification
</store>
</match>
<label @teams_notification>
<filter test.*>
@type grep
<regexp>
key level
pattern /^(?:WARNING|ERROR)$/
</regexp>
</filter>
<filter test.*>
@type record_transformer
<record>
title "An error occurred in ${tag_parts[1]}"
</record>
</filter>
<match test.*>
@type teams
webhook_url WEBHOOK_URL
</match>
</label>
```