0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AmazonLinux1(CentOS6世代)×fluentd GemでCloudWatchにログを転送する

Posted at
fluentd

AmazonLinux1(CentOS6世代) のlatesttd-agent3(embedded ruby2.4) において、CloudWatch連携プラグインfluent-plugin-cloudwatch-logsのgem依存関係がruby>=2.5を必要とするようになったため、システムのrubyランタイムを使ってfluentdgem直でCloudWatchにサーバーログを送信するためのロードマップ。

Ruby環境

AWS Amazon EC2にrbenvでRuby環境を構築する

rbenvで2.5.1を入れてglobalをスイッチ

sh
# rbenvバイナリをgithubからクローン
git clone https://github.com/sstephenson/rbenv.git /opt/rbenv

# ログインプロフィールにrbenvの環境設定
echo 'export RBENV_ROOT="/opt/rbenv"' > /etc/profile.d/rbenv.sh
echo 'export PATH="${RBENV_ROOT}/bin:${PATH}"' >> /etc/profile.d/rbenv.sh
echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh

# ログインプロフィールをローディング
source /etc/profile.d/rbenv.sh

# ruby 2.5.1をインストールする
rbenv install -v 2.5.1
rbenv rehash

# インストールバイナリ確認
rbenv versions

* system
2.5.1 (set by /opt/rbenv/version)

# システムバージョンを2.5.1に変更
rbenv global 2.5.1

# システムバージョンを確認
rbenv versions
  system
* 2.5.1 (set by /opt/rbenv/version)

fluentdパッケージをインストール

rbenvで環境を縛る

sh
rbenv exec gem install fluentd

# yajl-rubyがrequire ruby >= 2.6.0
ERROR:  Error installing fluentd:
        The last version of yajl-ruby (~> 1.0) to support your Ruby & RubyGems was 1.4.1. Try installing it with `gem install yajl-ruby -v 1.4.1` and then running the current command again
        yajl-ruby requires Ruby version >= 2.6.0. The current ruby version is 2.5.0.

# yajl-rubyがrequire ruby >= 2.Xなv1.4.1に落としてインストール
rbenv exec gem install yajl-ruby -v 1.4.1

rbenv exec gem install fluentd

# bundlerがrequire ruby >= 3.0.0
ERROR:  Error installing fluentd:
        The last version of bundler (>= 0) to support your Ruby & RubyGems was 2.3.27. Try installing it with `gem install bundler -v 2.3.27` and then running the current command again
        bundler requires Ruby version >= 3.0.0. The current ruby version is 2.5.0.

# bundlerをrequire ruby >= 2.Xなv2.3.27に落としてインストール
rbenv exec gem install bundler -v 2.3.27

# 成功
rbenv exec gem install fluentd

fluentdプラグインをインストール

fluent-plugin-cloudwatch-logsプラグイン

CloudWatchに送信するためにfluent-plugin-cloudwatch-logsプラグインをインストールする

sh
rbenv exec gem install fluent-plugin-cloudwatch-logs

fluent-plugin-record-reformerプラグイン

ログにホストのメタ情報を添加するためにfluent-plugin-record-reformerプラグインをインストールする

sh
rbenv exec gem install fluent-plugin-record-reformer

fluentdのセットアップ

fluent.conf

setupコマンドでconfを作成する

sh
fluentd --setup /etc/fluentd
> Installed /etc/fluentd/fluent.conf.

fluentdの制御

ネイティブ制御

フロント起動させて動作確認するときに

fluentdのフロント実行コマンド

sh
fluentd -c /path/to/fluent.conf -vv &

終了は直接プロセスを落とす

sh
pkill fluentd

init.d制御

/etc/init.d/fluentdに下記のinit.dスクリプトを作成する

  • コンフィグファイル: /etc/fluentd/fluent.conf
  • ログファイル: /var/log/fluentd/fluentd.log
/etc/init.d/fluentd
#!/bin/sh
# chkconfig: 2345 99 01
# description: Fluentd
### BEGIN INIT INFO
# Provides:          fluentd
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO
# USER=fluent
USER=root
# DAEMON=/usr/local/bin/fluentd
DAEMON=/opt/rbenv/shims/fluentd

DAEMON_ARGS="-c /etc/fluentd/fluent.conf -o /var/log/fluentd/fluentd.log --daemon /var/run/fluentd.pid"
PID=/var/run/fluentd.pid
case "$1" in
 start)
       echo -n "Starting Fluentd: "
       su - $USER -c "$DAEMON $DAEMON_ARGS"
       echo "done"
       ;;
 stop)
       echo -n "Stopping Fluentd: "
       kill `cat $PID`
       echo "done"
       ;;
 restart)
       $0 stop
       $0 start
       ;;
 *)
       echo "Usage: $0 {start|stop|restart}"
       exit 1
esac
exit 0

制御方法

sh
# init.dスクリプトに実行権限あてる
chmod +x /etc/init.d/fluentd
# 起動
/etc/init.d/fluentd start
# 終了
/etc/init.d/fluentd stop
# 再起動
/etc/init.d/fluentd restart

自動起動の設定

sh
chkconfig --add fluentd
chkconfig fluentd on

chkconfig | grep fluentd
> fluentd         0:off   1:off   2:on    3:on    4:on    5:on    6:off

設定

/etc/fluentd/fluent.conf

apacheのカスタムアクセスログの構成例 )

