ログストリーミング:Datadog
最終更新日 2021-06-09
Fastly のリアルタイムログストリーミング機能を、Datadog が読める形式でログを送信するように設定することができます。Datadog はクラウドベースの監視・分析ソリューションで、スタック内のアプリケーション内部を確認し、結果を集計できます。
Fastly ではサードパーティのサービスに関する直接のサポートは行っておりません。詳細については、Fastly サービスの利用規約をご参照ください。
前提条件
Fastly サービスのログエンドポイントとして Datadog を追加する前に以下が必要です。
- Datadog アカウントの登録。 Datadog サイトでアカウントを作成できます。制限付きの無料プラン、またはアップグレードしてより多くの機能を利用することができます。Datadog の設定を登録する場所が米国 (US) または欧州連合 (EU) である場合、Fastly でログエンドポイントを設定する際に使用するコマンドが異なります。
-
Datadog API キーを Datadog の設定ページから取得。 Datadog インターフェイスで Integrations -> APIs にアクセスすることで API キーを作成・取得できます。
この例では
decafbaddeadbeef
キーが表示されています。お客様の API キーは、これとは異なります。このキーを忘れないようにメモしてください。
ログエンドポイントとして Datadog を追加する
Datadog アカウントを作成し、Datadog API キーを書き留めたら、以下の手順で Fastly サービスのログエンドポイントとして Datadog を追加します。
- リモートログストリーミングの設定に関するガイドの情報をご参照ください。
- Datadog Create endpoint ボタンをクリックしてください。Create a Datadog endpoint ページが表示されます。
- Create a Datadog endpoint に以下のように記入します。
- Name フィールドに分かりやすいエンドポイントの名前を入力します。
- Placement セクションでは、生成される VCL にログコールが配置される場所を選択します。有効な値は Format Version Default、waf_debug (waf_debug_log)、None です。詳細については、ログ配置の変更に関するガイドをご参照ください。
- Log format 欄に、Datadog に送信するデータを入力します。 この形式の使用方法については以下をご覧ください。
- Region メニューから、ログを配信するリージョンを選択します。
- API key フィールドに、Datadog アカウントの API キーを入力します。
- Create ボタンをクリックすると、新しいログエンドポイントが作成されます。
- Activate ボタンをクリックして設定変更をデプロイします。
エンドポイントの作成とサービスへの変更が完了すると、数秒後にログが Datadog アカウントに表示されるようになります。これらのログは Datadog アカウント内の Datadog Log Explorer を介してアクセスできます。
JSON ログ形式の使用
Datadog は JSON 形式のログファイルを自動的に解析できます。カスタマイズされたログルールを必要としないため、JSON 形式が Datadog にデータを取り込む最も簡単な方法となっています。さらに、Datadog は service
や date
など、予約済みフィールドを認識します。
この例の JSON ログは、読み取りやすくフォーマットされています。正しく解析されるためには、改行とインデントの空白をすべて取り除いた上で Log format 欄に1行で入力する必要があります。
例えば、以下の JSON では、ログを送信した Fastly サービスの ID を service
と設定していますが、人間可読形式の名前を使用したり fastly
などの共通の名前のもとにすべてのログをグループ化することも可能です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
{
"ddsource": "fastly",
"service": "%{req.service_id}V",
"date": "%{begin:%Y-%m-%dT%H:%M:%S%z}t",
"time_start": "%{begin:%Y-%m-%dT%H:%M:%S%Z}t",
"time_end": "%{end:%Y-%m-%dT%H:%M:%S%Z}t",
"http": {
"request_time_ms": %D,
"method": "%m",
"url": "%{json.escape(req.url)}V",
"useragent": "%{User-Agent}i",
"referer": "%{Referer}i",
"protocol": "%H",
"request_x_forwarded_for": "%{X-Forwarded-For}i",
"status_code": "%s"
},
"network": {
"client": {
"ip": "%h",
"name": "%{client.as.name}V",
"number": "%{client.as.number}V",
"connection_speed": "%{client.geo.conn_speed}V"
},
"destination": {
"ip": "%A"
},
"geoip": {
"geo_city": "%{client.geo.city.utf8}V",
"geo_country_code": "%{client.geo.country_code}V",
"geo_continent_code": "%{client.geo.continent_code}V",
"geo_region": "%{client.geo.region}V"
},
"bytes_written": %B,
"bytes_read": %{req.body_bytes_read}V
},
"host":"%{if(req.http.Fastly-Orig-Host, req.http.Fastly-Orig-Host, req.http.Host)}V",
"origin_host": "%v",
"is_ipv6": %{if(req.is_ipv6, "true", "false")}V,
"is_tls": %{if(req.is_ssl, "true", "false")}V,
"tls_client_protocol": "%{json.escape(tls.client.protocol)}V",
"tls_client_servername": "%{json.escape(tls.client.servername)}V",
"tls_client_cipher": "%{json.escape(tls.client.cipher)}V",
"tls_client_cipher_sha": "%{json.escape(tls.client.ciphers_sha)}V",
"tls_client_tlsexts_sha": "%{json.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_accept_content": "%{Accept}i",
"request_accept_language": "%{Accept-Language}i",
"request_accept_encoding": "%{Accept-Encoding}i",
"request_accept_charset": "%{Accept-Charset}i",
"request_connection": "%{Connection}i",
"request_dnt": "%{DNT}i",
"request_forwarded": "%{Forwarded}i",
"request_via": "%{Via}i",
"request_cache_control": "%{Cache-Control}i",
"request_x_requested_with": "%{X-Requested-With}i",
"request_x_att_device_id": "%{X-ATT-Device-Id}i",
"content_type": "%{Content-Type}o",
"is_cacheable": %{if(fastly_info.state~"^(HIT|MISS)$", "true","false")}V,
"response_age": "%{Age}o",
"response_cache_control": "%{Cache-Control}o",
"response_expires": "%{Expires}o",
"response_last_modified": "%{Last-Modified}o",
"response_tsv": "%{TSV}o",
"server_datacenter": "%{server.datacenter}V",
"req_header_size": %{req.header_bytes_read}V,
"resp_header_size": %{resp.header_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
}