メインコンテンツまでスキップ
Sumo Logic Japanese

Fastly のログの収集

このページでは、Fastly アプリケーションのログ収集をセットアップする手順を説明します。  

ステップ 1: Collector および Source の設定

このステップでは、Fastly ログを受信するために Collector および Source を設定します。 

  1. Sumo Logic の Hosted Collector を Sumo Logic 組織に追加します。
  2. Fastly リクエスト ログ用に HTTP Source を設定します。HTTP Source を設定するときに、必ず Source Category を設定してください。例: fastly。Source に割り当てる Source Category を書き留めます。この Source Category 値は、Fastly アプリケーションをインストールするときに指定します。

ステップ 2.CDN ログ用の Fastly でのエンドポイントの設定

このステップでは、Fastly サービス用のログ エンドポイントとして Sumo Logic を追加し、CDN ログを受信するように設定します。このプロセスについては、Fastly ヘルプの「Adding Sumo Logic as a logging endpoint (ログ エンドポイントとしての Sumo Logic の追加)」で説明しています。

CDN および Request WAF ログを収集する場合は、下記の「WAF リクエスト ログの収集」を参照してください。

Fastly による Sumo Logic エンドポイントの作成

Fastly で
Sumo Logic エンドポイントを設定するとき:

  1. Name (名前): 接続の名前を入力します。たとえば、“Prod Fastly” です。
  2. Log format (ログ形式)。次の形式文字列を使用します。これによって、必要な JSON 出力が生成されます。

{
 "service_id":"%{req.service_id}V",
 "service_version":"%{fastly_info.version}V",
 "time_start":"%{begin:%Y-%m-%dT%H:%M:%S%Z}t",
 "time_end":"%{end:%Y-%m-%dT%H:%M:%S%Z}t",
 "time_elapsed":%{time.elapsed.usec}V,
 "client_ip":"%{req.http.Fastly-Client-IP}V",
 "request":"%{req.request}V",
 "protocol":"%{req.proto}V",
 "host":"%{req.http.Fastly-Orig-Host}V",
 "origin_host":"%{req.http.Host}V",
 "url":"%{cstr_escape(req.url)}V",
 "is_ipv6":%{if(req.is_ipv6, "true", "false")}V,
 "is_tls":%{if(req.is_ssl, "true", "false")}V,
 "tls_client_protocol":"%{cstr_escape(tls.client.protocol)}V",
 "tls_client_servername":"%{cstr_escape(tls.client.servername)}V",
 "tls_client_cipher":"%{cstr_escape(tls.client.cipher)}V",
 "tls_client_cipher_sha":"%{cstr_escape(tls.client.ciphers_sha )}V",
 "tls_client_tlsexts_sha":"%{cstr_escape(tls.client.tlsexts_sha)}V",
 "is_h2":%{if(fastly_info.is_h2, "true", "false")}V,
 "is_h2_push":%{if(fastly_info.h2.is_push, "true", "false")}V,
 "h2_stream_id":"%{fastly_info.h2.stream_id}V",
 "request_referer":"%{cstr_escape(req.http.Referer)}V",
 "request_user_agent":"%{cstr_escape(req.http.User-Agent)}V",
 "request_accept_content":"%{cstr_escape(req.http.Accept)}V",
 "request_accept_language":"%{cstr_escape(req.http.Accept-Language)}V",
 "request_accept_encoding":"%{cstr_escape(req.http.Accept-Encoding)}V",
 "request_accept_charset":"%{cstr_escape(req.http.Accept-Charset)}V",
 "request_connection":"%{cstr_escape(req.http.Connection)}V",
 "request_dnt":"%{cstr_escape(req.http.DNT)}V",
 "request_forwarded":"%{cstr_escape(req.http.Forwarded)}V",
 "request_via":"%{cstr_escape(req.http.Via)}V",
 "request_cache_control":"%{cstr_escape(req.http.Cache-Control)}V",
 "request_x_requested_with":"%{cstr_escape(req.http.X-Requested-With)}V",
 "request_x_forwarded_for":"%{cstr_escape(req.http.X-Forwarded-For)}V",
 "status":"%{resp.status}V",
 "content_type":"%{cstr_escape(resp.http.Content-Type)}V",
 "cache_status":"%{regsub(fastly_info.state, "^(HIT-(SYNTH)|(HITPASS|HIT|MISS|PASS|ERROR|PIPE)).*", "\\2\\3")}V",
 "is_cacheable":%{if(fastly_info.state ~"^(HIT|MISS)$", "true", "false")}V,
 "response_age":"%{cstr_escape(resp.http.Age)}V",
 "response_cache_control":"%{cstr_escape(resp.http.Cache-Control)}V",
 "response_expires":"%{cstr_escape(resp.http.Expires)}V",
 "response_last_modified":"%{cstr_escape(resp.http.Last-Modified)}V",
 "response_tsv":"%{cstr_escape(resp.http.TSV)}V",
 "geo_datacenter":"%{server.datacenter}V",
 "geo_city":"%{geoip.city}V",
 "geo_country_code":"%{geoip.country_code}V",
 "geo_continent_code":"%{geoip.continent_code}V",
 "geo_region":"%{geoip.region}V",
 "req_header_size":%{req.header_bytes_read}V,
 "req_body_size":%{req.body_bytes_read}V,
 "resp_header_size":%{resp.header_bytes_written}V,
 "resp_body_size":%{resp.body_bytes_written}V,
 "socket_cwnd":%{client.socket.cwnd}V,
 "socket_nexthop":"%{client.socket.nexthop}V",
 "socket_tcpi_rcv_mss":%{client.socket.tcpi_rcv_mss}V,
 "socket_tcpi_snd_mss":%{client.socket.tcpi_snd_mss}V,
 "socket_tcpi_rtt":%{client.socket.tcpi_rtt}V,
 "socket_tcpi_rttvar":%{client.socket.tcpi_rttvar}V,
 "socket_tcpi_rcv_rtt":%{client.socket.tcpi_rcv_rtt}V,
 "socket_tcpi_rcv_space":%{client.socket.tcpi_rcv_space}V,
 "socket_tcpi_last_data_sent":%{client.socket.tcpi_last_data_sent}V,
 "socket_tcpi_total_retrans":%{client.socket.tcpi_total_retrans}V,
 "socket_tcpi_delta_retrans":%{client.socket.tcpi_delta_retrans}V,
 "socket_ploss":%{client.socket.ploss}V
}
  1. Collector URL (Collector URL)。上記のステップ 1 で作成した HTTP Source の URL を入力します。
  2. [Advanced options (詳細オプション)] をクリックします。
    fastly-log-format.png
  3. デフォルトでは、ログ行の形式は [Classic (クラシック)] に設定されます。[Blank (空白)] に変更します。
  4. [Create (作成)] ボタンをクリックして、新しいログ エンドポイントを作成します。
  5. [Activate (アクティブ化)] ボタンをクリックして、設定をデプロイします。 