fluent.conf
# sourceディレクティブ
# pathに定義したログをトラッキングしてformatに合致したとき、tagとともに、<...>のキャプチャ内容をmatchフェーズに送る
<source>
  @type tail
  format /^(?<xforwarded>[^ ]*) (?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")? "(?<sess>[^\"]*)"$/
  time_format %d/%b/%Y:%H:%M:%S %z
  path /etc/httpd/logs/access.log
  pos_file /var/log/fluentd/log.httpd.access.idt.pos
  # メタ情報を添加するために.reformタグをつける
  tag this.tagname.reform
</source>

# matchディレクティブ
# sourceから送られてきたtag識別子をもとにmatchディレクティブのタグとスクリーニングし、それをどうするかを定義

# 1. はじめに.reformタグをスクリーニングして、ホストのメタ情報を添加して、matchフェーズに再入させる
<match **.reform>
  # record-reformerプラグイン
  @type record_reformer
  renew_record false
  enable_ruby true

  # 添加後、スクリーニング再入で本来のmatchアクションディレクティブに補足させるためにreformタグをクレンジングして、tagディレクティブでmatchフェーズに再入する
  # クレンジングしないと永遠に<match **.reform>にマッチして、無限ループになるので要注意
  tag ${(tag_parts - ["reform"]).join(".")}

  # ホスト名とタイムスタンプを添加する
  <record>
    hostname ${hostname}
    servertime ${time.iso8601(3)}
  </record>
</match>

# 2. <match **.reform>による再入後、データをアクションする
<match this.tagname.**>
  # cloudwatch-logsプラグイン
  @type cloudwatch_logs

  region ap-northeast-1
  log_group_name path.to.loggroup

  # ロググループ内に{タグ名}で自動的にログストリームを作成する
  auto_create_stream true
  use_tag_as_stream true
</match>

sourceディレクティブに入力されるapacheアクセスログ

XXX.XXX.XXX.XXX YYY.YYY.YYY.YYY - - [23/Mar/2024:05:45:00 +0900] "GET /path/to/page HTTP/1.1" 200 138792 "https://host.example.com/" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36" "abcdefg"

フォーマット後のjson

json
{
    "xforwarded": "XXX.XXX.XXX.XXX",
    "host": "YYY.YYY.YYY.YYY",
    "user": "-",
    "method": "GET",
    "path": "/path/to/page",
    "code": "200",
    "size": "687368",
    "referer": "https://host.example.com/",
    "agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36",
    "sess": "abcdefg",
	# record_reformerで追加したメタ情報
    "hostname": "fluent-host",
    "servertime": "2024-03-23T05:45:03.000+09:00"
}

AWS

EC2/IAM

EC2のロールにCloudWatchLogsFullAccessポリシーを追加する

CloudWatch

ロググループpath.to.loggroupを作成しておく
※ログストリームはauto_create_streamオプションで自動的に作成してくれる

httpdとアプリログのスニペット

fluent.conf
############################################
# sourceディレクティブ 
############################################

# アプリケーションログ
<source>
  @type tail
  format /^\[(?<timestamp>.*)\]\[(?<level>[^ ]*)\] \[(?<ip>[^ ]*) - (?<session_id>[^ ]*).*\] (?<message>.*)$/
  path /var/www/project/log/*.log
  pos_file /var/log/fluentd/log.app.pos
  tag log.app.reform
  read_from_head true
</source>

# httpdアクセスログ
<source>
  @type tail
  format /^(?<xforwarded>[^ ]*) (?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")? "(?<sess>[^\"]*)"$/
  time_format %d/%b/%Y:%H:%M:%S %z
  path /etc/httpd/logs/access.log
  pos_file /var/log/fluentd/log.httpd.access.pos
  tag log.httpd.access.reform
</source>

# httpdエラーログ
<source>
  @type tail
  format /^\[[^ ]* (?<time>[^\]]*)\] \[(?<level>[^\]]*)\](?: \[pid (?<pid>[^\]]*)\])? \[client (?<client>[^\]]*)\] (?<message>.*)$/
  path /etc/httpd/logs/error.log
  pos_file /var/log/fluentd/log.httpd.error.pos
  tag log.httpd.error.reform
</source>

# auditlog
<source>
  @type tail
  format none
  path /var/log/audit/audit.log
  pos_file /var/log/fluentd/log.audit.pos
  tag log.audit.reform
</source>

# securelog
<source>
  @type tail
  format syslog
  path /var/log/secure
  pos_file /var/log/fluentd/log.secure.pos
  tag log.secure.reform
</source>

# ホストのメタ情報を追加してmatchフェーズに再入させる
<match **.reform>
  @type record_reformer
  renew_record false
  enable_ruby true
  tag ${(tag_parts - ["reform"]).join(".")}
  <record>
    hostname ${hostname}
    servertime ${time.iso8601(3)}
  </record>
</match>

# CloudWatchLogsのlog.appロググループに送信
<match log.app.**>
  @type cloudwatch_logs
  region ap-northeast-1
  log_group_name log.app
  auto_create_stream true
  use_tag_as_stream true
</match>

# CloudWatchLogsのlog.httpd.accessロググループに送信
<match log.httpd.access.**>
  @type cloudwatch_logs
  region ap-northeast-1
  log_group_name log.httpd.access
  auto_create_stream true
  use_tag_as_stream true
</match>

# CloudWatchLogsのlog.httpd.errorロググループに送信
<match log.httpd.error.**>
  @type cloudwatch_logs
  region ap-northeast-1
  log_group_name log.httpd.error
  auto_create_stream true
  use_tag_as_stream true
</match>

# CloudWatchLogsのlog.auditロググループに送信
<match log.audit.**>
  @type cloudwatch_logs
  region ap-northeast-1
  log_group_name log.audit
  auto_create_stream true
  use_tag_as_stream true
</match>

# CloudWatchLogsのlog.secureロググループに送信
<match log.secure.**>
  @type cloudwatch_logs
  region ap-northeast-1
  log_group_name log.secure
  auto_create_stream true
  use_tag_as_stream true
</match>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?