Fluentd と BigQuery を使用したリアルタイムのログ分析

このチュートリアルでは、ブラウザ トラフィックをリアルタイムでロギングし、分析する方法について説明します。この機能は、さまざまなソースから大量のログを取得している場合に役立ちます。また、問題のデバッグや、ログから最新の統計情報を生成する場合にも役立ちます。

このチュートリアルでは、NGINX ウェブサーバーから生成されたログ情報を Fluentd で BigQuery に送信し、BigQuery でログ情報を分析する方法について説明します。以下の説明では、Google Cloud、Linux コマンドライン、アプリケーション ログの収集、ログの分析について基本的な知識があることを前提としています。

概要

ログは、大規模なシステムやアプリケーションがどのように動作しているかを調べることができる強力なツールです。しかし、システムの規模や複雑さが増すにつれて、さまざまなコンピューティング リソースに分散しているログを管理することが課題の 1 つとなっています。

Fluentd はよく使われているオープンソースのログ収集ツールの 1 つで、多くのデータソースやシステムからログを収集し、統一されたロギング レイヤーに統合することを目的としています。分析に役立つデータかどうかを事前に知ることは難しいため、すべてのデータをログに記録してから分類していくのが一般的なアプローチです。しかし、すべてのデータを収集して分類するのは容易な作業ではなく、時間もかかります。また、必要な情報が得られないことも少なくありません。

このようなログ分析に役立つのが BigQuery です。BigQuery は、Google が提供するフルマネージドのクラウドデータ ウェアハウスです。分析エンジンを搭載し、優れたスケーラビリティを提供します。テラバイト単位のログでも数十秒でクエリを実行できます。このパフォーマンスにより、システムの修正や向上に必要な情報をすばやく得ることができます。

デフォルトでは、1 秒あたり 100,000 行のログデータを BigQuery に送信できます。この上限は、割り当ての追加をリクエストすることで変更できます。

Fluentd の出力プラグインでは、収集したログの保管先として BigQuery を設定できます。このプラグインを使用すると、ほぼリアルタイムで複数のサーバーから BigQuery に直接ログを読み込むことができます。また、Google スプレッドシートまたは Google データポータル内で頻繁に更新されるダッシュボードを作成することで、このデータを簡単に可視化できます。

目標

  • Compute Engine インスタンスで NGINX ウェブサーバーを実行する。
  • Fluentd ログ収集エージェントをインストールする。
  • 次の処理を行うように Fluentd を構成する。
    • NGINX トラフィック ログを収集する。
    • ログを BigQuery に転送する。
  • BigQuery ウェブ UI を使用して、ログメッセージをクエリで取得する。
  • BigQuery を使用して、ログに分析クエリを実行する。

費用

このチュートリアルでは、Google Cloud の課金対象となる以下のコンポーネントを使用します。

  • Compute Engine
  • BigQuery

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. GCP Console のプロジェクト セレクタのページで、GCP プロジェクトを選択または作成します。

    プロジェクト セレクタのページに移動

  3. Google Cloud Platform プロジェクトに対して課金が有効になっていることを確認します。 プロジェクトに対して課金が有効になっていることを確認する方法を学習する

このチュートリアルを終了した後、作成したリソースを削除すれば、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

NGINX ウェブサーバー VM を作成する

このチュートリアルでは、Google Cloud Marketplace を使用して、Compute Engine インスタンスを作成し、NGINX ウェブサーバーを実行するように構成します。

  1. Cloud Console の Marketplace を表示し、Nginx(Google クリック デプロイ)イメージの詳細ページに移動します。

    NGINX の詳細ページに移動

  2. [COMPUTE ENGINE 上で起動] をクリックします。

  3. プロンプトが表示されたら、使用する Google Cloud プロジェクトを選択します。

  4. 必要な API が有効になるまで待ちます。

  5. デプロイメントに nginx という名前を付けます。

  6. 米国またはヨーロッパのリージョン内のゾーンを選択します。

  7. [ネットワーキング] セクションの [ファイアウォール] で、[HTTP トラフィックを許可する] オプションが選択されていることを確認します。

  8. [利用規約] にある利用規約を読みます。

  9. 利用規約に同意する場合は、[デプロイ] をクリックします。

    デプロイの詳細画面に、指定したゾーンに作成中の新しい VM とインストール中の NGINX ウェブサーバーが表示されます。

  10. デプロイが完了したら操作を続行します。

権限を追加する