ステップ 3: WAF リクエスト ログの収集

Fastly の Web アプリケーション ファイアウォール (WAF) がある場合は、以下のステップを実行して、上記のステップ 2 で作成したエンドポイントの設定を更新します。WAF リクエスト ログおよび CDN ログを受信するようにエンドポイントを更新します。 

  1. 「CDN ログ用の Fastly でのエンドポイントの設定」で指定したオブジェクトではなく、下記の JSON オブジェクトを [Log format (ログ形式)] フィールドに使用します



{"service_id":"%{req.service_id}V","service_version":"%{fastly_info.version}V","time_start":"%{begin:%Y-%m-%dT%H:%M:%S%Z}t","time_end":"%{end:%Y-%m-%dT%H:%M:%S%Z}t","time_elapsed":%{time.elapsed.usec}V,"client_ip":"%{req.http.Fastly-Client-IP}V","request":"%{req.request}V","protocol":"%{req.proto}V","host":"%{req.http.Fastly-Orig-Host}V","origin_host":"%{req.http.Host}V","url":"%{cstr_escape(req.url)}V","is_ipv6":%{if(req.is_ipv6,"true","false")}V,"is_tls":%{if(req.is_ssl,"true","false")}V,"tls_client_protocol":"%{cstr_escape(tls.client.protocol)}V","tls_client_servername":"%{cstr_escape(tls.client.servername)}V","tls_client_cipher":"%{cstr_escape(tls.client.cipher)}V","tls_client_cipher_sha":"%{cstr_escape(tls.client.ciphers_sha)}V","tls_client_tlsexts_sha":"%{cstr_escape(tls.client.tlsexts_sha)}V","is_h2":%{if(fastly_info.is_h2,"true","false")}V,"is_h2_push":%{if(fastly_info.h2.is_push,"true","false")}V,"h2_stream_id":"%{fastly_info.h2.stream_id}V","request_referer":"%{cstr_escape(req.http.Referer)}V","request_user_agent":"%{cstr_escape(req.http.User-Agent)}V","request_accept_content":"%{cstr_escape(req.http.Accept)}V","request_accept_language":"%{cstr_escape(req.http.Accept-Language)}V","request_accept_encoding":"%{cstr_escape(req.http.Accept-Encoding)}V","request_accept_charset":"%{cstr_escape(req.http.Accept-Charset)}V","request_connection":"%{cstr_escape(req.http.Connection)}V","request_dnt":"%{cstr_escape(req.http.DNT)}V","request_forwarded":"%{cstr_escape(req.http.Forwarded)}V","request_via":"%{cstr_escape(req.http.Via)}V","request_cache_control":"%{cstr_escape(req.http.Cache-Control)}V","request_x_requested_with":"%{cstr_escape(req.http.X-Requested-With)}V","request_x_forwarded_for":"%{cstr_escape(req.http.X-Forwarded-For)}V","status":"%{resp.status}V","content_type":"%{cstr_escape(resp.http.Content-Type)}V","cache_status":"%{regsub(fastly_info.state,"^(HIT-(SYNTH)|(HITPASS|HIT|MISS|PASS|ERROR|PIPE)).*","\\2\\3")}V","is_cacheable":%{if(fastly_info.state~"^(HIT|MISS)$","true","false")}V,"response_age":"%{cstr_escape(resp.http.Age)}V","response_cache_control":"%{cstr_escape(resp.http.Cache-Control)}V","response_expires":"%{cstr_escape(resp.http.Expires)}V","response_last_modified":"%{cstr_escape(resp.http.Last-Modified)}V","response_tsv":"%{cstr_escape(resp.http.TSV)}V","geo_datacenter":"%{server.datacenter}V","geo_city":"%{geoip.city}V","geo_country_code":"%{geoip.country_code}V","geo_continent_code":"%{geoip.continent_code}V","geo_region":"%{geoip.region}V","req_header_size":%{req.header_bytes_read}V,"req_body_size":%{req.body_bytes_read}V,"resp_header_size":%{resp.header_bytes_written}V,"resp_body_size":%{resp.body_bytes_written}V,"socket_cwnd":%{client.socket.cwnd}V,"socket_nexthop":"%{client.socket.nexthop}V","socket_tcpi_rcv_mss":%{client.socket.tcpi_rcv_mss}V,"socket_tcpi_snd_mss":%{client.socket.tcpi_snd_mss}V,"socket_tcpi_rtt":%{client.socket.tcpi_rtt}V,"socket_tcpi_rttvar":%{client.socket.tcpi_rttvar}V,"socket_tcpi_rcv_rtt":%{client.socket.tcpi_rcv_rtt}V,"socket_tcpi_rcv_space":%{client.socket.tcpi_rcv_space}V,"socket_tcpi_last_data_sent":%{client.socket.tcpi_last_data_sent}V,"socket_tcpi_total_retrans":%{client.socket.tcpi_total_retrans}V,"socket_tcpi_delta_retrans":%{client.socket.tcpi_delta_retrans}V,"socket_ploss":%{client.socket.ploss}V,"type":"request_logs","request_id":"%{req.http.x-request-id}V","waf_logged":"%{waf.logged}V","waf_block":"%{waf.blocked}V","waf_failures":"%{waf.failures}V","waf_rule_id":"%{waf.rule_id}V","waf_severity":"%{waf.severity}V","waf_passed":"%{waf.passed}V","waf_logdata":"%{cstr_escape(waf.logdata)}V","waf_executed":"%{waf.executed}V","waf_anomaly_score":"%{waf.anomaly_score}V","waf_sql_score":"%{waf.sql_injection_score}V","waf_rfi_score":"%{waf.rfi_score}V","waf_lfi_score":"%{waf.lfi_score}V","waf_xss_score":"%{waf.xss_score}V","waf_http_score":"%{waf.http_violation_score}V","waf_php_score":"%{waf.php_injection_score}V","waf_rce_score":"%{waf.rce_score}V","waf_session_fixation_score":"%{waf.session_fixation_score}V","waf_message":"%{cstr_escape(waf.message)}V"}
  1. Fastly ヘルプの「waf_debug_log」で説明しているように、curl を使用してログ エンドポイントで waf_debug_log サブルーティンを参照します。
  2. 1 つのリクエストをトラッキングするために request_id ヘッダを作成します。

