Synthetics และ Uptime Check
ไอเดียหลักในหนึ่งประโยค
หัวข้อที่มีชื่อว่า “ไอเดียหลักในหนึ่งประโยค”Synthetic Monitoring รัน check ที่ script ไว้เชิงรุกจาก global network ของ location ของ Datadog เอง แทนที่จะรอ real user หรือ backend traffic มาเผยปัญหาให้เห็น และพอ test ตัวหนึ่ง fail มันเสียบเข้ากับ monitor และ notification pipeline ตัวเดียวกันเป๊ะกับที่ครอบไปแล้วก่อนหน้าใน module นี้
API test: check request-response เดี่ยว ๆ
หัวข้อที่มีชื่อว่า “API test: check request-response เดี่ยว ๆ”API test คือ check request-response เดี่ยว ๆ แบบ HTTP/TCP/DNS/ICMP — เช่น ยิง health-check endpoint แล้ว assert บน status code, response time, หรือ body content มันรันซ้ำ ๆ จาก location ไหนก็ได้ที่เราเลือก
{ "name": "Checkout health check", "type": "api", "subtype": "http", "config": { "request": { "method": "GET", "url": "https://checkout.example.com/health" }, "assertions": [ { "type": "statusCode", "operator": "is", "target": 200 }, { "type": "responseTime", "operator": "lessThan", "target": 300 } ] }, "locations": ["aws:ap-southeast-1", "aws:eu-west-1"], "message": "@pagerduty-checkout-critical Checkout health check is failing.", "options": { "tick_every": 60, "retry": { "count": 2, "interval": 300 } }, "status": "live"}Browser test: user journey ที่ script ไว้เต็มรูปแบบ
หัวข้อที่มีชื่อว่า “Browser test: user journey ที่ script ไว้เต็มรูปแบบ”Browser test รัน browser flow ที่ script ไว้เต็มรูปแบบข้าม step หลายขั้น — โหลดหน้า, คลิกปุ่ม login, assert ว่า dashboard element โผล่มา — เพื่อทดสอบ user journey จริงแบบ end to end สิ่งนี้จับสิ่งที่ API test จับไม่ได้ทางกายภาพ: หน้าหนึ่งคืนค่า 200 ได้แต่ยัง render UI ที่พังได้ หรือ flow fail กลางทางได้แม้ว่าทุก request ที่อยู่ข้างหลังมัน “สำเร็จ” ทีละตัว
{ "name": "Login flow", "type": "browser", "config": { "request": { "method": "GET", "url": "https://app.example.com/login" }, "assertions": [] }, "steps": [ { "type": "goToUrl", "params": { "value": "https://app.example.com/login" } }, { "type": "click", "params": { "element": "#login-button" } }, { "type": "assertElementPresent", "params": { "element": "#dashboard" } } ], "locations": ["aws:us-east-1"], "message": "@slack-app-oncall Login flow is failing.", "options": { "tick_every": 900, "retry": { "count": 1, "interval": 300 } }, "status": "live"}Assertion: คำศัพท์ operator กับ type จริง
หัวข้อที่มีชื่อว่า “Assertion: คำศัพท์ operator กับ type จริง”ทั้งสอง fence ข้างบนใช้ triple type/operator/target อ่าน enum จริงที่ติดตั้งจริงตรง ๆ แทนที่จะเดาว่า operator ไหนมีอยู่ — SyntheticsAssertionOperator.allowed_values: is, isNot, contains, doesNotContain, matches, doesNotMatch, lessThan, lessThanOrEqual, moreThan, moreThanOrEqual, isInLessThan, isInMoreThan, isUndefined, doesNotExist, validates SyntheticsAssertionType.allowed_values มี statusCode, responseTime, header, body, certificate, tlsVersion, latency, packetLossPercentage, grpcHealthcheckStatus, และอื่น ๆ อีก — คำศัพท์จริงที่ใหญ่กว่าสอง type ที่ตัวอย่างในบทนี้ใช้มาก ครอบ TCP/gRPC/certificate check คู่กับ HTTP ธรรมดา
Location กับ private location
หัวข้อที่มีชื่อว่า “Location กับ private location”array locations (aws:ap-southeast-1, aws:eu-west-1, aws:us-east-1 ข้างบน) อ้างถึง public managed location network ของ Datadog สำหรับ endpoint ที่เป็น internal-only เท่านั้น docs.datadoghq.com/synthetics/private_locations/ อธิบายกลไกแยกต่างหาก: “Private locations allow you to monitor internal-facing applications or any private endpoints that aren’t accessible from the public internet.” พูดเป็นรูปธรรม: “Private locations come as Docker containers or Windows services that you can install inside of your private network… Your private location worker pulls your test configurations from Datadog’s servers using HTTPS, executes the test on a schedule or on-demand, and returns the test results to Datadog’s servers.” ID ของ private location ใส่เข้าไปใน array locations เดียวกันเป๊ะกับ location สาธารณะ — จากมุมมองของ test definition private location ก็แค่อีกหนึ่ง string ใน list นั้น แม้ว่าตัวที่รัน check จะเป็น infrastructure ที่เรา deploy เองแทนที่จะเป็น network ของ Datadog เอง
พิสูจน์: กับดัก default ของ min_location_failed
หัวข้อที่มีชื่อว่า “พิสูจน์: กับดัก default ของ min_location_failed”การรัน test จาก location หลายที่ (ทั้งสอง fence ข้างบนใช้สองหรือสามที่) มักถูกสมมติว่าหมายความว่า “เราจะไม่ได้ false alarm จาก region ที่ flaky หนึ่งอัน” model SyntheticsTestOptions จริงมี field เฉพาะสำหรับ tune เรื่องนี้: min_location_failed เอกสาร Terraform provider ของ Datadog เองระบุ default ของมันตรง ๆ: “min_location_failed (Number) Minimum number of locations in failure required to trigger an alert. Defaults to 1.”
default นั้นหมายความว่า test ที่ config ให้รันจากสาม location — ตั้งใจในทางจิตวิญญาณให้เฉลี่ยผลของ region ไหนสักอันที่ network สะดุดชั่วคราวออกไป — alert ทันทีที่อันใดอันหนึ่งในสาม location fail เว้นแต่ min_location_failed จะถูกยกขึ้นชัดเจน location หลายที่ปรับปรุง coverage (เรารู้ว่า endpoint เข้าไม่ได้จาก region เฉพาะไหน) แต่ไม่ได้ทำอะไรกับ alert stability เลยด้วยตัวมันเอง — คุณสมบัติที่สองนั้นขึ้นกับ min_location_failed ทั้งหมด field แยกต่างหากที่คนส่วนใหญ่ที่ config “location เพิ่มเพื่อความน่าเชื่อถือ” ไม่เคยแตะเลย นี่คือกับดักรูปทรงเดียวกับข้อกำหนดของ notify_no_data ที่ต้องเคยรายงานมาแล้วครั้งหนึ่ง และเอกสารของ resource Terraform เองคือที่ที่ระบุไว้ตรงที่สุด ไม่ใช่ JSON API reference
{ "options": { "tick_every": 60, "retry": { "count": 2, "interval": 300 }, "min_location_failed": 2 }}Retry: ดูดซับความล้มเหลวชั่วคราวก่อนที่จะ page ใคร
หัวข้อที่มีชื่อว่า “Retry: ดูดซับความล้มเหลวชั่วคราวก่อนที่จะ page ใคร”options.retry ({count, interval} ยืนยันจริงบน SyntheticsTestOptionsRetry.attribute_map) คือกลไกที่ต่างจาก min_location_failed — มัน retry check ของ location เดียวกัน อีก count ครั้ง ห่างกัน interval มิลลิวินาที ก่อนที่จะถือว่าผลของ location นั้นตัวเดียวเป็นความล้มเหลวเลย ทั้งสองรวมกัน: retry ดูดซับความสะดุดชั่วขณะของ location เดียว; min_location_failed ตัดสินว่า location กี่ที่ หลัง retry ของตัวเองหมดแล้ว ต้องเห็นตรงกันว่ามีอะไรผิดจริงก่อนที่จะมีใคร notify
Alerting pipeline เดียวกัน แค่ signal source ต่างกัน
หัวข้อที่มีชื่อว่า “Alerting pipeline เดียวกัน แค่ signal source ต่างกัน”Synthetic test ที่ fail trigger monitor แบบ synthetics alert — และ synthetics alert monitor ใช้ threshold, notification, และ escalation mechanic เดียวกันเป๊ะกับที่สอนไปแล้วก่อนหน้าใน module นี้ Critical/warning threshold, @-mention, escalation_message, และ Downtime สำหรับ maintenance ที่วางแผนไว้ทำงานเหมือนกันหมด มีแค่ input ที่ป้อนเข้า monitor ที่ต่างกัน
{ "type": "synthetics alert", "query": "\"synthetics\" for test_public_id in (\"abc-def-ghi\") \"failure\" over \"5m\" last \"3\" check greater than 2", "options": { "thresholds": { "critical": 2, "warning": 1 }, "escalation_message": "@pagerduty-checkout-escalation Still failing, escalating." }, "message": "@slack-checkout-oncall @pagerduty-checkout-critical Checkout health check is failing from multiple locations."}Terraform: datadog_synthetics_test
หัวข้อที่มีชื่อว่า “Terraform: datadog_synthetics_test”resource "datadog_synthetics_test" "checkout_health" { name = "Checkout health check" type = "api" subtype = "http" status = "live" message = "@pagerduty-checkout-critical Checkout health check is failing." locations = ["aws:ap-southeast-1", "aws:eu-west-1"] tags = ["service:checkout-service", "env:production"]
request_definition { method = "GET" url = "https://checkout.example.com/health" }
assertion { type = "statusCode" operator = "is" target = "200" }
assertion { type = "responseTime" operator = "lessThan" target = "300" }
options_list { tick_every = 60 min_location_failed = 2 retry { count = 2 interval = 300 } }}$ terraform init && terraform validateSuccess! The configuration is valid.รัน terraform init + terraform validate กับ provider datadog ที่ pin ไว้ 4.22.0 (credential ปลอม, validate = false, ไม่มี API call จริง): สะอาด ลองค่า type ที่ผิดโดยตั้งใจเพื่อดู error จริง เพราะ HCL shape ตรงนี้ (block request_definition/assertion/options_list ต่างจาก object config ที่ซ้อนของ JSON API มากพอที่ควรเช็คแยกต่างหาก ไม่ใช่สมมติว่าตรงกัน):
# @expect-error terraform validate real error: Invalid enum value — 'invalid value "not-a-real-type" for SyntheticsTestDetailsType: valid values are [api browser mobile network]'resource "datadog_synthetics_test" "broken_test" { name = "Broken test" type = "not-a-real-type" status = "live" message = "test" locations = ["aws:eu-central-1"]
request_definition { method = "GET" url = "https://example.org" }}error จริงระบุ type ฝั่ง Go เป๊ะ (SyntheticsTestDetailsType) และ list ค่าที่ valid จริง — api, browser, mobile, network — ยืนยันว่า Terraform resource นี้ครอบ synthetic test family สี่แบบเดียวกับที่ field type ของ JSON API มี จาก client-side schema check ที่อิสระจากกันโดยสิ้นเชิง
flowchart LR Loc1[Location: ap-southeast-1] --> Test[Synthetic test: API or Browser] Loc2[Location: eu-west-1] --> Test Test -->|retry absorbs one blip| Retried[Per-location result] Retried -->|min_location_failed locations agree| History[Test result history] History --> Mon[synthetics alert monitor] Mon -->|critical/warning thresholds| Notify[Same notification/escalation pipeline as metric and composite monitors]
Reading AI-generated code
หัวข้อที่มีชื่อว่า “Reading AI-generated code”🐛 หา bug ในโค้ดนี้
// AI comment: "Run from 3 locations for redundancy so one flaky region doesn't page us"{"name": "Checkout health check","type": "api","subtype": "http","config": { "request": { "method": "GET", "url": "https://checkout.example.com/health" }, "assertions": [ { "type": "statusCode", "operator": "is", "target": 200 } ]},"locations": ["aws:ap-southeast-1", "aws:eu-west-1", "aws:us-east-1"],"message": "@pagerduty-checkout-critical Checkout health check is failing.","options": { "tick_every": 60 }}เฉลย
นี่ validate สะอาดกับ SyntheticsAPITest model จริง — พิสูจน์แล้วก่อนหน้าในบทนี้ location string จริงสามอัน assertion จริงหนึ่งอัน ไม่มีอะไรผิดเชิงโครงสร้างเลย บั๊กคือสิ่งที่ comment ของ AI อ้างว่าแก้ได้พอดีเป๊ะ: comment บอกว่าสามที่หมายความว่า “region ที่ flaky หนึ่งอันไม่ page เรา” แต่พิสูจน์แล้วข้างบนจากเอกสาร Terraform provider ของ Datadog เอง min_location_failed default เป็น 1 — location เดียวที่ fail จากกี่ที่ก็ตามที่ config ไว้ trigger alert เพิ่ม location ตรงนี้ปรับปรุง coverage (มุมมองมากขึ้น) แต่ไม่ได้ทำอะไรกับเป้าหมาย alert-stability ที่ comment ระบุไว้เลย การแก้: เพิ่ม "min_location_failed": 2 (หรือสูงกว่า) เข้าไปใน options เพื่อบังคับให้ต้องมีมากกว่าหนึ่ง location เห็นตรงกันก่อนจะ page จริง ๆ และแยกต่างหาก options.retry ถ้าเป้าหมายคือดูดซับความสะดุดชั่วคราวของ location เดียวก่อนที่จะนับเป็นความล้มเหลวด้วยซ้ำ
Mental Model
หัวข้อที่มีชื่อว่า “Mental Model”Result pipeline ของ Synthetic test มี filter อิสระสามชั้นเรียงกันตามลำดับ และการปนกันคือกับดักทั้งหมดที่บทนี้พิสูจน์ Retry คือ filter แรก — “check ครั้งเดียวของ location นี้แค่สะดุดชั่วขณะรึเปล่า” — ใช้ต่อ-location ก่อนที่ผลของ location นั้นจะถูก finalize ด้วยซ้ำ min_location_failed คือ filter ที่สอง — “ผลที่ finalize แล้วกี่ location ต้องเห็นตรงกันว่ามันดับจริง” — ใช้ข้าม location หลัง retry threshold ของ synthetics alert monitor เอง คือ filter ที่สาม รูปทรงเดียวกันเป๊ะกับ monitor type อื่นทุกตัวใน module นี้ ใช้กับ history ผลของ test ตามเวลา การรันจาก location เพิ่มเสริมแค่สอง filter แรกถ้า min_location_failed ถูก tune ให้ตรงกัน ด้วยตัวมันเอง location เพิ่มแค่หมายความว่ามีโอกาสอิสระมากขึ้นที่ filter หนึ่งจะพลาดไปถึง filter สอง
Trade-offs
หัวข้อที่มีชื่อว่า “Trade-offs”- API test เทียบกับ Browser test สำหรับ endpoint เดียวกัน — API test รันถูกกว่าและคิดง่ายกว่า แต่พิสูจน์แล้วข้างบนว่ามันจับหน้าที่คืน status
200แต่ render UI พังไม่ได้; Browser test จับความล้มเหลวประเภทนั้นได้ แลกกับความช้ากว่า แพงกว่า และเปราะกว่าเวลามี UI change ที่ไม่เกี่ยวข้องมาทำให้ script พัง - Location เพิ่ม เทียบกับ
min_location_failedที่สูงขึ้น — location เพิ่มอย่างเดียว (พิสูจน์แล้วข้างบน) ขยาย coverage โดยไม่เปลี่ยน alert stability เลย; ยกmin_location_failedให้ตรงกับจำนวน location ลด false page จากปัญหาชั่วคราวของ region หนึ่ง แลกกับ regional outage จริงที่ต้องกระจายไปหลาย location มากขึ้นก่อนที่จะมีใครถูก page - Public managed location เทียบกับ private location — public location ไม่ต้องมี infrastructure เลยและครอบมุมมองของ public internet; private location (พิสูจน์แล้วข้างบน โครงสร้าง Docker/Windows worker จริง) จำเป็นสำหรับ endpoint ที่ internal-only เท่านั้น แลกกับต้องรันและดูแล worker นั้นเอง
Common Misconceptions
หัวข้อที่มีชื่อว่า “Common Misconceptions”- “รัน test จาก location เพิ่มทำให้ alert เสถียรขึ้นต่อ region ที่ flaky หนึ่งอันอัตโนมัติ” ไม่จริง — พิสูจน์แล้วข้างบนจากเอกสารของ Datadog เอง:
min_location_faileddefault เป็น1location เดียวที่ fail จากกี่ที่ก็ตามที่ config ไว้ trigger alert เสถียรภาพต้องยก field นั้นขึ้นเองชัดเจน - “
retryกับmin_location_failedคือสองชื่อของสิ่งเดียวกัน” ไม่จริง — พิสูจน์แล้วข้างบน:retrycheck location เดียวกัน ซ้ำก่อนที่จะ finalize ผลของมัน;min_location_failedนับว่า location ที่finalize แล้วกี่ที่ต้องเห็นตรงกัน หลัง retry เสร็จแล้ว - “JSON payload ของ Browser test จะ construct สำเร็จตราบใดที่
stepsถูกกรอกถูกต้อง” ไม่จริง — พิสูจน์แล้วข้างบน:SyntheticsBrowserTestต้องการmessageตอน construct ไม่ว่าstepsจะถูกแค่ไหน payload ที่ขาดมัน throwTypeErrorจริงก่อนที่stepsจะถูกพิจารณาด้วยซ้ำ - “resource
datadog_synthetics_testที่มีค่าtypeที่ไม่รองรับ fail แค่ตอนapplyกับ API จริงเท่านั้น” ไม่จริง — พิสูจน์แล้วข้างบน:terraform validateจับค่า enumtypeที่ผิดได้ฝั่ง client ทั้งหมด ไม่มี API call เกี่ยวข้อง ระบุค่าที่ valid จริงตรง ๆ ใน error เลย