nokoのブログ

こちらは暫定のメモ置き場ですので悪しからず

fluentdとKinesisDataFirehostとlogrotateでログの収集とローテをする

はじめに

  • fluentd(EC2→CloudWatchLogs) + Kinesis Data Firehose(EC2→CloudWatchLogs → S3) でログの収集
  • logrotateでログのローテ・改廃(EC2)

fluentdでログの収集

fluentdの仕組み

  • 1つのメッセージは、[tag, time, record]で構成される
  • 流れ
    • Inputプラグイン: 各種データソースからのログにタグを付けて収集する
    • Filterプラグイン: フィルタ(データの加工)を行う
    • Outputプラグイン: 各種データ保存先へ出力する
  • ディレクトリ構成
    • /etc/td-agent/td-agent.conf
    • /var/log/td-agent/
  • ディレクティブ
      • ディレクティブで指定したプラグインを経由してログ収集を始める
      • Inputプラグインを指定
        • tail が多い
          • pos_fileオプションの利用を推奨(再起動しても続きから)
          • formatが特になければnone
      • @type: プラグイン
      • tag: 出力タグ
      • 指定したタグパターンに該当するディレクティブで、タグの書き換えや外部へのデータ出力を行う
      • ログの出力先を決めるディレクティブ
      • @type: プラグイン
        • cloudwatch_logs
          • log_stream_nameをつける代わりに use_tag_as_stream true でも良い

fluentdの設定例

  • 下記のようにS3に直接送る場合もあるが、他サービスと合わせてCloudWatchLogsからS3に送る場合もある
<source>
  @type tail
  path /var/log/httpd/access_log
  pos_file /var/log/td-agent/httpd.access.log.pos
  format apache
  tag td.apache.access
</source>

<match td.apache.**>
  @type cloudwatch_logs
  region ap-northeast-1
  auto_create_stream true
  log_stream_name ${hostname}
  log_group_name ${tag}
  retention_in_days 8
  flush_at_shutdown true
</match>

<match td.apache.**>
  @type s3
  s3_region ap-northeast-1
  s3_enpoint s3-ap-northeast-1.amazonaws.com
  s3_bucket s3-bucket-log
  path ec2/
  time_slice_format ${hostname}/${tag}/${tag}-%Y%m%d%H
  flush_at_shutdown true
</match>
  • (参考)Slack通知バージョン
<source>
  @type tail
</source>

<match td.syslog.**>
  @copy
  <store>
    @type cloudwatch_logs
  </store>

  <store>
    @type s3
  </store>

  <store>
    @type grepcounter
  </store>
</match>

<filter slack.td.syslog.**>
  @type record_transformer
</filter>

...

<match slack.**>
  @type slack
</match>

Kinesis Data Firehoseでログの転送

Kinesis Data Firehoseの仕組み

  • CloudWatchLogsからS3へLambdaでの定期実行をしてはいけない理由
    • Export taskは1アカウント/regionで同時に一つしか実行できない
    • 対象となるデータにはタイムラグがあり、ニアリアルタイムのExportができない
    • 古いログの欠落に繋がる。久しぶりに起動したEC2から古いタイムスタンプのログが送られてきたり
  • 主な構成要素
    • 配信ストリーム(Delivery Stream)
      • データ配信の単位
    • データプロデューサー
      • Kinesis Data Firehose へのデータの送信元
  • Subscription Filterとは

Kinesis Data Firehoseの設定例

  • Kinesis Data Firehose のIAMロールを作成する
  • Kinesis Data Firehose の配信ストリームを作成する
    • データ変換(Lambdaをかます)もできる
    • 配信先を指定(S3など)
    • 上記で作成したロールを指定
  • CloudWatch Logs のIAMロールを作成する
    • CloudWatch Logs が Kinesis Data Firehose にデータを送信するためのIAMロールを作成
  • CloudWatch Logs から Kinesis Data Firehose にデータを送信するためのサブスクリプションフィルタを作成する
    • log-group-name
    • filter-pattern(今回は指定なし)
    • destination-arn
    • role-arn
  • → 概要としては、 kinesis firehose delivery stream とそのIAMロールを作る + CloudWatchの subscription filter とそのIAMロールを作る

logrotateでログのローテ・改廃

logrotateの仕組み

  • /etc/logrotate.confに全ての設定を記載することも可能だが、/etc/logrotate.d以下もincludeされているので、ここにサービスごとの設定ファイルを作成し、記載する。
  • dry run
    • logrotate -dv /etc/logrotate.conf

logrotateの設定例

/var/log/sample/access.log { # 対象のログファイル
    ifempty                  # ログファイルが空でもローテーションする
    daily                    # 毎日ローテートする
    # dataext                # dailyと組み合わせ、元のファイル名 + -YYYYMMDD のファイル名で生成
    dateformat .%Y%m%d       # dateフォーマットを任意のものに変更する
    missingok                # ログファイルがなくてもエラーを出さない
    compress                 # 圧縮する
    delaycompress            # ログの圧縮作業を次回のローテーション時まで遅らせる。compressと共に指定
    rotate 10                # 10世代分古いログを残す
    # create 0644 fuga fuga  # ローテーションを行った後、代わりに空の新規ログファイルを作る。権限・グループ・ユーザを指定可能
    postrotate               # ローテート後にsyslogを再起動
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

参考