ステップ 4: WAF デバッグ ログの収集

Fastly の Web アプリケーション ファイアウォール (WAF) がある場合は、Fastly で次のステップを実行してもう 1 つのログ エンドポイントを追加し、WAF リクエストを Sumo Logic に送信するように設定します。 

  1. デバッグ ログ用にもう 1 つの HTTP Source を設定し、その Source Category を設定します。たとえば、fastly/debug です。Source に割り当てる Source Category を書き留めます。この Source Category 値は、Fastly アプリケーションをインストールするときに指定します。
  2. ステップ 2 の手順に従って Fastly でもう 1 つログ エンドポイントを作成しますが、下記の JSON を [Log format (ログ形式)] フィールドに入力します。



{"type":"debug_logs",
"service_id":"%{req.service_id}V",
"client_ip":"%{req.http.Fastly-Client-IP}V",
"request":"%{req.request}V",
"protocol":"%{req.proto}V",
"origin_host":"%{req.http.Host}V",
"url":"%{cstr_escape(req.url)}V",
"request_referer":"%{cstr_escape(req.http.Referer)}V", "request_user_agent":"%{cstr_escape(req.http.User-Agent)}V", "request_accept_content":"%{cstr_escape(req.http.Accept)}V",
"cache_status": "%{regsub(fastly_info.state, \"^(HIT-(SYNTH)|(HITPASS|HIT|MISS|PASS|ERROR|PIPE|NONE)).*\", \"\\2\\3\")}V", "geo_datacenter":"%{server.datacenter}V",
"geo_city":"%{geoip.city}V",
"geo_country_code":"%{geoip.country_code}V",
"geo_continent_code":
"%{geoip.continent_code}V",
"geo_region":"%{geoip.region}V",
"request_id":"%{req.http.x-request-id}V",
"waf_logged":"%{waf.logged}V",
"waf_block":"%{waf.blocked}V",
"waf_failures":"%{waf.failures}V",
"waf_rule_id":"%{waf.rule_id}V",
"waf_severity":"%{waf.severity}V",
"waf_passed":"%{waf.passed}V",
"waf_logdata":"%{cstr_escape(waf.logdata)}V",
"waf_executed":"%{waf.executed}V",
"waf_anomaly_score":"%{waf.anomaly_score}V",
"waf_sql_score":"%{waf.sql_injection_score}V",
"waf_rfi_score":"%{waf.rfi_score}V",
"waf_lfi_score":"%{waf.lfi_score}V",
"waf_xss_score":"%{waf.xss_score}V",
"waf_http_score":"%{waf.http_violation_score}V",
"waf_php_score":"%{waf.php_injection_score}V",
"waf_rce_score":"%{waf.rce_score}V",
"waf_session_fixation_score":"%{waf.session_fixation_score}V",
"waf_message":"%{cstr_escape(waf.message)}V"
}

