Logstashの動的テンプレートマッピングでNginxのJSON形式ログを収集する

LogstashからESへ送信されたデータは、自動的に「5シャード・5レプリカ」のインデックスとして作成され、すべてのフィールドがtext型にマッピングされます。この状態では、基本的にデータ分析を行うことはできません。

そこで、Logstashのデータをあらかじめ定義した形式でESに格納する必要があります。このときに利用するのがESのテンプレート機能です。ESではカスタムテンプレートと動的テンプレートを定義でき、以降、対象のインデックスは自動的にテンプレートで定義された形式へマッピングされます。

動的マッピングテンプレートファイル「nginx-json.template」を作成する

JSONログ中のキーの位置が固定されていない場合や、フィールド数が不明な場合は、動的マッピングテンプレートを使用します。

{
  "template": "nginx-json-log*",
  "settings": {
    "index.number_of_shards": 5,
    "index.number_of_replicas": 1
  },
  "mappings": {
    "_default_": {
      "_all": {
        "enabled": true,
        "omit_norms": true
      },
      "dynamic_templates": [
        {
          "message_field": {
            "match": "message",
            "match_mapping_type": "string",
            "mapping": {
              "type": "string",
              "index": "analyzed",
              "omit_norms": true,
              "fielddata": {
                "format": "disabled"
              }
            }
          }
        },
        {
          "string_fields": {
            "match": "*",
            "match_mapping_type": "string",
            "mapping": {
              "type": "string",
              "index": "not_analyzed",
              "doc_values": true
            }
          }
        }
      ],
      "properties": {
        "@timestamp": {
          "type": "date"
        },
        "@version": {
          "type": "string",
          "index": "not_analyzed"
        }
      }
    }
  }
}

dynamic_templates は、具体的な動的テンプレートのマッチング条件を定義する部分です。

  • match_mapping_type: "string" は、対象フィールドの型が文字列(string)であるデータにマッチします。
  • match: "time" は、フィールド名が time のデータにマッチします。
  • unmatch: "data" は、フィールド名が data のデータをマッチ対象から除外します。
  • mapping は、マッチしたデータを定義したデータ型へマッピングします。

Logstash設定ファイル「logstash-nginx.conf」

input {
  file {
    path => "/var/log/nginx/user_access.log"
    type => "nginx-json-log"
    codec => "json"
  }
}

filter {
  if [type] == "nginx-json-log" {
    json {
      source => "app_data"
    }
  }
}

output {
  if [type] == "nginx-json-log" {
    elasticsearch {
      hosts              => ["192.0.2.10:9200", "192.0.2.11:9200"]
      index              => "nginx-json-log"
      manage_template    => true
      template_overwrite => true
      template_name      => "nginx-json-template"
      template           => "/etc/logstash/templates/nginx-json.template"
      document_type      => "nginx_json_log"
    }
  }
}

Nginx設定ファイルでのJSONログフォーマット変換設定(必要なフィールドの範囲のみ抜粋)

escape=json は、nginx 1.11.8以降のバージョンで利用可能なパラメータです。

log_format user_log escape=json '{"app_data":"$app_data","@timestamp":"$time_iso8601"}';
...
access_log /var/log/nginx/user_access.log user_log;

生成されるログの例:

{"app_data":"{\"appid\":\"sample-app\",\"args\":{\"contentId\":0,\"duration\":111811,\"parentId\":0,\"totaltime\":0,\"type\":0},\"bk\":\"-\",\"cp_ver\":\"3.0.5\",\"duid\":\"2cba98f8ddc18464\",\"e\":\"sample.main.stay-duration\",\"os\":\"A\",\"ts\":1572584611,\"ver\":\"8.11.11\"}","@timestamp":"2019-11-01T06:23:31Z"}

Kibana上では、Logstashのjsonフィルターによってパースされた各フィールドとして確認できます。

よく使用されるログフォーマットの例は以下のとおりです。

log_format json_main escape=json
    '{"remote_addr":"$remote_addr",'
    '"time_local":"$time_local",'
    '"request_method":"$request_method",'
    '"request_uri":"$uri",'
    '"query_string":"$query_string",'
    '"status":"$status",'
    '"http_referer":"$http_referer",'
    '"http_user_agent":"$http_user_agent",'
    '"request_time":"$request_time",'
    '"upstream_response_time":"$upstream_response_time"}';

参考資料:https://doc.yonyoucloud.com/doc/logstash-best-practice-cn/filter/json.html

タグ: Logstash Elasticsearch nginx dynamic-templates json-log

9月8日 14:28 投稿