BigQuery に書き込みを行うため、仮想マシンに追加の権限を割り当てる必要があります。VM の権限を変更する前に、VM をシャットダウンする必要があります。

  1. Cloud Console で、Compute Engine VM インスタンスのページに移動します。

    [VM インスタンス] ページに移動

    nginx-vm という新しい VM インスタンスが表示されます。

  2. VM の詳細ページを開くには、VM 名をクリックします。

  3. ページの上部にある [停止] ボタンをクリックします。

    VM がシャットダウンするまでにしばらく時間がかかります。

  4. ページ上部の [編集] をクリックします。

  5. 下にスクロールし、BigQuery へのアクセス権を [有効] に変更します。

  6. ページの下部にある [保存] をクリックします。

  7. ページの上部にある [開始] をクリックして、新しい権限で VM を再起動します。

このページはまだ閉じないでください。次のセクションで引き続き使用します。

Fluentd と BigQuery コネクタをインストールする

このセクションでは、VM に Fluentd ログコレクタと BigQuery 用 Fluentd 出力プラグインをインストールします。

  1. VM インスタンスの詳細ページで、SSH ボタンをクリックし、インスタンスとの接続を開きます。
  2. VM のシェル ウィンドウで、Debian のバージョンを確認します。

    lsb_release -rdc
    

    VM で実行されている Debian のバージョンとコードネームが表示されます。

    Description:    Debian GNU/Linux 9.6 (stretch)
    Release:        9.6
    Codename:       stretch
    
  3. Debian 用 Fluentd のダウンロード ページに移動して、Debian のコードネームとバージョンに対応するインストール コマンドラインを探します。

    たとえば、Debian Stretch の場合は次のコマンドを探します。

    curl -L
       https://toolbelt.treasuredata.com/sh/install-debian-stretch-td-agent3.sh
       | sh
    
  4. VM のシェル ウィンドウにコマンドをコピーします。

    このコマンドにより、VM に td-agent パッケージがインストールされます。このパッケージに Fluentd ディストリビューションが含まれています。

  5. Fluentd-to-BigQuery プラグインをインストールします。

    sudo /usr/sbin/td-agent-gem install fluent-plugin-bigquery
    

ログを保存する BigQuery データセットとテーブルを作成する

Fluentd は、入力プラグインを使用して、他のアプリケーションとサービスが生成したログを収集します。このデータを解析して JSON 構造化レコードに変換し、構成済みの出力プラグインに転送します。

Fluentd NGINX アクセスログ パーサーは NGINX access.log ファイルを読み込みます。以下に、フィールドとサンプル値を含むレコードの例を示します。

time: 1362020400
record:
{
  "remote"              : "127.0.0.1",
  "host"                : "192.168.0.1",
  "user"                : "-",
  "method"              : "GET",
  "path"                : "/",
  "code"                : "200",
  "size"                : "777",
  "referer"             : "-",
  "agent"               : "Opera/12.0",
  "http_x_forwarded_for": "-"
}

BigQuery でログの宛先テーブルを作成するときに、ログレコードのフィールド名を列名にする必要があります。正しいテーブル列名が設定されるように、以下の手順では指定された名前をそのまま使用してください。

  1. BigQuery ウェブ UI を開きます。

    BigQuery ウェブ UI に移動

  2. ナビゲーション パネルの [リソース] で、プロジェクト名をクリックします。

  3. クエリエディタの下の詳細パネルで、[データセットを作成] をクリックします。

  4. [データセット ID] に fluentd を入力します。

  5. [データのロケーション] で、NGINX インスタンスの作成場所としてマルチリージョン ロケーション(US または Europe)を選択します。

  6. [データセットを作成] をクリックします。

  7. ナビゲーション パネルの [リソース] で、fluentd データセットをクリックします。

  8. クエリエディタの下の詳細パネルで、[テーブルを作成] をクリックします。

  9. テーブル名に nginx_access を入力します。

  10. [テキストとして編集] オプションを選択します。

  11. テキスト ボックスに次の JSON 列定義をコピーします。

    [  { "type": "TIMESTAMP", "name": "time" },
       { "type": "STRING",    "name": "remote" },
       { "type": "STRING",    "name": "host" },
       { "type": "STRING",    "name": "user" },
       { "type": "STRING",    "name": "method" },
       { "type": "STRING",    "name": "path" },
       { "type": "STRING",    "name": "code" },
       { "type": "INTEGER",   "name": "size" },
       { "type": "STRING",    "name": "referer" },
       { "type": "STRING",    "name": "agent" },
       { "type": "STRING",    "name": "http_x_forwarded_for" } ]
    

    Fluentd ログレコードのフィールド名と列名が一致していることに注意してください。ログレコードのタイムスタンプが BigQuery 対応のタイムスタンプ文字列に変換されるときに、time 列の値がレコードに追加されます。

  12. [パーティショニング] リストで [フィールドにより分割: time] を選択します。

    パーティショニング分割テーブルは、サイズの大きいテーブルを小さなセグメントに分割したテーブルで、クエリのパフォーマンスが向上します。また、クエリで読み込まれるデータ量を少なくすることで、コストを制御できます。詳細については、BigQuery ドキュメントのパーティション分割テーブルの概要をご覧ください。

  13. 下にある [テーブルを作成] をクリックします。

    これで、fluentd.nginx_access という名前の BigQuery テーブルにログレコードが記録されます。

  14. テーブルの詳細を確認するには、[リソース] > [詳細] の順に移動し、テーブル名をクリックします。

    テーブルの行数、テーブルが使用しているストレージの量などの情報が表示されます。

