ログストリーミング:Datadog

Fastly の リアルタイムログストリーミング機能は、Datadog が読み取れる形式でログを送信するように設定できます。Datadog は、クラウドベースの監視・分析ソリューションで、スタック内のアプリケーション内部を確認し、結果を集計できます。

前提条件

Fastly サービスのログエンドポイントとして Datadog を追加する前に、以下が必要です。

  • Datadog アカウントを登録。 Datadog サイトでアカウントを作成できます。 制限付きの無料プラン、またはアップグレードしてより多くの機能を利用することができます。 Datadog の設定を登録する場所が米国 (US) または欧州連合 (EU) である場合、Fastly でのログエンドポイント設定にて使用するコマンドが異なります。
  • Datadog API キーを、Datadog 設定ページから取得。 Datadog インターフェイスにて Integrations -> API メニューにアクセスすることで、API キーを作成・取得できます。

    トークンページ

    この例では、decafbaddeadbeef キーが表示されています。お客様の API キーは、これとは異なります。このキーは、忘れないように書き留めてください。

ログエンドポイントとして Datadog を追加

Datadog アカウントを作成し、Datadog API キーを書き留めたら、以下の手順で Fastly サービスのログエンドポイントとして Datadog を追加します。

  1. リモートログストリーミングの設定に関するガイドの情報をご参照ください。
  2. Datadog Create endpoint ボタンをクリックしてください。Create a Datadog endpoint ページが表示されます。
  3. Create a Datadog endpoint に以下のように記入します。
    • Name フィールドに分かりやすいエンドポイントの名前を入力します。
    • Placement セクションでは、生成される VCL にログコールが配置される場所を選択します。有効な値は Format Version Defaultwaf_debug (waf_debug_log)None です。詳細については、ログ配置の変更に関するガイドをご参照ください。
    • Log format 欄に、Datadog に送信するデータを入力します。 この形式の使用方法については以下をご覧ください。
    • Region メニューから、ログを配信するリージョンを選択します。
    • API key 欄に、Datadog アカウントの API キーを入力します。
  4. Create ボタンをクリックすると、新しいログエンドポイントが作成されます。
  5. Activate ボタンをクリックして設定変更をデプロイします。

エンドポイントの作成とサービス変更の完了後、数秒するとログが Datadog アカウントに表示されるようになります。これらのログは、Datadog アカウント内の Datadog Log Explorer を介してアクセスできます。

JSON ログ形式のご利用

Datadog は JSON 形式のログファイルを自動的に解析できます。カスタマイズされたログルールを必要としないため、JSON 形式が Datadog にデータを取り込む最も簡単な方法となっています。さらに Datadog は servicedateなど、予約されたフィールドを認識します。

例えば、以下の 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
}
Back to Top