Configuration
The Synthetic Exporter uses a declarative YAML configuration file (typically config.yaml). This file dictates the target system, the static APIs to check, and the complex UI journey to execute.
Structure Overview
A basic config.yaml looks like this:
service: "my-e-commerce-app"
api_endpoints:
- "https://my-e-commerce-app.example.com/api/health"
- "https://my-e-commerce-app.example.com/api/v1/products"
scenarios:
- name: "Login Flow"
steps:
- name: "navigate_to_login"
action: "goto"
target: "https://my-e-commerce-app.example.com/login"
error_type_name: "navigation_failed"Global Settings
| Field | Description |
|---|---|
service | The primary identifier for this target. It is attached as the service label on all Prometheus metrics, allowing for multi-tenant monitoring. |
api_endpoints | A list of URLs. The exporter will perform a simple HTTP GET on each, recording the status code and TLS certificate expiration date. |
scenarios | A list of scenarios. Each scenario is an independent multi-step headless UI journey. |
UI Scenarios and Steps
The scenarios array defines independent journeys. Inside each scenario, the steps array defines the sequential actions Playwright will take in the browser. If any step fails, the scenario stops, and a failure metric is recorded for that specific scenario and step.
Each step accepts the following fields:
name: A descriptive name for the stage (e.g.,fill_password).action: The Playwright action to perform. See Supported Actions.target: The URL (forgoto), CSS/XPath selector (for interactions), or file path (forscreenshot).value: (Optional) The text to input. Often used withfill.error_type_name: A custom error label that will be emitted to Prometheus if this stage fails. Very useful for grouping alerts (e.g.,dashboard_timeoutvslogin_failed).
Supported Actions
| Action | Target | Value | Description |
|---|---|---|---|
goto | URL | - | Navigates the browser to the specified URL and waits for network idle. |
fill | Selector | Text | Types the value into the element matching the target selector. |
click | Selector | - | Clicks the element matching the target selector. |
wait_for_selector | Selector | - | Pauses execution until the element matching the target selector is visible on screen. |
screenshot | File path | - | Takes a screenshot of the current page and saves it to the target path. |
Secret Resolution
To ensure security, the exporter natively supports resolving environment variables at runtime.
Any value string that exactly matches the pattern ${VARIABLE_NAME} will be replaced with the value of that environment variable.
- name: "fill_password"
action: "fill"
target: "xpath=//input[@id='password']"
# The actual password is injected from the host OS environment
value: "${APP_PASSWORD}"
error_type_name: "password_field_missing"WARNING
Ensure the environment variables are correctly injected into the exporter's process (e.g., via Docker -e flags or Kubernetes Secrets), otherwise the value will be empty, causing the UI journey to fail.
Best Practices for Scenarios
When designing your synthetic monitoring scenarios, consider the following best practices to maximize the value of your alerts.
1. Which Scenarios to Write?
Write scenarios that represent the critical path of your business. These act as strong indicators of your product's health.
- E-Commerce: Write a scenario that logs in, searches for a product, adds it to the cart, and verifies the cart badge updates.
- SaaS Platform: Write a scenario that logs in, navigates to the main dashboard, and creates a new test resource.
- Content Site: Write a scenario that navigates to an article and verifies that the main content and comment section load.
Avoid writing tests for every minor feature. Focus on flows where, if they break, you are losing money or users are entirely blocked.
2. How to Find XPaths
The easiest way to find reliable XPaths for your target fields is using your browser's Developer Tools:
- Open your target website in Chrome or Edge.
- Right-click the element you want to interact with and select Inspect.
- In the Elements panel, right-click the highlighted HTML node.
- Select Copy -> Copy XPath (or Copy full XPath).
- Prepend
xpath=to the copied string in yourconfig.yaml(e.g.,xpath=//*[@id="login-btn"]).
TIP
For more robust tests that survive UI changes, prefer using data-testid attributes (e.g., xpath=//button[@data-testid='submit']) rather than complex hierarchical XPaths.
3. Choosing an error_type_name
The error_type_name label is directly attached to the Prometheus metric when a step fails. You should choose names that are actionable and specific.
- Good:
login_button_missing,checkout_timeout,invalid_credentials_error_shown - Bad:
step_failed,error_1,ui_broken
By using specific names, your Prometheus alerts (e.g., in Alertmanager) will instantly tell the on-call engineer exactly what broke without them even needing to open the Grafana dashboard.