FER (Field Extraction Rules)

この FER (Field Extraction Rules) は、全体の parse 時間を削減するための例として提供されています。すべての parse オペレーションが FER でサポートされているわけではありません。詳細については、「FER (Field Extraction Rules) の作成」を参照してください。

parse "\"reqMethod\":\"*\"" as method, "\"status\":\"*\"" as status, "\"fwdHost\":\"*\"" as origin| parse "\"bytes\":\"*\"" as bytes, "\"edgeIP\":\"*\"" as edgeip, "\"country\":\"*\"" as country, "\"cookie\":\"*\"" as cookie

クエリのサンプル

エラーを起こしている上位の URL

_sourceCategory=fastly 50? | parse "\"reqPath\":\"*\"" as path, "\"status\":\"*\"" as status | urldecode(path) as path | where status > 499 | where status < 600 | count as errors by path | sort by errors

キャッシュのパフォーマンス

_sourceCategory=fastly cacheStatus | parse "\"cacheStatus\":\"*\"" as status | where !(status="") | if(status="0", "0 - Non cacheable", if(status="1" OR status="2", "1/2 - Cache Hit", if(status="3", "3 - Cache Miss", ""))) as cachestatus | count by cachestatus

ホスト別の上位の拒否

_sourceCategory=fastly waf denyRules reqHost | parse "\"denyRules\":\"*\"" as deny, "\"reqHost\":\"*\"" as host | where deny != "" | timeslice 1m | count by host, _timeslice | transpose row _timeslice column host

  • この記事は役に立ちましたか?