diff --git a/constructs/traceroute-monitor.mdx b/constructs/traceroute-monitor.mdx new file mode 100644 index 00000000..a9ea303b --- /dev/null +++ b/constructs/traceroute-monitor.mdx @@ -0,0 +1,268 @@ +--- +title: 'TracerouteMonitor Construct' +description: 'Learn how to configure Traceroute monitors with the Checkly CLI.' +sidebarTitle: 'Traceroute Monitor' +canonical: 'https://www.checklyhq.com/docs/constructs/traceroute-monitor/' +--- + +import GeneralMonitorOptionsTable from '/snippets/general-monitor-options-table.mdx'; + + +Learn more about Traceroute Monitors in [the Traceroute monitor overview](/detect/uptime-monitoring/traceroute-monitors/overview). + + +Traceroute monitors map the network path to a host hop-by-hop, measuring per-hop latency and packet loss, and detecting whether the destination is reached. Use them to monitor path stability and catch routing issues before they affect your users. + + +Before creating Traceroute Monitors, ensure you have: + +- An initialized Checkly CLI project +- A hostname or IP address you want to trace +- Basic understanding of network tracing (traceroute / tracert) + +For additional setup information, see [CLI overview](/cli/overview). + + + + +```ts Basic Example +import { Frequency, TracerouteMonitor } from "checkly/constructs" + +new TracerouteMonitor('traceroute-api', { + name: 'API Gateway Network Path', + description: "Maps the network path to `api.example.com` to detect routing changes.", + frequency: Frequency.EVERY_5M, + request: { + url: 'api.example.com', + }, +}) +``` + +```ts Advanced Example +import { Frequency, TracerouteAssertionBuilder, TracerouteMonitor } from "checkly/constructs" + +new TracerouteMonitor('traceroute-db', { + name: 'Database Routing Monitor', + description: "Traces path to `db.example.com` with strict latency and hop assertions.", + activated: true, + frequency: Frequency.EVERY_10M, + locations: ['us-east-1', 'eu-central-1'], + degradedResponseTime: 10000, + maxResponseTime: 20000, + request: { + url: 'db.example.com', + protocol: 'TCP', + port: 5432, + ipFamily: 'IPv4', + maxHops: 20, + maxUnknownHops: 10, + ptrLookup: true, + timeout: 15, + assertions: [ + TracerouteAssertionBuilder.hopCount().lessThan(15), + TracerouteAssertionBuilder.responseTime('avg').lessThan(50), + TracerouteAssertionBuilder.packetLoss().lessThan(5), + ], + }, +}) +``` + + + +## Configuration + +Traceroute monitors have their own probe-specific settings, plus the standard monitor options shared across all check types. + + + + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `request` | `object` | ✅ | - | Traceroute request configuration object | +| `degradedResponseTime` | `number` | ❌ | `10000` | Final-hop avg RTT in milliseconds at which the monitor is marked as degraded | +| `maxResponseTime` | `number` | ❌ | `20000` | Final-hop avg RTT in milliseconds at which the monitor is marked as failed | + + + + + + + + + +### `TracerouteMonitor` Options + + + +Traceroute request configuration, including probe protocol, target host, and response validation. + +**Usage:** + +```ts +new TracerouteMonitor('traceroute-monitor', { + name: 'Network Path Monitor', + request: { + url: 'api.example.com', + protocol: 'TCP', + port: 443, + assertions: [ + TracerouteAssertionBuilder.hopCount().lessThan(20), + ], + }, +}) +``` + +**Parameters:** + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `url` | `string` | ✅ | - | Target hostname or IP address. Do not include a scheme or port | +| `protocol` | `string` | ❌ | `'TCP'` | Probe protocol: `'TCP'` \| `'UDP'` \| `'ICMP'` \| `'SCTP'` | +| `port` | `number` | ❌ | `443` (TCP) / `33434` (UDP, SCTP) | Destination port (1–65535). Defaults to `443` for TCP and to `33434` — a high, typically closed port — for UDP/SCTP, so the destination returns ICMP Destination Unreachable to confirm arrival. Ignored (and not sent) when `protocol` is `'ICMP'` | +| `ipFamily` | `string` | ❌ | `'IPv4'` | IP family: `'IPv4'` \| `'IPv6'` | +| `maxHops` | `number` | ❌ | `30` | Maximum hops to probe (1–64) | +| `maxUnknownHops` | `number` | ❌ | `15` | Maximum consecutive unresponsive hops before stopping (1–30) | +| `ptrLookup` | `boolean` | ❌ | `true` | Perform reverse-DNS (PTR) lookups on hop IPs | +| `timeout` | `number` | ❌ | `10` | Seconds to wait for the trace to complete (1–30) | +| `assertions` | `TracerouteAssertion[]` | ❌ | `[]` | Response assertions using `TracerouteAssertionBuilder` | + + + + +Final-hop average RTT in milliseconds at which the monitor is marked as degraded (warning state). Maximum: 30,000. + +**Usage:** + +```ts highlight={3} +new TracerouteMonitor("traceroute-latency-tiers", { + name: "API Network Path", + degradedResponseTime: 5000, // Warn when final-hop avg RTT exceeds 5 seconds + request: { + url: 'api.example.com', + }, +}) +``` + + + +Final-hop average RTT in milliseconds at which the monitor is marked as failed. Maximum: 30,000. + +**Usage:** + +```ts highlight={3} +new TracerouteMonitor("traceroute-latency-tiers", { + name: "API Network Path", + maxResponseTime: 15000, // Fail when final-hop avg RTT exceeds 15 seconds + request: { + url: 'api.example.com', + }, +}) +``` + + +### `TracerouteMonitor` Assertions + +Assertions for Traceroute monitors are defined using the `TracerouteAssertionBuilder`. The following sources are available: + +- `responseTime(property?)`: Validate RTT at the final responding hop. Pass `'avg'`, `'min'`, `'max'`, or `'stdDev'` as the argument to target a specific statistic; when omitted, it defaults to `'avg'`. This assertion fails when `destinationReached` is `false` +- `hopCount()`: Assert against the total number of hops recorded in the trace +- `packetLoss()`: Assert against the packet loss percentage at the last recorded hop (0–100) + +Here are some examples: + +- Assert that the average final-hop latency is below a threshold (default property is `avg`): + +```ts +TracerouteAssertionBuilder.responseTime().lessThan(100) +// Equivalent to: +{ source: 'RESPONSE_TIME', property: 'avg', comparison: 'LESS_THAN', target: '100' } +``` + +- Assert against a specific RTT property: + +```ts +TracerouteAssertionBuilder.responseTime('max').lessThan(200) +// Equivalent to: +{ source: 'RESPONSE_TIME', property: 'max', comparison: 'LESS_THAN', target: '200' } +``` + +- Assert on the number of hops: + +```ts +TracerouteAssertionBuilder.hopCount().lessThan(15) +// Equivalent to: +{ source: 'HOP_COUNT', comparison: 'LESS_THAN', target: '15' } +``` + +- Assert on packet loss at the last hop: + +```ts +TracerouteAssertionBuilder.packetLoss().lessThan(10) +// Equivalent to: +{ source: 'PACKET_LOSS', comparison: 'LESS_THAN', target: '10' } +``` + +Learn more in our docs on [Assertions](/detect/assertions). + +### General Monitor Options + + +Friendly name for your Traceroute Monitor that will be displayed in the Checkly dashboard and used in notifications. + +**Usage:** + +```ts highlight={2} +new TracerouteMonitor("my-traceroute", { + name: "API Gateway Network Path", + /* More options ... */ +}) +``` + + + +How often the Traceroute Monitor should run. Use the `Frequency` enum to set the check interval. + +**Usage:** + +```ts highlight={3} +new TracerouteMonitor("my-traceroute", { + name: "API Gateway Network Path", + frequency: Frequency.EVERY_5M, + /* More options ... */ +}) +``` + +**Available frequencies**: `EVERY_30S`, `EVERY_1M`, `EVERY_2M`, `EVERY_5M`, `EVERY_10M`, `EVERY_15M`, `EVERY_30M`, `EVERY_1H`, `EVERY_2H`, `EVERY_3H`, `EVERY_6H`, `EVERY_12H`, `EVERY_24H`. Traceroute monitors do not support sub-30-second frequencies (`EVERY_10S` / `EVERY_20S`). + + + +Array of [public location codes](/concepts/locations/#public-locations) where the Traceroute Monitor should run from. Use `privateLocations` for [private locations](/platform/private-locations/overview). Multiple locations help detect regional routing differences. + +**Usage:** + +```ts highlight={3} +new TracerouteMonitor("global-path-monitor", { + name: "API Path from Multiple Regions", + locations: ["us-east-1", "eu-central-1", "ap-southeast-1"], + request: { + url: 'api.example.com', + }, +}) +``` + + + +Whether the Traceroute Monitor is enabled and will run according to its schedule. + +**Usage:** + +```ts highlight={3} +new TracerouteMonitor("my-traceroute", { + name: "API Gateway Network Path", + activated: false, // Disabled monitor + request: { + url: 'api.example.com', + }, +}) +``` + diff --git a/detect/uptime-monitoring/traceroute-monitors/configuration.mdx b/detect/uptime-monitoring/traceroute-monitors/configuration.mdx new file mode 100644 index 00000000..de734c41 --- /dev/null +++ b/detect/uptime-monitoring/traceroute-monitors/configuration.mdx @@ -0,0 +1,112 @@ +--- +title: 'Traceroute Monitor Configuration' +description: 'Configure your Traceroute monitor to map network paths and detect routing issues, latency, and packet loss.' +sidebarTitle: 'Configuration' +canonical: 'https://www.checklyhq.com/docs/detect/uptime-monitoring/traceroute-monitors/configuration/' +--- + + +To configure a Traceroute monitor using code, learn more about the [Traceroute Monitor Construct](/constructs/traceroute-monitor). + + +### Basic Setup + +Configure your Traceroute monitor by specifying the target host and probe parameters: + +* **Hostname or IP address:** The host to trace to (e.g. `api.example.com` or `203.0.113.1`). Do not include a scheme or port in this field +* **IP family:** Choose between IPv4 (default) or IPv6 +* **Protocol:** The probe protocol. TCP (default) is the most firewall-friendly option. See the [protocol reference](/detect/uptime-monitoring/traceroute-monitors/overview#probe-protocols) for details on TCP, UDP, ICMP, and SCTP +* **Port:** Destination port for TCP, UDP, and SCTP probes (1–65535). Defaults to `443` for TCP and `33434` for UDP/SCTP. Not applicable for ICMP — the port field is hidden when ICMP is selected +* **Max Hops:** Maximum number of hops to probe before stopping (1–64, default: 30) +* **Max Unknown Hops:** Maximum number of consecutive unresponsive hops to tolerate before cutting the trace short (1–30, default: 15). Many routers silently drop traceroute probes without affecting real traffic, so a reasonable limit prevents traces from halting unnecessarily +* **Timeout:** Maximum time in seconds to wait for the entire trace to complete (1–30, default: 10) +* **Reverse DNS (PTR lookup):** When enabled (default: on), Checkly performs a PTR lookup on each hop IP to resolve it to a hostname. Disable to reduce trace time when hostnames are not needed + +### Assertions + +Use assertions to validate Traceroute results and alert when paths change or degrade: + +You can create assertions based on: + +* **Latency:** RTT statistics for the **final responding hop**. Available properties: `avg`, `min`, `max`, `stdDev` (all in milliseconds). This assertion requires the destination to be reached — if `destinationReached` is `false`, `finalHopLatency` is absent and the assertion fails +* **Hop Count:** Total number of hops recorded in the trace. Use this to detect routing changes that add or remove hops from the expected path +* **Packet Loss:** Packet loss percentage at the **last recorded hop** (0–100). A non-zero value indicates that some probe packets were not returned + +For more details, see [Assertions](/detect/assertions). + +### Response Time Limits + +Set performance thresholds based on final-hop latency: + +* **Degraded After:** Final-hop avg RTT threshold (in milliseconds) after which the check is marked as degraded but not failed. Default: 3,000 ms. Maximum: 30,000 ms +* **Failed After:** Final-hop avg RTT threshold after which the check fails completely. Default: 5,000 ms. Maximum: 30,000 ms + + +Response-time thresholds apply to the **final-hop average RTT**, not the total check execution time. If the destination is not reached, the monitor is marked as failed regardless of these thresholds. + + +### JSON Response Schema + +The Traceroute response is available as structured JSON. These are the key fields (a few internal bookkeeping fields are omitted here, and fields marked as omitted are absent from the JSON rather than empty): + +```json +{ + "hostname": "api.example.com", // Target hostname or IP as configured + "resolvedIp": "93.184.216.34", // IP address used for the trace + "port": 443, // Destination port; for ICMP probes this reports the unused fallback 443 + "ipFamily": "IPv4", // "IPv4" or "IPv6" + "maxHops": 30, // Configured max hops + "totalHops": 12, // Number of hops actually recorded + "destinationReached": true, // Whether the destination responded + "truncationReason": "destinationReached",// Why the trace stopped: + // "destinationReached" | "maxHops" | "maxUnknownHops" | "timeout" + "probeProtocol": "TCP", // Probe protocol: "TCP" | "UDP" | "ICMP" | "SCTP" + "finalHopLatency": { // RTT stats for the last responding hop (the whole object is omitted when the destination is not reached) + "avg": 12.34, + "min": 11.80, + "max": 13.10, + "stdDev": 0.42 + }, + "hops": [ + { + "hop_number": 1, + "main_ip": "10.0.0.1", // Primary IP observed at this hop + "main_host": "router.isp.net", // Reverse-DNS hostname (omitted when PTR lookup is off or the lookup fails) + "sent": 3, // Probe packets sent to this hop + "received": 3, // Replies received from this hop + "loss_percentage": 0.0, // Packet loss at this hop + "rtt": { // RTT stats (omitted when the hop never replied) + "last_ms": 1.23, // RTT of the most recent probe + "avg_ms": 1.10, // Average RTT across all probes + "best_ms": 0.95, // Minimum RTT + "worst_ms": 1.23, // Maximum RTT + "stddev_ms": 0.12 // Standard deviation + }, + "asn": 15169, // Autonomous System Number (omitted when unknown) + "asn_org": "GOOGLE", // AS organization name (omitted when unknown) + "country": "US", // Two-letter country code (omitted when unknown) + "aws_region": "us-east-1", // AWS region — only present when the hop is inside AWS + "aws_service": "EC2" // AWS service — only present when the hop is inside AWS + } + // ... one entry per recorded hop + ], + "timestamp": 1720000000 // Unix timestamp of the trace run +} +``` + +### Frequency + +Set how often the monitor runs. Traceroute monitors run at most **once every 30 seconds** (every 30 seconds to 24 hours) — the two sub-30-second frequencies aren't available. + +### Scheduling & Locations + +* **Strategy:** Choose between round-robin or parallel execution. Learn more about [scheduling strategies](/concepts/scheduling) +* **Locations:** Select [public](/concepts/locations/#public-locations) or [private](/platform/private-locations/overview) locations to run the monitor from + +### Additional Settings + +* **Name:** Give your monitor a clear name to identify it in dashboards and alerts +* **Description:** Add context about what this monitor does and why it matters. Supports markdown, max 500 characters. When a failure occurs, [Rocky AI](/ai/rocky-ai) uses the description to provide more accurate [root cause and user impact analysis](/resolve/ai-root-cause-analysis/overview) +* **Tags:** Use tags to organize monitors across [dashboards](/communicate/dashboards/overview/) and [maintenance windows](/communicate/maintenance-windows/overview) +* **Retries:** Define how failed runs should be retried. See [retry strategies](/communicate/alerts/retries) +* **Alerting:** Configure your [alert settings](/communicate/alerts/configuration), [alert channels](/communicate/alerts/channels), or set up [webhooks](/integrations/alerts/webhooks) for custom integrations diff --git a/detect/uptime-monitoring/traceroute-monitors/overview.mdx b/detect/uptime-monitoring/traceroute-monitors/overview.mdx new file mode 100644 index 00000000..f358fef6 --- /dev/null +++ b/detect/uptime-monitoring/traceroute-monitors/overview.mdx @@ -0,0 +1,110 @@ +--- +title: 'Traceroute Monitors Overview' +description: 'Map the network path to any host and detect routing issues, high-latency hops, and packet loss.' +sidebarTitle: Overview +canonical: 'https://www.checklyhq.com/docs/detect/uptime-monitoring/traceroute-monitors/overview/' +--- + + +**Monitoring as Code**: Learn more about the [Traceroute Monitor Construct](/constructs/traceroute-monitor). + + +## What are Traceroute Monitors? + +Traceroute monitors map the network path between a Checkly location and your target host, recording every router hop along the way and measuring per-hop latency and packet loss. Typical use cases include: + +* Detecting routing anomalies or unexpected path changes between Checkly locations and your infrastructure +* Identifying which network segment is responsible for latency spikes or packet loss +* Verifying that the destination is reachable end-to-end, beyond just confirming that a port accepts connections +* Continuously monitoring path stability across regions over time + +## How do Traceroute Monitors work? + +A Traceroute monitor executes the following steps on each run: + +1. **Hostname resolution**: If a hostname is provided, Checkly resolves it to an IP address before sending any probes +2. **Probe execution**: The runner sends probe packets using the configured protocol (TCP by default). Each probe carries a progressively higher TTL, so each router on the path in turn drops the probe whose TTL expires there and responds with an ICMP Time Exceeded message +3. **Hop collection**: RTT statistics (avg, min, max, stddev) and packet loss are collected for each router hop along the path +4. **Destination detection**: When the destination host responds directly, the trace is complete and `destinationReached` is set to `true` +5. **Assertion evaluation**: Configured assertions are evaluated against the results — including final-hop latency, total hop count, and last-hop packet loss + +### Probe protocols + +| Protocol | Default port | How destination is detected | +|----------|-------------|---------------------------| +| **TCP** (default) | 443 | SYN-ACK or RST received from destination | +| **UDP** | 33434 | Any ICMP Destination Unreachable from the target (port unreachable, admin-prohibited, host unreachable, etc.) | +| **ICMP** | *(no port)* | Echo Reply from destination | +| **SCTP** | 33434 | Any ICMP Destination Unreachable from the target (protocol unreachable, port unreachable, etc.) | + + +The default port is protocol-dependent everywhere — web UI, CLI, and API: `443` for TCP and `33434` for UDP/SCTP. `33434` is a high, typically-closed port: UDP and SCTP arrival is only confirmed when the destination returns an ICMP Destination Unreachable, which requires the probed port to be closed. Avoid setting an open port (like `443`) for UDP/SCTP probes — it would never confirm arrival. + + +## Traceroute Monitor Results + +Select a specific check run to inspect its results: + +* **Summary:** Shows the target hostname, resolved IP, monitor state (`passed`, `degraded`, or `failed`), total hop count, and whether the destination was reached + +* **Error details:** If the trace failed — due to a DNS resolution error, an unreachable network, or assertion failures — the error message is shown here + +* **Hop-by-hop table:** Each hop shows: + * Hop number and primary IP address, with reverse-DNS hostname when PTR lookup is enabled + * ASN, organization name, and country + * AWS region and service (where applicable) + * Probes sent and received, plus packet loss percentage + * RTT statistics: last, avg, best, worst, and stddev in milliseconds + +* **Final-hop latency:** RTT statistics for the destination hop. This is the value used for `Latency` assertions and the degraded/failed response-time thresholds + +Learn more in our documentation on [Results](/concepts/results). + +## Troubleshooting Common Issues + + +**Symptom**: `destinationReached` is `false`, yet the website or API responds normally. + +**Root causes**: +* The configured port is firewalled — TCP SYN probes never receive a SYN-ACK or RST +* The target host silently drops probe packets at the network edge +* A middle-box rewrites or discards probe traffic before it reaches the destination + +**How to fix**: +1. Switch the probe protocol — try `ICMP` if the host responds to ping, or `UDP` for a connectionless probe +2. For TCP probes, change the port to one that is explicitly open on the target (e.g. `80` or `22`). For UDP/SCTP, keep a *closed* port — arrival is only confirmed by an ICMP Destination Unreachable reply +3. Confirm reachability at the application layer with an [API Monitor](/detect/synthetic-monitoring/overview) or [TCP Monitor](/detect/uptime-monitoring/tcp-monitors/overview) targeting the same host and port + + + +**Symptom**: Several intermediate hops show no response, but the destination is eventually reached. + +**Root cause**: Routers commonly deprioritize or filter ICMP Time Exceeded replies for probe traffic without affecting real data forwarding. The hops are still routing your packets — they simply do not respond to traceroute probes. + +**What to do**: +* Focus on `destinationReached` and final-hop latency rather than individual intermediate hops +* If the trace is cut short before the destination, increase the `Max Unknown Hops` limit + + + +**Symptom**: SCTP probes fail with a socket permission error on a self-hosted Checkly Agent. + +**Root cause**: Container runtimes drop `CAP_NET_RAW` by default. Traceroute monitors always need it — hop discovery listens for ICMP replies on a raw socket regardless of probe protocol — but SCTP is the case that surfaces an explicit socket error, because SCTP probes are also *sent* over a raw socket. + +**How to fix** — In **Kubernetes**, update your pod spec or Helm values: + +```yaml +securityContext: + allowPrivilegeEscalation: true + capabilities: + add: ["NET_RAW"] +``` + +In **Docker**: + +```bash +docker run --cap-add=NET_RAW ghcr.io/checkly/agent:latest +``` + +`CAP_NET_RAW` only grants permission to open raw sockets. It does not escalate broader container privileges. + diff --git a/docs.json b/docs.json index 42d520e4..33654d13 100644 --- a/docs.json +++ b/docs.json @@ -170,6 +170,13 @@ "detect/uptime-monitoring/icmp-monitors/configuration" ] }, + { + "group": "Traceroute Monitors", + "pages": [ + "detect/uptime-monitoring/traceroute-monitors/overview", + "detect/uptime-monitoring/traceroute-monitors/configuration" + ] + }, { "group": "Heartbeat Monitors", "pages": [ @@ -484,6 +491,7 @@ "constructs/dns-monitor", "constructs/tcp-monitor", "constructs/icmp-monitor", + "constructs/traceroute-monitor", "constructs/heartbeat-monitor", "constructs/agentic-check", "constructs/api-check", diff --git a/sitemap.xml b/sitemap.xml index 73b08849..751b76e4 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -903,6 +903,9 @@ https://www.checklyhq.com/docs/constructs/telegram-alert-channel/ + + https://www.checklyhq.com/docs/constructs/traceroute-monitor/ + https://www.checklyhq.com/docs/constructs/url-monitor/ @@ -1077,6 +1080,12 @@ https://www.checklyhq.com/docs/detect/uptime-monitoring/tcp-monitors/quickstart/ + + https://www.checklyhq.com/docs/detect/uptime-monitoring/traceroute-monitors/configuration/ + + + https://www.checklyhq.com/docs/detect/uptime-monitoring/traceroute-monitors/overview/ + https://www.checklyhq.com/docs/detect/uptime-monitoring/url-monitors/configuration/