24 Feb 2026 12:28 PM
Hi,
Yes, you can do this in DQL: compute 2xx and 5xx counts over the last 15 minutes, calculate the ratio, and filter when it exceeds 1%. Below is a working example based on spans using http.response.status_code. The important bit is using named optional parameters (else:) in if(), otherwise you may hit “Too many positional parameters…”.
fetch spans
| filter request.is_root_span == true
| filter isNotNull(http.response.status_code)
| makeTimeseries {
r2xx = sum(if(http.response.status_code >= 200 and http.response.status_code <= 299, 1, else: 0)),
r5xx = sum(if(http.response.status_code >= 500 and http.response.status_code <= 599, 1, else: 0))
},
by: { dt.entity.service },
interval: 1m,
from: -15m
| fieldsAdd rate_pct = 100 * r5xx[] / if(r2xx[] == 0, null, else: r2xx[])
| filter arrayMax(rate_pct) > 1
| sort arrayMax(rate_pct) descWhat it returns: only services where, in the last 15 minutes (1-minute buckets), the maximum 5xx/2xx ratio exceeds 1%.
If you want to triiger it, like trigger an error/alert, DQL itself won’t throw an error, but you can:
27 Feb 2026 11:22 AM
Hello,
Thanks, if I want to go with a service (123) and its target url (xyz). Is that doable?
Thank you
27 Feb 2026 02:47 PM
Sure, in the long term, a custom metric created on spans is preferred or DQL on spans.
An OpenPipeline example, don't forget to add the http reponse status, so you can filter on it afterwards.
DQL query on spans:
fetch spans
| filter span.kind == "client" and dt.smartscape.service == toSmartscapeId("SERVICE-123") and http.url == "XYZ"
Depending on your service detection rules, if you have the target endpoint as a dedicated service (Service detection rules v1 external webrequest or webservice rules), it has a service with metrics directly.
24 Feb 2026 01:09 PM
@t_pawlak I would strongly discourage using DQL directly on spans for this purpose, especially if you need to define an anomaly detector (implies costs and needs to read data constantly). The metric dt.service.request.count contains the http.response.status.code dimension among other dimensions.
24 Feb 2026 01:16 PM
Thanks, agree. For detection/anomaly use-cases I’d also prefer a metric-based approach (lighter/cheaper than scanning spans). dt.service.request.count indeed exposes http.response.status.code.
In my tenant/context, however, DQL doesn’t allow fetch metrics (I get “metrics isn’t a valid data object”), so I can’t query that metric via DQL directly.
The practical solution is to configure a Metric event using the metric selector expression (5xx / 2xx over 15m) and use DQL on spans only for ad-hoc analysis / when metrics aren’t available.
24 Feb 2026 01:43 PM
It's timeseries command, not fetch.
A more complex command to query metrics and query 4xx/5xx as both timeseries and scalar values in a single timeseries command:
timeseries {
`requests`=sum(dt.service.request.count), `requests.total` = sum(dt.service.request.count, scalar: true)
, `4xx`=sum(dt.service.request.count, filter: http.response.status_code >= 400 and http.response.status_code < 500)
, `4xx_total` = sum(dt.service.request.count, filter: http.response.status_code >= 400 and http.response.status_code < 500, scalar: true)
, `5xx`=sum(dt.service.request.count, filter: http.response.status_code >= 500 and http.response.status_code < 600)
, `5xx_total` = sum(dt.service.request.count, filter: http.response.status_code >= 500 and http.response.status_code < 600, scalar: true)
}, union:true
, by: { dt.entity.service }
You just need to adjust filters and compute the ratio you want.
Featured Posts