DQL
Questions about Dynatrace Query Language
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

DQL - Execution

munawarhossain3
Contributor

Hello,

How can I achieve this with DQL?

Trigger an error if the 5XX error rate > 1% of the 2XX / 15m

I've a timeseries metric preceding to the above condition.

Thanks

MH

6 REPLIES 6

t_pawlak
Leader

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) desc

What 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:

  • run this in a Workflow on a schedule and if the result is not empty → notify / create an event,
  • or (if you already have this as a metric) use a metric event threshold (>1%).

Zrzut ekranu 2026-02-24 132735.jpg

Hello,

Thanks, if I want to go with a service (123) and its target url (xyz). Is that doable?

Thank you

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.
openpipeline.png

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.


Dynatrace Ambassador | Alanata a.s., Slovakia, Dynatrace Master Partner

Julius_Loman
DynaMight Legend
DynaMight Legend

@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.


Dynatrace Ambassador | Alanata a.s., Slovakia, Dynatrace Master Partner

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.

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.

Dynatrace Ambassador | Alanata a.s., Slovakia, Dynatrace Master Partner

Featured Posts