概要

Datadog にログを送信する際は、Lograge を適用したファイルにログを記録し、Datadog Agent でそのファイルをテールします。Ruby でロギングのセットアップを行う際は、予約済み属性に注意してください。

Lograge を使えば、この例のように、テキストベースの標準的なログ形式を、

Started GET "/" for 127.0.0.1 at 2012-03-10 14:28:14 +0100
Processing by HomeController#index as HTML
  Rendered text template within layouts/application (0.0ms)
  Rendered layouts/_assets.html.erb (2.0ms)
  Rendered layouts/_top.html.erb (2.6ms)
  Rendered layouts/_about.html.erb (0.3ms)
  Rendered layouts/_google_analytics.html.erb (0.4ms)
Completed 200 OK in 79ms (Views: 78.8ms | ActiveRecord: 0.0ms)

より多くの構造を提供する以下の JSON 形式のログに変換することができます。

{
  "timestamp": "2016-01-12T19:15:19.118829+01:00",
  "level": "INFO",
  "logger": "Rails",
  "method": "GET",
  "path": "/jobs/833552.json",
  "format": "json",
  "controller": "jobs",
  "action": "show",
  "status": 200,
  "duration": 58.33,
  "view": 40.43,
  "db": 15.26
}

ロガーのインストールと構成

  1. プロジェクトに lograge gem を追加します。
    gem 'lograge'
    
  2. コンフィギュレーションファイルで、以下を設定し、Lograge を構成します。
    # Lograge config
    config.lograge.enabled = true
    
    # This specifies to log in JSON format
    config.lograge.formatter = Lograge::Formatters::Json.new
    
    ## Disables log coloration
    config.colorize_logging = false
    
    # Log to a dedicated file
    config.lograge.logger = ActiveSupport::Logger.new(Rails.root.join('log', "#{Rails.env}.log"))
    
    # This is useful if you want to log query parameters
    config.lograge.custom_options = lambda do |event|
        { :ddsource => 'ruby',
          :params => event.payload[:params].reject { |k| %w(controller action).include? k }
        }
    end
    
    : Lograge はコンテキスト情報をログに追加することも可能です。詳細は Lograge ドキュメントを参照してください。

この設定の詳細な例については、Rails アプリケーションのログを収集、カスタマイズ、管理する方法を参照してください。

RocketPants

Lograge を rocket_pants コントローラに構成するには、config/initializers/lograge_rocketpants.rb ファイル (場所はプロジェクトによって異なる場合があります) を作成します。

# 参照:
#   https://github.com/Sutto/rocket_pants/issues/111
app = Rails.application
if app.config.lograge.enabled
  ActiveSupport::LogSubscriber.log_subscribers.each do |subscriber|
    case subscriber
      when ActionController::LogSubscriber
        Lograge.unsubscribe(:rocket_pants, subscriber)
    end
  end
  Lograge::RequestLogSubscriber.attach_to :rocket_pants
end
  1. プロジェクトに grape_logging gem を追加します。

    gem 'grape_logging'
    
  2. 追加の構成を Grape に追加します。

    use GrapeLogging::Middleware::RequestLogger,
          instrumentation_key: 'grape',
          include: [ GrapeLogging::Loggers::Response.new,
                    GrapeLogging::Loggers::FilterParameters.new ]
    
  3. config/initializers/instrumentation.rb ファイルを作成し、次の構成を追加します。

    # Subscribe to grape request and log with a logger dedicated to Grape
    grape_logger = Logging.logger['Grape']
    ActiveSupport::Notifications.subscribe('grape') do |name, starts, ends, notification_id, payload|
        grape_logger.info payload
    end
    

Datadog Agent の構成

ログ収集が有効になったら、以下を行ってログファイルを追跡して Datadog に送信するカスタムログ収集を設定します。

  1. ruby.d/ フォルダーを conf.d/ Agent 構成ディレクトリに作成します。
  2. ruby.d/ に以下の内容で conf.yaml ファイルを作成します。
      logs:
        - type: file
          path: "<RUBY_LOG_FILE_PATH>.log"
          service: <SERVICE_NAME>
          source: ruby
          sourcecategory: sourcecode
          ## Uncomment the following processing rule for multiline logs if they
          ## start by the date with the format yyyy-mm-dd
          #log_processing_rules:
          #  - type: multi_line
          #    name: new_log_start_with_date
          #    pattern: \d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])
    
  3. Agent を再起動します
  4. Agent の status サブコマンドを実行し、Checks セクションで ruby を探し、ログが Datadog に正常に送信されることを確認します。

ログが JSON 形式の場合、Datadog は自動的にログメッセージをパースし、ログ属性を抽出します。ログエクスプローラーを使用して、ログを表示し、トラブルシューティングを行うことができます。

ログとトレースの接続

このアプリケーションで APM が有効になっている場合、APM Ruby のロギング手順に従うことでアプリケーションログとトレースの関連性を高め、ログにトレースとスパン ID を自動的に追加することが可能です。

ベストプラクティス

可能な限り、ログに追加のコンテキスト (ユーザー、セッション、アクション、メトリクス) を追加します。

単純な文字列メッセージのログの代わりに、次の例に示すようにログのハッシュを使用することができます。

my_hash = {'user' => '1234', 'button_name'=>'save','message' => 'User 1234 clicked on button saved'};
logger.info(my_hash);

ハッシュは JSON に変換され、userbutton_name の分析を実行することができます。

{
  "timestamp": "2016-01-12T19:15:18.683575+01:00",
  "level": "INFO",
  "logger": "WelcomeController",
  "message": {
    "user": "1234",
    "button_name": "save",
    "message": "User 1234 clicked on button saved"
  }
}

その他の参考資料