Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Observability

Prometheus metrics

Substrukt exposes a /metrics endpoint in Prometheus text format. This endpoint is unauthenticated (intended for internal scraping by your monitoring stack).

Available metrics

MetricTypeLabelsDescription
http_requests_totalCountermethod, path, statusTotal HTTP requests
http_request_duration_secondsHistogrammethod, pathRequest latency
http_connections_activeGaugeCurrently active connections
content_entries_totalGaugeschemaNumber of entries per schema
uploads_totalGaugeTotal uploaded files
uploads_size_bytesGaugeTotal size of all uploads

Content and upload gauges are updated on each scrape (when /metrics is requested).

Scraping

Add Substrukt to your Prometheus configuration:

scrape_configs:
  - job_name: 'substrukt'
    static_configs:
      - targets: ['localhost:3000']
    metrics_path: '/metrics'
    scrape_interval: 30s

Example output

# HELP http_requests_total Total HTTP requests
http_requests_total{method="GET",path="/",status="200"} 42
http_requests_total{method="POST",path="/content/{schema_slug}/{entry_id}",status="302"} 7

# HELP http_request_duration_seconds Request duration in seconds
http_request_duration_seconds_bucket{method="GET",path="/",le="0.01"} 40

# HELP content_entries_total Content entries per schema
content_entries_total{schema="blog-posts"} 15
content_entries_total{schema="faq"} 8

# HELP uploads_total Total uploaded files
uploads_total 23

# HELP uploads_size_bytes Total upload storage in bytes
uploads_size_bytes 15728640

Audit logging

Substrukt maintains an audit log in a separate SQLite database (audit.db in the data directory). Audit writes are asynchronous – they do not block request handling.

Logged actions

ActionResource typeWhen
loginsessionUser logs in
logoutsessionUser logs out
user_createuserAdmin account created during setup
schema_createschemaSchema created via UI
schema_updateschemaSchema updated via UI
schema_deleteschemaSchema deleted via UI
content_createcontentEntry created via UI or API
content_updatecontentEntry updated via UI or API
content_deletecontentEntry deleted via UI or API
token_createapi_tokenAPI token created
token_deleteapi_tokenAPI token deleted
importbundleContent bundle imported
exportbundleContent bundle exported
webhook_firewebhookWebhook fired (with success/failure status)

Audit log schema

Each audit entry contains:

ColumnDescription
timestampISO 8601 timestamp
actorUser ID, "api", or "system"
actionAction name (see table above)
resource_typeType of resource affected
resource_idIdentifier of the affected resource
detailsOptional JSON string with additional context

Viewing the audit log

The audit log is viewable in the web UI at Settings > Audit Log. You can also query it directly with SQLite:

sqlite3 data/audit.db "SELECT timestamp, actor, action, resource_type, resource_id FROM audit_log ORDER BY timestamp DESC LIMIT 20"

Structured logging

HTTP request/response tracing is provided by tower-http::TraceLayer. Each request is logged with method, path, status code, and duration.

Control log verbosity with the RUST_LOG environment variable:

RUST_LOG=substrukt=debug,tower_http=debug ./substrukt serve