diff --git a/constructs/traceroute-monitor.mdx b/constructs/traceroute-monitor.mdx new file mode 100644 index 00000000..735de888 --- /dev/null +++ b/constructs/traceroute-monitor.mdx @@ -0,0 +1,267 @@ +--- +title: 'TracerouteMonitor Construct' +description: 'Learn how to configure Traceroute monitors with the Checkly CLI.' +sidebarTitle: '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` | Destination port (1–65535). Defaults to `443` for all non-ICMP protocols. For UDP/SCTP, set `port: 33434` explicitly — a high closed port so the destination returns ICMP Unreachable to confirm arrival. Ignored 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. Defaults to the `avg` property. Use `.avg()`, `.min()`, `.max()`, or `.stdDev()` to target a specific statistic. 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..bcaf3bf4 --- /dev/null +++ b/detect/uptime-monitoring/traceroute-monitors/configuration.mdx @@ -0,0 +1,111 @@ +--- +title: 'Traceroute Monitor Configuration' +description: 'Configure your Traceroute monitor to map network paths and detect routing issues, latency, and packet loss.' +sidebarTitle: '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. All responses share this format: + +```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; always present (0 for ICMP probes) + "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 + "avg": 12.34, // Omitted entirely (field absent) when destination is not reached + "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 (empty when PTR lookup is off or 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": { + "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 (0 if unknown) + "asn_org": "GOOGLE", // AS organization name + "country": "US", // Two-letter country code + "aws_region": "", // AWS region name (if hop is in AWS) + "aws_service": "" // AWS service name (if hop is in 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..b9e04444 --- /dev/null +++ b/detect/uptime-monitoring/traceroute-monitors/overview.mdx @@ -0,0 +1,109 @@ +--- +title: 'Traceroute Monitors Overview' +description: 'Map the network path to any host and detect routing issues, high-latency hops, and packet loss.' +sidebarTitle: 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 responds with an ICMP Time Exceeded message before forwarding the packet +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 | SCTP ABORT or INIT-ACK from destination, or ICMP Destination Unreachable from the target | + + +The default port for UDP and SCTP in the Checkly web UI is pre-filled to `33434` — a high, typically-closed port where the destination is more likely to return an ICMP Destination Unreachable. When configuring via the CLI or API, the port defaults to `443` for all non-ICMP protocols, so set `port: 33434` explicitly for UDP/SCTP probes if you want the same behavior. + + +## 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. Change the port to one that is explicitly open on the target (e.g. `80` or `22`) +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**: SCTP probes require raw sockets, which need `CAP_NET_RAW`. Container runtimes drop this capability by default. + +**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 abfd76d5..edd6ad73 100644 --- a/docs.json +++ b/docs.json @@ -167,6 +167,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": [ @@ -481,6 +488,7 @@ "constructs/dns-monitor", "constructs/tcp-monitor", "constructs/icmp-monitor", + "constructs/traceroute-monitor", "constructs/heartbeat-monitor", "constructs/agentic-check", "constructs/api-check",