Synthetics Architecture
Statux Synthetics is a synthetic monitoring product that provides uptime monitoring and alerting for HTTP/HTTPS endpoints and TCP services.
Overview
The Synthetics API (apps/synthetics/) runs on port 3002 and is available at synthetics-api.statux.io.
Core Concepts
Checks
A Check defines what to monitor and how:
- Check Types: HTTP, HTTPS, TCP
- Targets: URLs for HTTP/HTTPS,
host:portfor TCP - Intervals: 30 seconds to 30 minutes
- Regions: AWS regions for distributed checks
- Relays: Private agents for internal network monitoring
Relays
Relays are private agents that can be deployed inside your network to monitor internal services:
- Connect to the API via secure token authentication
- Poll for assigned checks on a schedule
- Submit results back to the API
- Support heartbeat monitoring for connectivity status
Results
Check Results capture execution outcomes:
- Response time (ms)
- HTTP status codes
- TLS certificate info
- Error messages for failures
- Execution timestamps
Module Structure
apps/synthetics/src/
├── modules/
│ ├── checks/ # Check CRUD and querying
│ ├── results/ # Check result storage and queries
│ ├── relays/ # Private relay management
│ ├── execution/ # Public check execution engine
│ ├── aggregation/ # Metrics aggregation and S3 archival
│ ├── webhooks/ # Webhook notifications
│ ├── analytics/ # Usage analytics
│ ├── projects/ # Project management
│ ├── organizations/ # Organization management
│ ├── users/ # User access management
│ └── product-access/ # Product subscription access
├── entities/ # TypeORM entities
├── migrations/ # Database migrations
└── main.ts # Application bootstrap
Key Entities
Check Entity
@Entity({ schema: 'synthetics', name: 'checks' })
export class Check extends BaseEntity {
projectId: string;
name: string;
checkType: CheckType; // http, https, tcp
target: string; // URL or host:port
httpMethod: HttpMethod; // GET, POST, HEAD
expectedStatusCode: number;
intervalSeconds: number;
timeoutMs: number;
regions: string[]; // AWS region codes
relayId: string | null; // Private relay assignment
currentStatus: CheckStatus; // up, down, degraded, unknown
consecutiveFailures: number;
failureThreshold: number;
recoveryThreshold: number;
}
Relay Entity
@Entity({ schema: 'synthetics', name: 'relays' })
export class Relay extends BaseEntity {
projectId: string;
name: string;
authToken: string; // Hashed token
authTokenPrefix: string; // First 12 chars for identification
status: RelayStatus; // active, inactive, disconnected
relayVersion: string;
lastHeartbeatAt: Date;
}
API Patterns
Check Lifecycle
- Create Check: Validate target format, set default regions
- Execution: Either via public regions or private relay
- Result Processing: Update check state based on thresholds
- Alerting: Fire webhooks on status changes
Relay Authentication
Relays authenticate using bearer tokens:
// Token format: stx_relay_{64_char_hex}
// Stored as SHA-256 hash in database
const rawToken = `stx_relay_${randomBytes(32).toString('hex')}`;
const tokenHash = createHash('sha256').update(rawToken).digest('hex');
The RelayAuthGuard validates tokens and attaches the relay to the request.
Status State Machine
UNKNOWN → UP (on first successful check)
UP → DOWN (after failureThreshold consecutive failures)
DOWN → UP (after recoveryThreshold consecutive successes)
UP/DOWN → DEGRADED (on slow response or partial failure)
Testing
Run tests with:
npm run test:synthetics
Test files are located alongside service files:
checks.service.spec.tsrelays.service.spec.tsresults.service.spec.ts
Database
Uses the synthetics schema in PostgreSQL. All entities follow the snake_case naming convention for database columns.
Key Tables
| Table | Purpose |
|---|---|
projects | Project configuration |
checks | Check definitions |
check_results | Execution results |
relays | Private relay agents |
webhook_subscriptions | Notification webhooks |
users | Project user access |