構造化ロギング

Stackdriver Logging では、構造化ログとは jsonPayload フィールドを使用してペイロードに構造を追加するログエントリを意味します。Stackdriver Logging API またはコマンドライン ユーティリティ gcloud logging を使用すると、ペイロードの構造を制御できます。Stackdriver Logging エージェントを使用してログエントリを取得する場合、Logging エージェントによってペイロードを JSON 形式に変換するように指定できます。ペイロードの形式の詳細については、LogEntry をご覧ください。

次に、ログエントリの例を示します。構造化されたペイロードは太字になっています。


        {
         insertId:  "1m9mtk4g3mwilhp"
         "jsonPayload: {
          code:  "structured-log-code"
          message:  "This is a log from the log file at test-structured-log.log"
         }
         labels: {
          compute.googleapis.com/resource_name:  "add-structured-log-resource"
         }
         logName:  "projects/my-sample-project-12345/logs/structured-log"
         receiveTimestamp:  "2018-03-21T01:53:41.118200931Z"
         resource: {
          labels: {
           instance_id:  "5351724540900470204"
           project_id:  "my-sample-project-12345"
           zone:  "us-central1-c"
          }
          type:  "gce_instance"
         }
         timestamp:  "2018-03-21T01:53:39.071920609Z"
        }

構造化ロギング オペレーション

Logging エージェント google-fluentd は、Fluentd ログデータ コレクタに変更を加えたものです。Logging エージェントにはデフォルトの Fluentd 構成があります。Logging エージェントは、Fluentd 入力プラグインを使用して外部ソース(ディスク上のファイルなど)からイベントログを pull したり、受信ログレコードを解析したりします。

Fluentd にはサポートされるパーサーのリストがあります。これらのパーサーはログを抽出し、構造化ペイロード(JSON)に変換します。

ログソースに format [PARSER_NAME] を構成することで、Fluentd が提供する組み込みのパーサーを利用できます。

次のコードサンプルは、Fluentd の構成、入力されるログレコード、出力される構造化ペイロード(Stackdriver Logging のログエントリの一部)を示しています。

  • Fluentd の構成:

      <source>
        @type tail
    
        format syslog # <--- This uses a predefined log format regex named
                      # `syslog`. See details at https://docs.fluentd.org/v1.0/articles/parser_syslog.
    
        path /var/log/syslog
        pos_file /var/lib/google-fluentd/pos/syslog.pos
        read_from_head true
        tag syslog
      </source>
    
  • ログレコード(入力):

      <6>Feb 28 12:00:00 192.168.0.1 fluentd[11111]: [error] Syslog test
    
  • 構造化ペイロード:

        jsonPayload: {
            "pri": "6",
            "host": "192.168.0.1",
            "ident": "fluentd",
            "pid": "11111",
            "message": "[error] Syslog test"
        }
    

syslog パーサーの仕組みについては、Fluentd ドキュメントをご覧ください。

デフォルトで有効になっている標準パーサー

以下の表に、構造化ロギングを有効にした場合にエージェントに追加される標準パーサーを示します。

パーサー名 構成ファイル
syslog /etc/google-fluentd/config.d/syslog.conf
nginx /etc/google-fluentd/config.d/nginx.conf
apache2 /etc/google-fluentd/config.d/apache.conf
apache_error /etc/google-fluentd/config.d/apache.conf

Logging エージェントのインストール時に構造化ロギングを有効にする方法については、以下のインストールをご覧ください。

インストール

構造化ロギングを有効にするには、Logging エージェントをインストール(または再インストール)するときに、Logging エージェントのデフォルト構成を変更する必要があります。構造化ロギングを有効にすると、エージェントの最新バージョンが取得され、以前の構成ファイルが置換されます。エージェント自体のオペレーションに変更はありません。

構造化ロギングを有効にすると、構造化ログを有効にする前と異なる形式にログエントリが変換されます。Stackdriver Logging からのログのエクスポートを開始した後でこの変更を行うと、後処理のアプリケーションに影響を及ぼす可能性があります。BigQuery のエクスポートの場合、BigQuery は変更後の新しいログエントリを不適切なスキーマとして拒否します。

構造化ロギングを有効にしてエージェントをインストールするには、次の操作を行います。

  1. SSH または同様のツールを使用して、VM インスタンスへのターミナル接続を開きます。

  2. VM インスタンスで次のコマンドを実行して、Logging エージェントのインストール スクリプトをダウンロードします。

        curl -sSO "https://dl.google.com/cloudagents/install-logging-agent.sh"
    
  3. 次のコマンドでインストール スクリプトを実行します。

        sudo bash install-logging-agent.sh --structured
    
  4. インストールに成功したことを確認するには、ログビューアでエージェントのテストログ エントリを確認します。

  5. 正常に実行されたら、インストール スクリプトを削除できます。

Logging エージェントの構成ファイル(/etc/google-fluentd/config.d/)に、デフォルトで有効になっている標準パーサーが追加されます。

詳細については、Logging エージェントのインストールをご覧ください。

Apache アクセスログの形式の構成

Logging エージェントでは、Apache アクセスログのデータはデフォルトで jsonPayload フィールドに保存されます。例:

{
  "logName": ...,
  "resource": ...,
  "httpRequest": ...,
  "jsonPayload": {
    "user"   : "some-user",
    "method" : "GET",
    "code"   : 200,
    "size"   : 777,
    "host"   : "192.168.0.1",
    "path"   : "/some-path",
    "referer": "some-referer",
    "agent"  : "Opera/12.0"
  },
  ...
}

また、特定のフィールドを httpRequest フィールドに抽出するように Logging エージェントを構成することもできます。例:

