ZenPlus APM

Synthetic scenarios

Scripted multi-step user journeys run from the appliance on a schedule, with assertions and variable extraction, so a broken workflow is caught before a customer finds it.

Applies to ZenPlus 1.6.0 Updated 2026-08-06 Audience Operators + QA Reading time ~9 min

01 What they are for #

Everything else in APM is passive: it tells you about traffic that already happened. That leaves two gaps. At 3 a.m. there may be no traffic to observe, and some failures — a login that returns 200 with an empty token, a checkout that succeeds but writes nothing — look perfectly healthy from the outside.

A synthetic scenario is an active check: a scripted sequence of HTTP steps with assertions, executed by the appliance on a fixed interval. It fails loudly whether or not anyone is using the system.

02 Anatomy of a scenario #

Steps
Up to 20 HTTP requests executed in order. Each has a name, method, URL, optional headers and body, assertions, and extractions. Execution stops at the first failing step — there is no point asserting on a checkout when login already failed.
Variables
Key/value pairs available to every step as in URLs, headers and bodies.
Assertions
What must be true for a step to pass.
Extractions
Values pulled out of a response and stored as variables for later steps — how a session token flows from login to checkout.
Check interval
15 seconds to 24 hours.
Timeout
1 to 120 seconds per step.
Retries
0 to 5. A retry runs the whole scenario again before recording a failure, which suppresses single-packet-loss noise.
Verify TLS
Turn off only for internal endpoints with self-signed certificates.

03 Assertions #

TypeOperatorsExample
status_codeeq, neq, lt, lte, gt, gtestatus_code eq 200
latency_mslt, lte, gt, gte, eq, neqlatency_ms lt 2000
body_containssubstring matchbody contains Order confirmed
json_pathexists, eq, neq, lt, lte, gt, gte, containsuser.roles[0].name eq admin

JSON paths use dot and bracket notation — data.items[0].id. Numeric comparisons are applied when both sides look numeric, so json_path total gt 0 behaves as you would expect.

Assert on meaning, not just on 200

A login endpoint returning 200 with {"token": null} is broken. status_code eq 200 passes; json_path token exists catches it. The whole value of synthetics is asserting the thing that actually matters.

04 A worked example #

A three-step checkout journey. Step 1 authenticates and extracts a token, step 2 uses it, step 3 checks the result reflects the change.

#StepAssertionsExtracts
1POST /api/auth/login with test credentialsstatus_code eq 200
json_path access_token exists
token ← json access_token
2POST /api/cart/items, header Authorization: Bearer status_code eq 201
latency_ms lt 2000
cart_id ← json id
3GET /api/cart/status_code eq 200
json_path items[0].sku eq TEST-SKU
Use a dedicated test account

Scenarios run on their interval forever. Point them at a purpose-built account and test data, never at a real customer record, and make sure a scenario that creates something also cleans it up or writes somewhere disposable.

05 Running and reading results #

Run now executes immediately and returns full step-level detail — status code, latency, every assertion with pass/fail and the reason, and a snippet of the response body. Use it while authoring; it is far faster than waiting for the next scheduled tick.

Scheduled runs record: overall status (up/down), total duration, steps passed of steps total, which step failed and why. History is kept for 90 days, and the list shows uptime percentage, run count and average duration over the selected window.

Where execution happens

Scenarios run from the appliance, so they see your network the way the appliance does. That is right for internal services, and it means a scenario against a public endpoint is not measuring what a customer in another region experiences.

06 Alerting and scheduling #

A scenario that transitions to down raises an alert on its configured channels, and clears when it passes again. Only one appliance worker executes each tick, so a multi-worker deployment does not multiply your synthetic traffic.

Choose the interval by how fast you need to know: 60 seconds for revenue-critical journeys, 5 to 15 minutes for everything else. Every scenario is real traffic against your own systems — a 15-second interval on a heavy flow is a load test you did not mean to write.