Cloady Docs
API ReferenceEndpointsApplications

Query an app's metrics over a range

Runs a PromQL query at every step of a range against the app's own metrics, kept for 62 days, and returns Prometheus's answer unchanged: one `matrix` series per label set. Only the app's series are visible. The labels and series are queryAppMetrics'. A query the store refuses comes back with the store's own status and `error`. The path is the store's own, so a Grafana data source can point here too.

GET
/api/workspaces/{workspaceSlug}/apps/{appSlug}/prometheus/api/v1/query_range
AuthorizationBearer <token>

Personal API token (cldy_…)

In: header

Path Parameters

workspaceSlug*string
appSlug*string

Query Parameters

env?string

Value in

  • "production"
  • "preview"
  • "development"
region?string
query*string

A PromQL expression

Length1 <= length
start*string

Start of the range, as Unix seconds or RFC 3339

end*string

End of the range, as Unix seconds or RFC 3339

step*string

Seconds between points, or a duration such as 5m; at most 11,000 points per series

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/api/workspaces/string/apps/string/prometheus/api/v1/query_range?query=string&start=string&end=string&step=string"
{  "status": "string",  "data": {    "resultType": "string",    "result": [      null    ],    "property1": null,    "property2": null  },  "errorType": "string",  "error": "string",  "warnings": [    "string"  ],  "property1": null,  "property2": null}

Query an app's metrics GET

Runs a PromQL query at one instant against the app's own metrics, kept for 62 days, and returns Prometheus's answer unchanged. Only the app's series are visible, whatever the query selects. Every series carries `namespace`, the app's (getWorkspace returns each app's), and most carry `container`, the compose service, and `pod`. Resources: `container_cpu_usage_seconds_total`, `container_spec_cpu_quota` / `container_spec_cpu_period` (the CPU limit), `container_memory_working_set_bytes`, `container_spec_memory_limit_bytes`, `container_fs_reads_bytes_total`, `container_fs_writes_bytes_total`, `container_oom_events_total`, and `container_network_receive_bytes_total` / `container_network_transmit_bytes_total`, which carry only `pod`, so match them as `pod=~"<service>-[a-z0-9]+-[a-z0-9]+"`. Replicas: `kube_pod_container_status_ready`, `kube_pod_container_status_restarts_total`, `kube_pod_container_status_waiting_reason` and `kube_pod_container_status_last_terminated_reason` (`reason`), and `kube_deployment_spec_replicas` / `kube_deployment_status_replicas_available`, whose `deployment` is the service. Volumes: `kubelet_volume_stats_used_bytes` and `kubelet_volume_stats_capacity_bytes`, whose `persistentvolumeclaim` is the compose volume (each service's `volumes` in getWorkspace). Requests to the service the app's address routes to: `traefik_service_requests_total` (`code`, `method`, `protocol`) and `traefik_service_request_duration_seconds_bucket` (`le`). Uptime checks are `method="HEAD"`, so leave them out with `method!="HEAD"`, and a scale-to-zero function reports as `container="<service>-fn"`. Uptime: `cloady:probe_success:serving` (`kind="auto"` is the check of the app's address) and `cloady:service_up:serving`, each service's availability from 0 to 1. Spans, once the app sends OpenTelemetry traces: `traces_spanmetrics_calls_total` and `traces_spanmetrics_latency_bucket` (`span_name`, `span_kind`, `status_code`, `http_status`). RabbitMQ: `rabbitmq_detailed_queue_messages_ready`. Alert rules: `ALERTS` (`alertname`, `alertstate`, `container`, `cloady_metric`), whose `alertstate="firing"` samples are the app's incident history. queryAppMetricsRange runs a query over a range. A query the store refuses comes back with the store's own status and `error`. The path is the store's own, so a Grafana data source can point here too.

Query an app's logs GET

Runs a LogQL query over the app's own logs, kept for seven days, and returns Loki's answer unchanged: lines for a log query, series for a metric query. Streams: `{container="<service>"}` is each compose service's own output, with `pod` and a `detected_level` (error, critical, fatal, warn, info, debug, trace or unknown) to filter on as `| detected_level=~"error|critical|fatal"`; `{container="_events"}` holds the Kubernetes events about the app's objects as JSON (`kind`, `name`, `reason`, `type`, `msg`, `count`); `{container="_access", service="<service>"}` is the ingress access log of the service the app's address routes to, as Traefik's JSON (`RequestMethod`, `RequestPath`, `DownstreamStatus`, `Duration` in nanoseconds, `request_User-Agent`), with `route`, `method` and `status` as fields; and `{container="_rum", kind="pageview"}` with kinds `vital`, `error`, `net`, `signal`, `custom` and `session` holds browser monitoring, with `page`, `session`, `device`, `browser`, `os` and `country` as fields. Session recordings are kept apart: getBrowserSessionReplay reads them, with the developer role. A query the store refuses comes back with the store's own status and `error`. The path is the store's own, so a Grafana data source can point here too.