LoginSignup
2
2

More than 5 years have passed since last update.

OpsWorks上でfluentdでログ収集してBigQueryに投入する方法要点まとめ

Last updated at Posted at 2016-04-13

この記事の要点

  • OpsWorksでfluentdをインストール・設定する方法
  • IPアドレスを固定できない中、どうやって転送先のサーバを指定するか
  • Ruby on Rails 4.2でfluentdにログを送るには

方針

  • VPC使います。
  • 手順はカスタムCookbookでコード化する
  • 設定の使い分け
    • カスタムJSON
      • 環境によって変わる値(ステージングか、本番かなど)
    • カスタムCoookbookのopsworks/attributes/default.rb
      • 決め打ちしたい設定値
    • Appsの環境変数(Environment Variables)
      • Railsアプリの設定、秘密情報など

前提: カスタムCookbook

設定操作などをコード化するためにカスタムCookbookを使います。

カスタムCookbookの設定について

スタック設定でUse custom Chef cookbooksYesにします。
リポジトリにGitHubを使う場合はssh://git@ssh.github.com:443/hoge/fuga.gitのようにします。普通外向きの22番ポートは開けないので443番ポートを使います。

また、カスタムCookbookは1つしか指定できないので、ほかのCookbookを使えるようにするために、Manage BerkshelfYesにしておきます。
こうすることでBerksfileに記載したCookbookを使えるようになります。

OpsWorksでfluentdをインストールする

公式のCookbookを使います。

これを使うことで、fluentdのインストールだけでなく、設定もChefのレシピで書けるようになります。

サーバーとクライアント

fluentdでログを収集する場合、ログを集約するサーバーと、自ホスト内のログをとりまとめてサーバーに送るクライアント(?という表現でよいでしょうか)を用意するのが一般的かと思います。

OpsWorksでサーバーとクライアントそれぞれの設定を行うために、今回はレイヤーを使うことにしました。

具体的にはFluentd Server Layerを用意し、そのレイヤーが設定されたインスタンスにはサーバー向けの設定、その他のインスタンスではクライアント向けの設定を行うようなレシピを書くことにしました。

BigQueryに蓄積する

fluent-plugin-bigqueryを使いました。

それとは別に

  • APIの利用登録
  • bqコマンドでデータセットの作成
  • Google API ConsoleでGCEサービスアカウントJSONキーの取得

など行っておきます。

サーバーの指定

プライベートIPアドレスを固定できればそれで指定してやるのが楽ですが、OpsWorksでは指定できません。そこで、

  • Route53のPrivate DNS機能をVPC内で名前解決できるようにする
  • インスタンス起動時に自身のホスト名とプライベートIPアドレスをRoute53のAレコードに登録

とすることにしました。
こうすることでサーバーの指定をlog.stackname.yourdomain.localのような形で設定に記述でき、プライベートIPアドレスが変化しても自動的に追従できます。

VPCでPrivate DNSを使うには以下の記事が参考になるので適当に設定します。

Route53編~Private DNS~ | ナレコムAWSレシピ

OpsWorksで起動時にRoute53のAレコードを設定するには、route53を使って自分で書くか、あるいはopsworks_route53などを使えば簡単です。

なお、インスタンスのIAM RoleにRoute 53の設定を触れる権限が必要です。(通常 aws-opsworks-ec2-role に AmazonRoute53DomainsFullAccess AmazonRoute53FullAccess あたりを設定すればとりあえず動くはずです。)

Ruby on Rails 4.2でfluentdにログを送る

act-fluent-logger-railsを使いました。

Railsからはローカルホストのfluentdにしかるべきタグを付けて送るだけです。

実装

カスタムJSON(Stack)

{
  "fluentd_server":{
    "gce_project_id": "BigQuery使うプロジェクトID",
    "gce_service_json": "サービスアカウントJSONキーの内容",
    "host":"log-server1.stackname.yourprivatedomain.local",
    "port":24224
  },
  "opsworks_route53":{
    "domainname":"yourprivatedomain.local",
    "prepend_stack_name":true,
    "zone_id":"XXXXXXXXXXXXX"
  }
}