ログの収集と BigQuery への転送を設定する

Fluentd 構成ファイル /etc/td-agent/td-agent.conf に、ログデータの収集元、収集したログの出力、フィルタを定義します。また、収集したログにタグを適用し、ログの処理方法や転送先の出力プラグインを定義できます。

以下では、Fluentd を次のように構成します。

ログの収集と転送を設定するには:

  1. SSH を使用して、NGINX がインストールされている VM に接続します。
  2. シェル ウィンドウを開き、root ユーザーの権限でテキスト エディタ(Vim、Nano など)を開きます。Fluentd エージェントの構成ファイル /etc/td-agent/td-agent.conf を編集します。たとえば、Vim でファイルを開く場合は次のコマンドを使用します。

    sudo vim /etc/td-agent/td-agent.conf
    
  3. ファイルの最後に次の行を追加します。これにより、tail 入力プラグインが NGINX ログを読み込み、NGINX パーサーで分析を行い、ログに nginx.access というタグを設定します。

    <source>
      @type tail
      @id input_tail
      <parse>
        @type nginx
      </parse>
      path /var/log/nginx/access.log
      pos_file /var/log/td-agent/httpd-access.log.pos
      tag nginx.access
    </source>
    
  4. 次の行を追加し、BigQuery 出力プラグインを構成します。[MY_PROJECT_NAME] は、Google Cloud プロジェクトの名前で置き換えます。

    <match nginx.access>
      @type bigquery_insert
    
      # Authenticate with BigQuery using the VM's service account.
      auth_method compute_engine
      project [MY_PROJECT_NAME]
      dataset fluentd
      table nginx_access
      fetch_schema true
    
      <inject>
        # Convert fluentd timestamp into TIMESTAMP string
        time_key time
        time_type string
        time_format %Y-%m-%dT%H:%M:%S.%NZ
      </inject>
    </match>
    

    これにより、Fluentd は次の処理を行います。

    • nginx.access タグ付きのログエントリごとに、Fluentd は bigquery_insert プラグインを使用してレコードを BigQuery テーブルに書き込みます。
    • VM のサービス アカウントを使用して認証が行われます。
    • 元のタイムスタンプが BigQuery 対応の文字列形式でレコードに追加されます。
  5. ファイルを保存してエディタを終了します。

  6. Fluentd エージェントを再起動して、新しい構成を適用します。

    sudo systemctl restart td-agent
    

別の認証方法など、構成ファイルのパラメータの詳細については、BigQuery Fluentd プラグイン サイトFluentd プラグインのドキュメントをご覧ください。

BigQuery でログを表示する

Fluentd の構成が終わったので、NGINX ログデータを生成して BigQuery で表示してみましょう。

  1. Cloud Console で、Compute Engine VM インスタンスのページに移動します。

    [VM インスタンス] ページに移動

  2. nginx-vm VM インスタンスの外部 IP アドレスをコピーします。

  3. ブラウザで別のタブを開き、アドレス ボックスに IP アドレスを貼り付けます。

    デフォルトの Welcome to nginx! ページが表示されます。

  4. Cloud Console で、BigQuery ページに移動します。

  5. 次のクエリを [クエリエディタ] ペインにコピーし、[実行] をクリックします。

    SELECT * FROM `fluentd.nginx_access`
    

    [クエリ結果] パネルの行に、ブラウザのアクセスログ レコードが表示されます。VM はインターネットからアクセスできるので、他のリモートホストのアクセスログの行も表示される場合があります。

読み込みをシミュレーションしてログから統計情報を計算する

