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