{
  "logName": ...,
  "resource": ...,
  "httpRequest": {
    "requestMethod": "GET",
    "requestUrl": "/some-path",
    "requestSize": "777",
    "status": "200",
    "userAgent": "Opera/12.0",
    "serverIp": "192.168.0.1",
    "referrer":"some-referrer",
  },
  "jsonPayload": {
    "user":"some-user"
  },
  ...
}

上記に示すように httpRequest フィールドを構成すると、トレースがしやすくなります。GCP Console では、1 つの HTTP リクエストのすべてのログが親子階層で表示されるためです。

こうした抽出を構成するには、以下を /etc/google-fluentd/config.d/apache.conf の末尾に追加します。

  <filter apache-access>
    @type record_transformer
    enable_ruby true
    <record>
      httpRequest ${ {"requestMethod" => record['method'], "requestUrl" => record['path'], "requestSize" => record['size'], "status" => record['code'], "userAgent" => record['agent'], "serverIp" => record['host'],
      "referer" => record['referer']} }
    </record>
    remove_keys method, path, size, code, agent, host, referer
  </filter>

ログエントリの構成方法については、ログレコードの変更をご覧ください。

nginx アクセスログの形式の構成

Logging エージェントでは、nginx アクセスログのデータはデフォルトで jsonPayload フィールドに保存されます。例:

  {
    "logName": ...,
    "resource": ...,
    "httpRequest": ...,
    "jsonPayload": {
      "remote":"127.0.0.1",
      "host":"192.168.0.1",
      "user":"some-user",
      "method":"GET",
      "path":"/some-path",
      "code":"200",
      "size":"777",
      "referrer":"some-referrer",
      "agent":"Opera/12.0",
      "http_x_forwarded_for":"192.168.3.3"
    },
    ...
  }

また、特定のフィールドを httpRequest フィールドに抽出するように Logging エージェントを構成することもできます。例:

  {
    "logName": ...,
    "resource": ...,
    "httpRequest": {
      "requestMethod": "GET",
      "requestUrl": "/some-path",
      "requestSize": "777",
      "status": "200",
      "userAgent": "Opera/12.0",
      "remoteIp": "127.0.0.1",
      "serverIp": "192.168.0.1",
      "referrer":"some-referrer",
    },
    "jsonPayload": {
      "user":"some-user",
      "http_x_forwarded_for":"192.168.3.3"
    },
    ...
  }

上記に示すように httpRequest フィールドを構成すると、トレースがしやすくなります。GCP Console では、1 つの HTTP リクエストのすべてのログが親子階層で表示されるためです。

こうした抽出を構成するには、以下を /etc/google-fluentd/config.d/nginx.conf の末尾に追加します。

<filter nginx-access>
  @type record_transformer
  enable_ruby true
  <record>
    httpRequest ${ {"requestMethod" => record['method'], "requestUrl" => record['path'], "requestSize" => record['size'], "status" => record['code'], "userAgent" => record['agent'], "remoteIp" => record['remote'], "serverIp" => record['host'], "referer" => record['referer']} }
  </record>
  remove_keys method, path, size, code, agent, remote, host, referer
</filter>

ログエントリの構成方法については、ログレコードの変更をご覧ください。

独自のパーサーを作成する

ログが標準パーサーでサポートされていない場合は、独自のログを作成できます。パーサーは、ログレコードの照合とラベルの適用に使用される正規表現から構成されます。

次の 3 つのサンプルコードは、ログレコードのログ行、ログ行の形式を表す正規表現を含む設定、結果のログエントリを示しています。

  • ログレコードのログ行:

    REPAIR CAR $500
    
  • ログ行の形式を表す正規表現を含む構成:

    $ sudo vim /etc/google-fluentd/config.d/test-structured-log.conf
    $ cat /etc/google-fluentd/config.d/test-structured-log.conf
    <source>
      @type tail
    
      # Format indicates the log should be translated from text to
      # structured (JSON) with three fields, "action", "thing" and "cost",
      # using the following regex:
      format /(?<action>\w+) (?<thing>\w+) \$(?<cost>\d+)/
      # The path of the log file.
      path /tmp/test-structured-log.log
      # The path of the position file that records where in the log file
      # we have processed already. This is useful when the agent
      # restarts.
      pos_file /var/lib/google-fluentd/pos/test-structured-log.pos
      read_from_head true
      # The log tag for this log input.
      tag structured-log
    </source>
    
  • 結果のログエントリ:

     {
      insertId:  "eps2n7g1hq99qp"
      jsonPayload: {
        action:  "REPAIR"
        thing:  "CAR"
        cost:  "500"
      }
      labels: {
        compute.googleapis.com/resource_name:  "add-structured-log-resource"
      }
      logName:  "projects/my-sample-project-12345/logs/structured-log"
      receiveTimestamp:  "2018-03-21T01:47:11.475065313Z"
      resource: {
        labels: {
          instance_id:  "3914079432219560274"
          project_id:  "my-sample-project-12345"
          zone:  "us-central1-c"
        }
        type:  "gce_instance"
      }
      timestamp:  "2018-03-21T01:47:05.051902169Z"
     }
    

構造化ログを表示する

ログビューアでログを検索し、ログエントリを表示する方法については、ログの表示をご覧ください。

SDK または API を使用してログエントリを読み取る方法については、ログエントリを読み取るをご覧ください。

トラブルシューティング

Logging エージェントのインストールや操作に関する一般的な問題のトラブルシューティングについては、エージェントのトラブルシューティングをご覧ください。

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

ご不明な点がありましたら、Google のサポートページをご覧ください。