このセクションでは、サンプルの読み込みを実行し、BigQuery に読み込みの指標を表示します。この操作を行うと、BigQuery でログを読み取るだけでなく、分析も可能になります。

  1. Cloud Console で、Cloud Shell を起動します。
  2. ApacheBenchab)ウェブサーバー ベンチマーク ツールと関連ツールをインストールします。

     sudo apt install -y apache2-utils
    
  3. Cloud Shell でテスト用の読み込みを生成し、NGINX サーバーに実行します。[IP_ADDRESS] は、VM の IP アドレスで置き換えます。

    ab -t 20 -c 1 http://[IP_ADDRESS]/
    

    ApacheBench ツールを使用して、NGINX サーバーに 20 秒の読み込みを実行します。

  4. Cloud Console で BigQuery ページに移動します。

    BigQuery ページに移動

  5. [クエリエディタ] ペインで次のクエリを実行し、ApacheBench リクエストの一覧を取得します。

    SELECT * FROM `fluentd.nginx_access` limit 100
    
  6. 次の SQL コマンドを実行し、1 秒あたりのレスポンス コードに対するリクエスト数を計算します。

    SELECT
      time_sec, code, COUNT(*) as count
    FROM (
      SELECT
        TIMESTAMP_TRUNC(time, SECOND)AS time_sec, code
      FROM
        `fluentd.nginx_access`)
    GROUP BY
      time_sec, code
    ORDER BY
      time_sec DESC
    

    1 秒あたりの値は、前に表示した ApacheBench 出力の Requests per second 行とほぼ同じになります。

省略可: 大量のログを一括で読み込む

前述のように、このチュートリアルでは BigQuery のストリーミング入力を使用し、データを数秒以内で取得しています。この方法では若干の料金が発生し、挿入のサイズと頻度に上限があります。

ログデータが大量にある場合は、BigQuery のバッチ読み込みを使用します。その名前のとおり、この機能では優先度の低いバッチ処理でデータを読み込みます。バッチ読み込みの場合、ストリーミング挿入よりもデータが使用可能になるまでに時間がかかります。ただし、バッチ読み込みでは料金が発生しません。

ストリーミング挿入と同様に、バッチ読み込みジョブの頻度には上限があります。1 日のテーブルあたりの読み込みジョブは 1,000 件まで、1 日のプロジェクトあたりの読み込みジョブは 50,000 件に制限されています。

バッチ読み込みを実装するには、bigquery_load Fluentd プラグインを使用します。このプラグインは、所定の上限またはサイズになるまで Fluentd バッファにファイル内のログを格納し、これらのログをまとめて BigQuery に送信します。

バッチ読み込みを使用するには、次の操作を行います。

  1. root ユーザーで Fluentd 構成ファイル /etc/td-agent/td-agent.conf を編集します。
  2. 前に指定した BigQuery 出力プラグインの構成を次の行で置き換えます。[MY_PROJECT_NAME] は、Google Cloud プロジェクトの名前で置き換えます。

    <match nginx.access>
      @type bigquery_load
    
      <buffer>
        @type file
        path /var/log/bigquery_nginx_access.*.buffer
        flush_at_shutdown true
        timekey_use_utc
        total_limit_size 1g
        flush_interval 3600
      </buffer>
    
      # Authenticate with BigQuery using the VM's service account.
      auth_method compute_engine
      project [MY_PROJECT_NAME]
      dataset fluentd
      table nginx_access
      fetch_schema true
    
      <inject>
        # Convert fluentd timestamp into TIMESTAMP string
        time_key time
        time_type string
        time_format %Y-%m-%dT%H:%M:%S.%NZ
      </inject>
    </match>
    

    この構成により、bigquery_insert プラグインではなく bigquery_load 出力プラグインが使用されます。

    buffer セクションで、1 GB のログが収集されるか、1 時間が経過するまでログデータを VM のバッファに保存することを指定します。この条件を満たすと、バッファ内のデータが BigQuery に読み込まれます。構成パラメータの詳細については、プラグインのドキュメントをご覧ください。

トラブルシューティング

エージェントがログを収集または送信していない可能性がある場合は、Fluentd VM のシェル ウィンドウから次のコマンドを実行して状態を確認できます。

sudo systemctl status td-agent

サービスの状態とそのサービスから取得したログの最後の数行が表示されます。

Active: active (running) since [DATE]

エージェントが開始していない場合、Fluentd 構成ファイルにエラーがある可能性があります。このエラーは Fluentd のログファイルに記録されます。このファイルを参照するには、VM シェル ウィンドウで次のコマンドを使用します。

sudo less /var/log/td-agent/td-agent.log

たとえば、次の出力はプラグイン名が正しくないことを示しています。

[info]: parsing config file is succeeded path="/etc/td-agent/td-agent.conf"
[error]: config error file="/etc/td-agent/td-agent.conf" error_class=Fluent::ConfigError error="Unknown output plugin 'bad_plugin'. Run 'gem search -rd fluent-plugin' to find plugins"

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

  1. GCP Console で [リソースの管理] ページに移動します。

    [リソースの管理] ページに移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