EBに置いたrailsからAmazon Kinesis Data FirehoseでlogをamazonESに投げる

はじめに

ちょっとググるとamazonESにログを送信するのにfluentd(td-agent)を利用するケースが多いですが、その場合以下のライブラリを利用するみたいなのが多く出てきます。
https://github.com/atomita/fluent-plugin-aws-elasticsearch-service
ただ、メンテナンスされてないっぽいのと、Amazon Kinesis Data Firehoseを利用したほうが楽そうだったので設定してみました。

※EBの設定はしてあるものとします

Railsの設定

logrageでjsonのlog吐き出す

参考
https://qiita.com/ichi_s/items/7cf6ce5dbfaa00976dd4

Gemfile
gem 'lograge'
gem 'logstash-event'
gem "rack-user_agent"

config/initializers/lograge.rb
Rails.application.configure do
  config.lograge.enabled = true
  config.lograge.base_controller_class = ['ActionController::API', 'ActionController::Base']
  config.lograge.formatter = Lograge::Formatters::Logstash.new
  config.lograge.keep_original_rails_log = true
  config.lograge.logger = ActiveSupport::Logger.new "#{Rails.root}/log/lograge_#{Rails.env}.log"
  config.lograge.custom_options = lambda do |event|
    payload = event.payload

    data = payload.slice(*%i(
      uuid host remote_ip user_agent os os_version browser browser_version user_id 
    ))

    if payload[:exception]
      e = payload[:exception_object]
      data[:exception_class] = e.class.to_s
      data[:exception_message] = e.message
      data[:stacktrace] = "#{e.class}: #{e.message}\n" + (e.backtrace || []).join("\n")
    end

    data
  end
end

application_controller.rb
  def append_info_to_payload(payload)
    super
  
    payload[:uuid]                = request.uuid
    payload[:host]                = request.host
    payload[:remote_ip]           = request.remote_ip
    payload[:user_agent]          = request.user_agent
    payload[:os]                  = request.os
    payload[:os_version]          = request.os_version
    payload[:browser]             = request.browser
    payload[:browser_version]     = request.browser_version
    payload[:user_id]             = current_user.id.to_s if current_user.present?
  end

AmazonES設定

この辺を参考に画面からポチポチ作成していきます。
https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-createupdatedomains.html

access policy参考
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::IAMユーザーのARN",
        ]
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:ESのARN"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:*",
      "Resource": "ESのARN",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "許可したいIPアドレス"
        }
      }
    }
  ]
}

Amazon Kinesis Data Firehose設定

この辺を参考に画面からポチポチ設定していきます
https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/what-is-this-service.html

.ebextensionsの下に設定ファイルを置きます。今回はnginx、railsのログをFirehoseに送信します
.ebextensions/0-aws-kinesis-agent.config
packages: 
  yum:
    aws-kinesis-agent: []
files:
  "/etc/aws-kinesis/agent.json":
    owner: root
    group: root
    content: |
      {
        "cloudwatch.emitMetrics": true,
        "cloudwatch.endpoint": "https://monitoring.ap-northeast-1.amazonaws.com",
        "firehose.endpoint": "https://firehose.ap-northeast-1.amazonaws.com",
      
        "flows": [
          {
            "filePattern": "/var/app/current/log/lograge_production.log*",
            "deliveryStream": "設定したdeliveryStream名"
          },
          {
            "filePattern": "/var/log/nginx/access.log*",
            "deliveryStream": "設定したdeliveryStream名",
            "dataProcessingOptions": [
              {
                "optionName": "LOGTOJSON",
                "logFormat": "COMMONAPACHELOG"
              }
            ]
          }
        ]
      }

.ebextensions/1-aws-kinesis-agent.config
commands:
  01-command:
   command: service aws-kinesis-agent restart

これで完了なのでdeployします

ログのローテート時にエラーになる対処

一件うまくいったように見えますが、ログのローテート時に以下のエラーが永遠に出続けます
2018-04-03 17:51:21.779+0000 ip-10-199-93-156 (FileTailer[fh:lukew_nginx_access_log:/var/log/nginx/access.log]) com.amazon.kinesis.streaming.agent.tailing.FileTailer [ERROR] FileTailer[fh:lukew_nginx_access_log:/var/log/nginx/access.log]: Error when processing current input file or when tracking its status.
java.lang.IllegalArgumentException: Current file is not contained in current snapshot!
 at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
 at com.amazon.kinesis.streaming.agent.tailing.TrackedFileRotationAnalyzer.(Unknown Source)
 at com.amazon.kinesis.streaming.agent.tailing.SourceFileTracker.updateCurrentFile(Unknown Source)
 at com.amazon.kinesis.streaming.agent.tailing.SourceFileTracker.refresh(Unknown Source)
 at com.amazon.kinesis.streaming.agent.tailing.FileTailer.updateRecordParser(Unknown Source)
 at com.amazon.kinesis.streaming.agent.tailing.FileTailer.processRecords(Unknown Source)
 at com.amazon.kinesis.streaming.agent.tailing.FileTailer.runOnce(Unknown Source)
 at com.amazon.kinesis.streaming.agent.tailing.FileTailer.run(Unknown Source)
 at com.google.common.util.concurrent.AbstractExecutionThreadService$1$2.run(AbstractExecutionThreadService.java:60)
 at com.google.common.util.concurrent.Callables$3.run(Callables.java:95)
 at java.lang.Thread.run(Thread.java:748)
issueにも上がってます
https://github.com/awslabs/amazon-kinesis-agent/issues/50

対処法としては、EBの場合にローテートされたファイルは同じディレクトリではなくて、ディレクトリの下に出来るのでダミーファイルをおいてあげることで解決しました。


/var/log/nginx/access.log.dummy
/var/app/current/log/lograge_production.log.dummy

1-aws-kinesis-agent.configに以下を追加
commands:
  01-command:
    command: touch /var/log/nginx/access.log.dummy
rails側のログは空ファイルのログをコミットします
log/lograge_production.log.dummy

これでいいのかわかりませんが、今のところ問題なさそう

コメント

  1. 그것을 빨리 인출하고 필요할 때 즉시 보충하기 위해 출납원을 방문하라. 게다가 처음 경기에 등록했을 때 후한 환영 보너스로 혜택을 받을 수 마이다스카지노 있을 것이다. 그리고 카지노의 충성심 계획에 등록하여 자주 상과 상을 타도록 하십시오. 2020년에는 모든 온라인 카지노에서 최소와 최대 베팅 제한을 찾을 수 있을 거야.

    返信削除

コメントを投稿

このブログの人気の投稿

FunBizのシステム環境

メッセージUIライブラリMessageKitの紹介