setup等のレシピ内で使用する設定で、opsworks/attributes/default.rbに含められない内容をここで設定します。

カスタムCookbook

今回は

  • Setup opsworks::setup
  • Configure opsworks::configure
  • Deploy opsworks::deploy

を使いました。

Berksfile

source 'https://supermarket.chef.io'

# (snip)

cookbook 'td-agent', '~> 2.2.0'
cookbook 'opsworks_route53', git: 'https://github.com/verdigris-cookbooks/opsworks-route53.git'

td-agentおよびopsworks_route53クックブックを使うのでその指定を追加しました。

opsworks/metadata.rb

name             'opsworks'
maintainer       'Yuichi Takeuchi'
maintainer_email 'info@takeyu-web.com'
license          'All rights reserved'
description      'Installs/Configures base'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version          '0.1.0'
depends          'td-agent'            # これと
depends          'opsworks_route53'    # これ

dependsを指定してデフォルトのattributesを読み込むようにします。

opsworks/attributes/default.rb

default[:td_agent][:plugins] = [
    'bigquery'
]
default[:td_agent][:includes] = true

fluent-plugin-bigqueryを使うのでその指定と、追加の設定を/etc/td-agent/conf.dに置く設定を追加しました。この設定についてはこのへん

opsworks/recipes/setup.rb

# (snip)

# fluentd server and client
include_recipe 'td-agent'
is_log_server = node[:opsworks][:instance][:layers].select { |layer| layer.match(/\Afluentd-server\z/) }.any?
if is_log_server
  td_agent_match 'myapp' do
    type 'bigquery'
    tag 'myapp'
    params(
        method: 'insert',
        auth_method: 'json_key',
        json_key: '/etc/td-agent/service_account.json',
        project: node[:fluentd_server][:gce_project_id],
        dataset: 'myapp',
        auto_create_table: true,
        table: 'rails_%Y%m%d',
        time_format: '%s',
        time_field: 'time',
        field_integer: 'time',
        field_string: 'messages,ip,ua,uid'
    )
  end

  file '/etc/td-agent/service_account.json' do
    action :create
    mode '0600'
    owner 'td-agent'
    group 'td-agent'
    content node[:fluentd_server][:gce_service_json]
  end
else
  td_agent_match 'myapp' do
    type 'forward'
    tag 'myapp'
    params(
        method: 'insert',
        flush_interval: '60s',
        send_timeout: '60s',
        heartbeat_type: 'udp',
        heartbeat_interval: '1s',
        server: [
            {
                host: node[:fluentd_server][:host],
                port: node[:fluentd_server][:port]
            }
        ],
        secondary: [
            {
                type: 'file',
                path: '/var/log/td-agent/forward-failed'
            }
        ]
    )
  end
end

インスタンスセットアップ時にfluentdをインストールして、インスタンスがFluentd Serverレイヤーかどうかでそれぞれサーバ向けの設定とクライアント向けの設定ファイルを作ります。

opsworks/recipes/configure.rb

# (snip)

include_recipe 'opsworks_route53'

opsworks_route53::defaultを実行するだけで、インスタンス名.スタック名.ドメイン名(例 log-server1.stackname.yourprivatedomain.local)をRoute53にAレコードを登録してくれます。便利。

opsworks/recipes/deploy.rb
# (snip)

node[:deploy].each do |application, deploy|
  next unless deploy[:application_type] == 'rails'

  template "#{deploy[:deploy_to]}/current/config/fluent-logger.yml" do
    source 'fluent-logger.yml.erb'
    action :create
    mode '0660'
    owner deploy[:user]
    group deploy[:group]
    variables(
        rails_env: deploy[:rails_env]
    )
  end
end

Railsアプリのデプロイの際に、act-fluent-logger-railsの設定を置くことにしました。

opsworks/templates/default/fluent-logger.yml.erb

<%= @rails_env %>:
  fluent_host:   '127.0.0.1'
  fluent_port:   24224
  tag: 'myapp'
  messages_type: 'string'
2
2
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
2
2