diff --git a/config/_default/menus/main.en.yaml b/config/_default/menus/main.en.yaml index 6eee19b60e8..916c679e7af 100644 --- a/config/_default/menus/main.en.yaml +++ b/config/_default/menus/main.en.yaml @@ -7793,21 +7793,26 @@ menu: parent: synthetics_notifications identifier: synthetics_notifications_template_variables weight: 1001 + - name: Step Data Variables + url: synthetics/notifications/step_data_variables + parent: synthetics_notifications_template_variables + identifier: synthetics_notifications_step_data_variables + weight: 10001 - name: Conditional Alerting url: synthetics/notifications/conditional_alerting parent: synthetics_notifications identifier: synthetics_notifications_conditional_alerting - weight: 1002 + weight: 1003 - name: Advanced Notifications url: synthetics/notifications/advanced_notifications parent: synthetics_notifications identifier: synthetics_notifications_advanced_notifications - weight: 1003 + weight: 1004 - name: Integrate with Statuspage url: synthetics/notifications/statuspage parent: synthetics_notifications identifier: synthetics_notifications_statuspage - weight: 1004 + weight: 1005 - name: Troubleshooting url: synthetics/troubleshooting/ parent: synthetics diff --git a/content/en/synthetics/notifications/step_data_variables.md b/content/en/synthetics/notifications/step_data_variables.md new file mode 100644 index 00000000000..279263ef2ed --- /dev/null +++ b/content/en/synthetics/notifications/step_data_variables.md @@ -0,0 +1,529 @@ +--- +title: Step Data Template Variables +description: Template variables for accessing step-level data in Synthetic test notifications +further_reading: +- link: "/synthetics/notifications/template_variables/" + tag: "Documentation" + text: "Synthetic Monitoring Template Variables" +- link: "/monitors/manage/" + tag: "Documentation" + text: "Learn how to manage monitors" +--- + +## Overview + +Step data template variables allow you to access detailed information about individual steps in multistep, browser, mobile, and API tests. Similar to standard API tests, the variables are listed in the `synthetics.attributes.variables.extracted` property, but inside steps themselves. These values are available as long as the step is successful. + +## General steps + +For multistep, browser, and mobile tests: + +| Variable | Description | +|----------|-------------| +| `synthetics.attributes.variables.extracted.steps.allowFailure` | Whether the step is allowed to fail without failing the entire test | +| `synthetics.attributes.variables.extracted.steps.duration` | Step execution duration in milliseconds | +| `synthetics.attributes.variables.extracted.steps.failure` | Failure information object containing `.code` and `.message` | +| `synthetics.attributes.variables.extracted.steps.id` | Unique step identifier | +| `synthetics.attributes.variables.extracted.steps.isCritical` | Whether the step is critical to the test | +| `synthetics.attributes.variables.extracted.steps.status` | Step execution status | +| `synthetics.attributes.variables.extracted.steps.type` | Type of step being executed | + +**Subtest information:** + +| Variable | Description | +|----------|-------------| +| `synthetics.attributes.variables.extracted.steps.subTest.id` | Subtest identifier | +| `synthetics.attributes.variables.extracted.steps.subStep.parentStep.id` | Parent step identifier | +| `synthetics.attributes.variables.extracted.steps.subStep.parentTest.id` | Parent test identifier | +| `synthetics.attributes.variables.extracted.steps.subStep.level` | Nesting level (1 for subtests, 2 for subtests of subtests) | + +{{% collapse-content title="Example JSON" level="p" %}} + +```json +{ + "steps": [ + { + "allowFailure": false, + "duration": 10955, + "failure": { + "code": "ASSERTION_FAILURE", + "message": "Element's content should not equal given value." + }, + "id": "g8e-q4a-fix", + "isCritical": true, + "status": "failed", + "type": "assertElementContent", + "subTest": { + "id": "m2i-fcy-eva" + }, + "subStep": { + "parentStep": {"id": "ikj-juk-z2u"}, + "parentTest": {"id": "th5-wic-5mj"}, + "level": 1 + } + } + ] +} +``` + +{{% /collapse-content %}} + +## Browser tests + +**General:** + +| Variable | Description | +|----------|-------------| +| `{{synthetics.attributes.result.startUrl}}` | URL from test configuration | + +**Steps:** + +| Variable | Description | +|----------|-------------| +| `.apiTest.request` | API test request configuration (only for "Run API Test" steps where `type` is `runApiTest`) | +| `.apiTest.result` | API test result data (similar to `attributes.result` for API tests) | +| `.assertionResult.expected` | Expected value for assertions | +| `.assertionResults.checkType` | Type of assertion check | +| `.assertionResults.actual` | Actual value found during assertion | +| `.browserErrors` | List of browser errors encountered | +| `.timings.firstByte` | Time to first byte | +| `.timings.tcp` | TCP connection timing | +| `.description` | Step description | + +{{% collapse-content title="Example JSON" level="p" %}} + +```json +{ + "startUrl": "https://datadoghq.com", + "apiTest": { + "request": { + "subType": "http", + "method": "GET", + "url": "https://datadoghq.com" + }, + "result": { + "statusCode": 200 + } + }, + "assertionResults": { + "expected": "100", + "checkType": "equals", + "actual": "200" + }, + "timings": { + "firstByte": 7.1, + "tcp": 5.2 + } +} +``` + +{{% /collapse-content %}} + +{{% collapse-content title="Browser errors example" level="p" %}} + +```json +[ + { + "name": "Console error", + "description": "Failed to load resource: the server responded with a status of 403 ()", + "type": "js" + }, + { + "name": "[GET] 403 - https://accounts.google.com/v3/signin/identifier", + "description": "https://accounts.google.com/v3/signin/identifier...", + "type": "network", + "status": 403 + } +] +``` + +{{% /collapse-content %}} + +## Mobile tests + +| Variable | Description | +|----------|-------------| +| `.application.versionId` | Mobile application version identifier | +| `.apiTest` | API test data (for API test steps within mobile tests) | +| `.description` | Step description | + +{{% collapse-content title="Example JSON" level="p" %}} + +```json +{ + "application": { + "versionId": "4408df2e-9b7a-4665-9510-b9041b2ae1e8" + }, + "description": "Tap on Button Sign In" +} +``` + +{{% /collapse-content %}} + +## API tests + +**Multistep:** + +| Variable | Description | +|----------|-------------| +| `.name` | Step name | +| `.type` | Step type | + +*Note: Follow regular API fields per subType* + +**Non-Multistep:** + +| Variable | Description | +|----------|-------------| +| `.assertions.actual` | Actual value from assertion | +| `.assertions.expected` | Expected value for assertion | +| `.assertions.operator` | Assertion operator | +| `.assertions.type` | Assertion type | +| `.dnsResolution.resolvedIp` | Resolved IP address | +| `.dnsResolution.server` | DNS server used | +| `.timings.dns` | DNS resolution time | +| `.timings.tcp` | TCP connection time | +| `.request.url` | Request URL | +| `.request.host` | Request host | +| `.response.body` | Response body content | +| `.response.statusCode` | HTTP status code | +| `.response.headers` | Response headers | +| `.response.httpVersion` | HTTP version | +| `.response.redirects` | Redirect information | + +{{% collapse-content title="Example JSON" level="p" %}} + +```json +{ + "name": "Check API endpoint", + "type": "http", + "assertions": { + "actual": 1.5145, + "expected": 1000, + "operator": "moreThan", + "type": "latency" + }, + "dnsResolution": { + "resolvedIp": "18.245.199.78", + "server": "8.8.4.4" + }, + "timings": { + "tcp": 6.9, + "download": 33.5, + "total": 75, + "dns": 7.5, + "firstByte": 17.2, + "ssl": 9.9 + }, + "request": { + "url": "https://www.datadoghq.com", + "host": "datadoghq.com", + "method": "GET" + }, + "response": { + "body": "Example Page Content", + "statusCode": 200, + "headers": { + "content-type": "text/html; charset=utf-8", + "content-length": "250661" + }, + "httpVersion": "1.1", + "redirects": [ + { + "location": "https://datadoghq.com", + "statusCode": 302 + } + ] + } +} +``` + +{{% /collapse-content %}} + +## Network tests + +{{% collapse-content title="WebSocket" level="h3" %}} + +| Variable | Description | +|----------|-------------| +| `.timings.open` | Time to open connection (in milliseconds) | +| `.timings.receive` | Time to receive response | +| `.handshake.request` | Handshake request data | +| `.handshake.response` | Handshake response data | +| `.request.message` | WebSocket request message | +| `.response.message` | WebSocket response message | +| `.close.reason` | Connection close reason | +| `.close.statusCode` | Connection close status code | + +**Example:** + +```json +{ + "timings": { + "tcp": 96, + "receive": 97, + "download": 0, + "total": 201.9, + "dns": 7.7, + "firstByte": 0, + "ssl": 1, + "open": 0.2 + }, + "handshake": { + "response": { + "statusCode": 101 + } + }, + "request": { + "message": "Ping" + }, + "response": { + "message": "Pong" + }, + "close": { + "reason": "message_received", + "statusCode": 1000 + } +} +``` + +{{% /collapse-content %}} + +{{% collapse-content title="gRPC" level="h3" %}} + +| Variable | Description | +|----------|-------------| +| `.callType` | Call type (`unary` or `healthcheck`) | +| `.timings.rpc` | RPC call timing | +| `.response.healthcheck.status` | Health check status | +| `.request.message` | gRPC request message | +| `.response.message` | gRPC response message | + +**Example:** + +```json +{ + "callType": "healthcheck", + "timings": { + "total": 55.3, + "rpc": 9.2, + "dns": 46.1 + }, + "response": { + "healthcheck": { + "status": 1 + } + }, + "request": { + "message": "Ping" + }, + "response": { + "message": "Pong" + } +} +``` + +{{% /collapse-content %}} + +{{% collapse-content title="UDP" level="h3" %}} + +| Variable | Description | +|----------|-------------| +| `.request.message` | UDP request message | +| `.response.message` | UDP response message | +| `.timings.message` | Message timing | + +**Example:** + +```json +{ + "timings": { + "total": 135.3, + "dns": 14.4, + "message": 120.9 + }, + "request": { + "message": "Ping" + }, + "response": { + "message": "Pong" + } +} +``` + +{{% /collapse-content %}} + +{{% collapse-content title="TCP" level="h3" %}} + +| Variable | Description | +|----------|-------------| +| `.connectionOutcome` | Connection result | +| `.netpath.routers.ip` | Router IP addresses | +| `.traceroute.latency.min` | Minimum latency | +| `.traceroute.latency.max` | Maximum latency | +| `.traceroute.latency.avg` | Average latency | +| `.traceroute.latency.stddev` | Standard deviation | +| `.traceroute.latency.values` | Latency values array | + +**Example:** + +```json +[ + { + "packetLossPercentage": 0, + "packetsReceived": 2, + "latency": { + "avg": 0.2375, + "min": 0.189, + "max": 0.286, + "values": [0.189, 0.286], + "stddev": 0.048 + }, + "packetsSent": 2, + "routers": [ + { + "ip": "10.241.134.75" + } + ] + } +] +``` + +{{% /collapse-content %}} + +{{% collapse-content title="ICMP" level="h3" %}} + +| Variable | Description | +|----------|-------------| +| `.traceroute` | Same structure as TCP traceroute | +| `.request.host` | Target host | +| `.ping` | Ping results | +| `.latency.min`, `.latency.max`, `.latency.avg`, `.latency.stddev`, `.latency.values` | Latency measurements | + +**Example:** + +```json +{ + "ping": { + "packetLossPercentage": 0, + "packetsReceived": 4, + "latency": { + "avg": 1.47375, + "min": 1.442, + "max": 1.516, + "values": [1.467, 1.442, 1.47, 1.516], + "stddev": 0.0267 + }, + "resolvedIp": "18.245.199.70", + "packetsSent": 4, + "packetSize": 56 + } +} +``` + +{{% /collapse-content %}} + +## Protocol tests + +{{% collapse-content title="SSL" level="h3" %}} + +| Variable | Description | +|----------|-------------| +| `.cert` | SSL certificate information | +| `.cipher` | Cipher suite used | +| `.issuer` | Certificate issuer | +| `.subject` | Certificate subject | +| `.valid.from` | Certificate valid from date | +| `.valid.to` | Certificate valid to date | +| `.ocsp` | OCSP (Online Certificate Status Protocol) information | +| `.timings.handshake` | SSL handshake timing | + +**Example:** + +```json +{ + "cipher": "TLS_AES_128_GCM_SHA256", + "issuer": { + "C": "US", + "CN": "DigiCert Global G2 TLS RSA SHA256 2020 CA1", + "O": "DigiCert Inc" + }, + "valid": { + "from": 1751414400000, + "to": 1783036799000 + } +} +``` + +{{% /collapse-content %}} + +{{% collapse-content title="DNS" level="h3" %}} + +| Variable | Description | +|----------|-------------| +| `.response.records.type` | DNS record type | +| `.response.records.values` | DNS record values | + +**Example:** + +```json +{ + "dns": { + "response": { + "records": { + "type": "A", + "values": ["192.0.2.1", "192.0.2.2"] + } + } + } +} +``` + +{{% /collapse-content %}} + +## Step summary + +**Accessing steps by index (0-based):** + +| Syntax | Description | +|--------|-------------| +| `.steps.0` | First step | +| `.steps.1` | Second step | +| `.steps.-1` | Last step | +| `.steps.-2` | Step before last | + +**Accessing steps by name or ID:** + +| Syntax | Description | +|--------|-------------| +| `.steps[Click button]` | By step name | +| `.steps.abc-def-ghi` | By step ID | + +Then access data as usual: `.steps.-1.status`, `.steps[Click button].status`, `.steps.abc-def-ghi.status` + +**Step properties:** + +| Variable | Description | +|----------|-------------| +| `.id` | Step identifier | +| `.status` | Step status | +| `.type` | Step type | +| `.duration` | Step duration | +| `.description` | Step description | +| `.failure.message` | Failure message | +| `.failure.code` | Failure code | +| `.url` | Step URL | + +**Summary data:** + +| Variable | Description | +|----------|-------------| +| `.count.steps.total` | Total number of steps | +| `.count.steps.completed` | Completed steps count | +| `.count.errors` | Error count | +| `.count.hops` | Hop count | + +## Further Reading + +{{< partial name="whats-next/whats-next.html" >}} + diff --git a/content/en/synthetics/notifications/template_variables.md b/content/en/synthetics/notifications/template_variables.md index 613dd103e9f..64a377b6d3a 100644 --- a/content/en/synthetics/notifications/template_variables.md +++ b/content/en/synthetics/notifications/template_variables.md @@ -3,6 +3,9 @@ title: Synthetic Monitoring Template Variables aliases: - /synthetics/guide/synthetic-test-monitors/ further_reading: +- link: "/synthetics/notifications/step_data_variables/" + tag: "Documentation" + text: "Step Data Template Variables" - link: "/monitors/manage/" tag: "Documentation" text: "Learn how to manage monitors" @@ -13,102 +16,47 @@ further_reading: ## Overview -Template variables allow you to insert dynamic values from your test results and configuration into Synthetic Monitoring notification messages. Access these variables using the `synthetics.attributes` prefix. For example: - -```text -Test failed at step {{synthetics.failed_step.name}} with error: {{synthetics.failed_step.failure.message}}. -``` - -**Note**: For information about accessing local (config) variables, see the [Variables](#variables) section. - -### Common variable shortcuts - -`{{synthetics.failed_step.name}}` -: The name of the failing step (for example, `Test div #title content`). - -`{{synthetics.failed_step.failure.message}}` -: The error message (for example, `Element's content should match the given regex`). - -`{{synthetics.failed_step.url}}` -: The URL of the failed step (for example, `https://www.datadoghq.com/blog/`). - -`{{synthetics.attributes.result.response.statusCode}}` -: The HTTP status code (for example, `403`). - -`{{synthetics.result.step_count}}` -: Number of steps (for example, `4`). - -`{{synthetics.result.duration}}` -: Duration of the test run (in milliseconds) (for example, `9096`). - -`{{tags.env}}` -: The environment tag value (for example, `prod`). - -**Note:** Not all variables are available for every test type. You may need to test different outputs to verify the data returned. You can export the result as a JSON file from the **Actions** tab, then reference the path directly within your monitor configuration. - - -### Result attributes +Template variables allow you to insert dynamic values from your test results and configuration into Synthetic Monitoring notification messages. Access these variables using the `synthetics.attributes` prefix. -{{< tabs >}} -{{% tab "Test Info" %}} +
Not all variables are available for every test type. You can export test results as a JSON file from the Actions tab to verify available data and reference paths directly in your monitor configuration.
-`{{synthetics.attributes.test}}` -: The `test` object contains information about the test like its `name`, `type`, `subtype`, and `id` +## Test execution attributes -`{{synthetics.attributes.test.name}}` -: The name of the test +Use the following template variables to customize your Synthetic Monitoring alert notifications. Each section contains variables for different attributes that you can reference in your notification messages. -`{{synthetics.attributes.test.type}}` -: Test type (for example, `api`) +### Test info +| Variable | Description | +|----------|-------------| +| `{{synthetics.attributes.test}}` | The `test` object containing `name`, `type`, `subtype`, and `id` | +| `{{synthetics.attributes.test.name}}` | The name of the test | +| `{{synthetics.attributes.test.type}}` | Test type (for example, `api`) | +| `{{synthetics.attributes.test.subType}}` | Subtype for API tests (for example, `http`, `dns`, `multi`) | +| `{{synthetics.attributes.test.id}}` | The test's public ID (for example, `abc-def-ghi`) | -`{{synthetics.attributes.test.subType}}` -: Subtype for API tests (for example, `http`, `dns`, and `multi`) +### Location +| Variable | Description | +|----------|-------------| +| `{{synthetics.attributes.location}}` | The `location` object containing test execution location data | +| `{{synthetics.attributes.location.id}}` | Location ID (for example, `aws:eu-central-1`) | +| `{{synthetics.attributes.location.name}}` | Name of the location (for example, `Frankfurt (AWS)`) | +| `{{synthetics.attributes.location.privateLocation}}` | `true` for Private Locations | -`{{synthetics.attributes.test.id}}` -: The test's public ID (for example, `abc-def-ghi`) - -{{% /tab %}} -{{% tab "Location" %}} - -`{{synthetics.attributes.location}}` -: The `location` object contains information about the location of where the test is run from - -`{{synthetics.attributes.location.id}}` -: Location ID (for example, `aws:eu-central-1`) - -`{{synthetics.attributes.location.name}}` -: Name of the location (for example, `Frankfurt (AWS)`) - -`{{synthetics.attributes.location.privateLocation}}` -: `true` for Private Locations - -{{% /tab %}} -{{% tab "Device" %}} +### Device Applies to browser and mobile tests. -`{{synthetics.attributes.device}}` -: The `device` object contains information about the device on which the test is run on - -`{{synthetics.attributes.device.id}}` -: Device identifier +| Variable | Description | +|----------|-------------| +| `{{synthetics.attributes.device}}` | The `device` object containing device information | +| `{{synthetics.attributes.device.id}}` | Device identifier | +| `{{synthetics.attributes.device.name}}` | Human-readable device name | +| `{{synthetics.attributes.device.type}}` | Device type classification | +| `{{synthetics.attributes.device.width}}`, `{{synthetics.attributes.device.height}}` | Screen resolution dimensions | +| `{{synthetics.attributes.device.browser.type}}` | Browser type (browser tests only) | +| `{{synthetics.attributes.device.platform.name}}`, `{{synthetics.attributes.device.platform.version}}` | Platform information (mobile tests only) | -`{{synthetics.attributes.device.name}}` -: Human-readable device name +{{% collapse-content title="Example JSON" level="p" %}} -`{{synthetics.attributes.device.type}}` -: Device type classification - -`{{synthetics.attributes.device.width}}`, `{{synthetics.attributes.device.height}}` -: Screen resolution dimensions - -`{{synthetics.attributes.device.browser.type}}` -: Browser type (browser tests only) - -`{{synthetics.attributes.device.platform.name}}`, `{{synthetics.attributes.device.platform.version}}` -: Platform information (mobile tests only) - -**Example values:** ```json { "device": { @@ -122,34 +70,24 @@ Applies to browser and mobile tests. } ``` -{{% /tab %}} -{{% tab "Result" %}} - -`{{synthetics.attributes.result}}` -: The `result` object contains information about the executed test run - -`{{synthetics.attributes.result.id}}` -: Unique result ID - -`{{synthetics.attributes.result.status}}` -: Test execution status (for example, `passed` or `failed`) +{{% /collapse-content %}} -`{{synthetics.attributes.result.duration}}` -: Test duration in milliseconds +### Result +| Variable | Description | +|----------|-------------| +| `{{synthetics.attributes.result}}` | The `result` object containing test execution data | +| `{{synthetics.attributes.result.id}}` | Unique result ID | +| `{{synthetics.attributes.result.status}}` | Test execution status (for example, `passed` or `failed`) | +| `{{synthetics.attributes.result.duration}}` | Test duration in milliseconds | +| `{{synthetics.attributes.result.testStartedAt}}` | Test start time (epoch milliseconds) | +| `{{synthetics.attributes.result.testFinishedAt}}` | Test finish time (epoch milliseconds) | +| `{{synthetics.attributes.result.testTriggeredAt}}` | Test trigger time (epoch milliseconds) | +| `{{synthetics.attributes.result.failure}}` | The `failure` object with failure details | +| `{{synthetics.attributes.result.failure.message}}` | The failure message | +| `{{synthetics.attributes.result.failure.code}}` | The failure code | -`{{synthetics.attributes.result.testStartedAt}}`, `{{synthetics.attributes.result.testFinishedAt}}`, `{{synthetics.attributes.result.testTriggeredAt}}` -: Epoch timestamps in milliseconds +{{% collapse-content title="Example JSON" level="p" %}} -`{{synthetics.attributes.result.failure}}` -: The `failure` object contains information about why the test failed - -`{{synthetics.attributes.result.failure.message}}` -: The failure message - -`{{synthetics.attributes.result.failure.code}}` -: The failure code - -**Example values:** ```json { "result": { @@ -167,31 +105,25 @@ Applies to browser and mobile tests. } ``` -{{% /tab %}} -{{< /tabs >}} +{{% /collapse-content %}} -## Variables +## Variable attributes -{{< tabs >}} -{{% tab "Local config variables" %}} +### Local config variables -These are local variables configured for API tests or defined outside individual steps in step-based tests. This also includes variables created by JavaScript code execution. +Local variables configured for API tests or defined outside individual steps in step-based tests. This also includes variables created by JavaScript code execution. Located at `{{synthetics.attributes.result.variables.config}}`: -`{{synthetics.attributes.result.variables.config.name}}` -: Variable name - -`{{synthetics.attributes.result.variables.config.type}}` -: Variable type +| Variable | Description | +|----------|-------------| +| `{{synthetics.attributes.result.variables.config.name}}` | Variable name | +| `{{synthetics.attributes.result.variables.config.type}}` | Variable type | +| `{{synthetics.attributes.result.variables.config.secure}}` | Whether the variable value is obfuscated | +| `{{synthetics.attributes.result.variables.config.value}}` | Variable value (non-obfuscated only) | -`{{synthetics.attributes.result.variables.config.secure}}` -: Whether the variable value is obfuscated +{{% collapse-content title="Example JSON" level="p" %}} -`{{synthetics.attributes.result.variables.config.value}}` -: Variable value (non-obfuscated only) - -**Examples:** ```json { "name": "RANDOM_NUMBER", @@ -201,28 +133,23 @@ Located at `{{synthetics.attributes.result.variables.config}}`: } ``` -{{% /tab %}} -{{% tab "Global variables" %}} +{{% /collapse-content %}} -These are extracted variables whose value updates a global variable value. +### Global variables -Available only for **successful test results** and **recovery notifications**. +Extracted variables whose value updates a global variable value. Available only for **successful test results** and **recovery notifications**. Located at `{{synthetics.attributes.result.variables.extracted}}`: -`{{synthetics.attributes.result.variables.extracted.id}}` -: Global variable ID - -`{{synthetics.attributes.result.variables.extracted.name}}` -: Variable name +| Variable | Description | +|----------|-------------| +| `{{synthetics.attributes.result.variables.extracted.id}}` | Global variable ID | +| `{{synthetics.attributes.result.variables.extracted.name}}` | Variable name | +| `{{synthetics.attributes.result.variables.extracted.secure}}` | Whether the variable value is obfuscated | +| `{{synthetics.attributes.result.variables.extracted.val}}` | Variable value (note: uses `.val`, not `.value`) | -`{{synthetics.attributes.result.variables.extracted.secure}}` -: Whether the variable value is obfuscated +{{% collapse-content title="Example JSON" level="p" %}} -`{{synthetics.attributes.result.variables.extracted.val}}` -: Variable value (note: uses `.val`, not `.value`) - -**Examples:** ```json { "id": "ec734823-536e-4aba-8b5f-55733189d936", @@ -232,21 +159,20 @@ Located at `{{synthetics.attributes.result.variables.extracted}}`: } ``` -{{% /tab %}} -{{% tab "Step extracted variables" %}} +{{% /collapse-content %}} -For tests with steps, step data is contained in `{{synthetics.attributes.result.steps}}`. +### Step extracted variables -`.extractedValue.name` -: Variable name +For tests with steps, step data is contained in `{{synthetics.attributes.result.steps}}`. -`.extractedValue.secure` -: Whether the variable value is obfuscated +| Variable | Description | +|----------|-------------| +| `synthetics.attributes.result.steps.extractedValue.name` | Variable name | +| `synthetics.attributes.result.steps.extractedValue.secure` | Whether the variable value is obfuscated | +| `synthetics.attributes.result.steps.extractedValue.value` | Variable value (if step was successful) | -`.extractedValue.value` -: Variable value (if step was successful) +{{% collapse-content title="Example JSON" level="p" %}} -**Examples:** ```json { "extractedValue": { @@ -257,661 +183,14 @@ For tests with steps, step data is contained in `{{synthetics.attributes.result. } ``` -{{% /tab %}} -{{< /tabs >}} - -### Variables extracted by steps - -Similar to standard API tests, the variables are listed in the `variables.extracted` property, but inside steps themselves. These values are available as long as the step is successful. - -{{< tabs >}} -{{% tab "General steps" %}} - -**For multistep/browser/mobile tests**: - -`.steps.allowFailure` -: Whether the step is allowed to fail without failing the entire test - -`.steps.duration` -: Step execution duration in milliseconds - -`.steps.failure` -: Failure information object containing `.code` and `.message` - -`.steps.id` -: Unique step identifier - -`.steps.isCritical` -: Whether the step is critical to the test - -`.steps.status` -: Step execution status - -`.steps.type` -: Type of step being executed - -**Subtest information:** - -`.steps.subTest.id` -: Subtest identifier - -`.steps.subStep.parentStep.id` -: Parent step identifier - -`.steps.subStep.parentTest.id` -: Parent test identifier - -`.steps.subStep.level` -: Nesting level (1 for subtests, 2 for subtests of subtests) - -**Examples:** -```json -{ - "steps": [ - { - "allowFailure": false, - "duration": 10955, - "failure": { - "code": "ASSERTION_FAILURE", - "message": "Element's content should not equal given value." - }, - "id": "g8e-q4a-fix", - "isCritical": true, - "status": "failed", - "type": "assertElementContent", - "subTest": { - "id": "m2i-fcy-eva" - }, - "subStep": { - "parentStep": {"id": "ikj-juk-z2u"}, - "parentTest": {"id": "th5-wic-5mj"}, - "level": 1 - } - } - ] -} -``` - -{{% /tab %}} -{{% tab "Browser Tests" %}} - -**General:** - -`{{synthetics.attributes.result.startUrl}}` -: URL from test configuration - -**Steps:** - -`.apiTest.request` -: API test request configuration (only for "Run API Test" steps where `type` is `runApiTest`) - -`.apiTest.result` -: API test result data (similar to `attributes.result` for API tests) - -`.assertionResult.expected` -: Expected value for assertions - -`.assertionResults.checkType` -: Type of assertion check - -`.assertionResults.actual` -: Actual value found during assertion - -`.browserErrors` -: List of browser errors encountered - -`.timings.firstByte` -: Time to first byte - -`.timings.tcp` -: TCP connection timing - -`.description` -: Step description - -**Examples:** -```json -{ - "startUrl": "https://datadoghq.com", - "apiTest": { - "request": { - "subType": "http", - "method": "GET", - "url": "https://datadoghq.com" - }, - "result": { - "statusCode": 200 - } - }, - "assertionResults": { - "expected": "100", - "checkType": "equals", - "actual": "200" - }, - "timings": { - "firstByte": 7.1, - "tcp": 5.2 - } -} -``` - -Examples for `.browserErrors`: - -```json -{ - "name": "Console error", - "description": "Failed to load resource: the server responded with a status of 403 ()", - "type": "js" -}, -{ - "name": "[GET] 403 - https://accounts.google.com/v3/signin/identifier?dsh=S688774280%3A1687962864348747&conti", - "description": "https://accounts.google.com/v3/signin/identifier?dsh=S688774280%3A1687962864348747&continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Faction_handle_signin%3Dtrue%26app%3Ddesktop%26hl%3Den%26next%3D%252Fsignin_passive%26feature%3Dpassive&hl=en&ifkv=AeDOFXjMKzxp0wt-b9IzWKz6RS9Kk-VmW5z_fzLP_cjbSWd4hWeP5g53fvdrhX6b2cDVQrNtJ5B7vA&passive=true&service=youtube&uilel=3&flowName=GlifWebSignIn&flowEntry=ServiceLogin\n}} - -{{% collapse-content title= "gRPC" level="h4" expanded=false %}} - -`.callType` -: Call type (`unary` or `healthcheck`) - -`.timings.rpc` -: RPC call timing - -`.response.healthcheck.status` -: Health check status - -`.request.message` -: gRPC request message - -`.response.message` -: gRPC response message - -**Examples:** -```json -{ - "callType": "healthcheck", - "timings": { - "total": 55.3, - "rpc": 9.2, - "dns": 46.1 - }, - "response": { - "healthcheck": { - "status": 1 - } - }, - "request": { - "message": "Ping" - }, - "response": { - "message": "Pong" // Responses can be truncated if too big (only the start is available) - } -} -``` - -{{< /collapse-content >}} - -{{% collapse-content title= "UDP" level="h4" expanded=false %}} - -`.request.message` -: UDP request message - -`.response.message` -: UDP response message - -`.timings.message` -: Message timing - -**Examples:** -```json -{ - "timings": { - "total": 135.3, - "dns": 14.4, - "message": 120.9 - }, - "request": { - "message": "Ping" - }, - "response": { - "message": "Pong" - } -} -``` - -{{< /collapse-content >}} - -{{% collapse-content title= "TCP" level="h4" expanded=false %}} - -`.connectionOutcome` -: Connection result - -`.netpath.routers.ip` -: Router IP addresses - -`.traceroute.latency.min` -: Minimum latency - -`.traceroute.latency.max` -: Maximum latency - -`.traceroute.latency.avg` -: Average latency - -`.traceroute.latency.stddev` -: Standard deviation - -`.traceroute.latency.values` -: Latency values array - -**Examples:** -```json -[ - { - "packetLossPercentage": 1, - "packetsReceived": 0, - "packetsSent": 2, - "routers": [ - { - "ip": "???" - } - ] - }, - { - "packetLossPercentage": 0, - "packetsReceived": 2, - "latency": { - "avg": 0.2375, - "min": 0.189, - "max": 0.286, - "values": [ - 0.189, - 0.286 - ], - "stddev": 0.04849999999999999 - }, - "packetsSent": 2, - "routers": [ - { - "ip": "10.241.134.75" - } - ] - } -] -``` - -{{< /collapse-content >}} - -{{% collapse-content title= "ICMP" level="h4" expanded=false %}} - -`.traceroute` -: Same structure as TCP traceroute - -`.request.host` -: Target host - -`.ping` -: Ping results - -`.latency.min`, `.latency.max`, `.latency.avg`, `.latency.stddev`, `.latency.values` -: Latency measurements (same as TCP) - -**Examples:** -```json -{ - "ping": { - "packetLossPercentage": 0, - "packetsReceived": 4, - "latency": { - "avg": 1.47375, - "min": 1.442, - "max": 1.516, - "values": [ - 1.467, - 1.442, - 1.47, - 1.516 - ], - "stddev": 0.02670557057993708 - }, - "resolvedIp": "18.245.199.70", - "packetsSent": 4, - "packetSize": 56 - } -} -``` - -{{< /collapse-content >}} - -{{% /tab %}} -{{% tab "Protocol tests" %}} - -{{% collapse-content title= "SSL" level="h4" expanded=false %}} - -`.cert` -: SSL certificate information - -`.cipher` -: Cipher suite used - -`.issuer` -: Certificate issuer - -`.subject` -: Certificate subject - -`.valid.from` -: Certificate valid from date - -`.valid.to` -: Certificate valid to date - -`.ocsp` -: OCSP (Online Certificate Status Protocol) information - -`.timings.handshake` -: SSL handshake timing - -**Examples:** -```json - "cipher": TLS_AES_128_GCM_SHA256, - "issuer": { - "C": "US", - "CN": "DigiCert Global G2 TLS RSA SHA256 2020 CA1", - "O": "DigiCert Inc" - }, -``` -```json -{ - "issuer": { - "C": "US", - "CN": "DigiCert Global G2 TLS RSA SHA256 2020 CA1", - "O": "DigiCert Inc" - }, - "valid.from": 1751414400000, //milliseconds - "valid.to": 1783036799000 //milliseconds -} -``` - -{{< /collapse-content >}} - -{{% collapse-content title= "DNS" level="h4" expanded=false %}} - -`.response.records.type` -: DNS record type - -`.response.records.values` -: DNS record values - -**Examples:** -```json -{ - "dns": { - "response": { - "records": { - "type": "A", - "values": ["192.0.2.1", "192.0.2.2"] - } - } - } -} -``` - -{{< /collapse-content >}} - -{{% /tab %}} -{{% tab "Step summary" %}} +{{% /collapse-content %}} -**Step Summary:** -- `.result.steps.` - - `.id`, `.status`, `.type`, `.duration`, `.description`, `.failure.message`, `.code`, `.url` - -The step summary contains the same data as described in [steps](#variables-extracted-by-steps), but you can access it in several ways: - -By step index (0-based): -- `.steps.0` - first step -- `.steps.1` - second step -- `.steps.-1` - last step -- `.steps.-2` - step before last - -By step name: -- `.steps[Click button]` - -By step id: -- `.steps.abc-def-ghi` - -Then you access the data as usual, for example: -- `.steps.-1.status` -- `.steps[Click button].status` -- `.steps.abc-def-ghi.status` - -**Summary Data:** -- `.count.steps.{total,completed}`, `.count.errors`, `.count.hops` (for example, `4`) - -**Service Tag:** -If `service` tag is set: -- `{{service.name}}` -- `{{service.team}}` -- `{{service.docs}}`, `{{service.links}}` - -**Examples**: -```json -{ - "service.name": "API Server", - "service.team": "Backend team", - "service.docs": "https://docs.datadoghq.com/api/" -} -``` - -{{% /tab %}} -{{< /tabs >}} +## Step data +For detailed template variables related to individual test steps, including browser tests, mobile tests, API tests, network tests, and protocol tests, see [Step Data Template Variables][1]. ## Further Reading {{< partial name="whats-next/whats-next.html" >}} + +[1]: /synthetics/notifications/step_data_variables/ diff --git a/layouts/partials/nav/left-nav.html b/layouts/partials/nav/left-nav.html index e7be72bb38d..aa1169ff971 100644 --- a/layouts/partials/nav/left-nav.html +++ b/layouts/partials/nav/left-nav.html @@ -69,7 +69,7 @@