Dynatrace tips
Tips and workarounds from Dynatrace users for Dynatrace users.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Handling Metric Definition Changes in a Single DQL Timeseries

MaximilianoML
Champion

Sometimes, the definition of a metric changes over time. For example, an endpoint may initially be measured only by its name, but after a certain date you may need to restrict the calculation to specific services as well.

Instead of creating two separate dashboard tiles or manually changing the query depending on the selected timeframe, you can calculate both versions in the same timeseries query and then use a timestamp cutover to decide which one should be used for each datapoint.

The idea

In this example, the query calculates two versions of the same business metric:

  • TotalRequests_Old and FailedRequests_Old: used before the cutover date.
  • TotalRequests_New and FailedRequests_New: used after the cutover date, with additional dt.entity.service filtering.

The key part is this:

| fieldsAdd TotalRequests =
    if(
        datapointStart[] < toTimestamp("2026-03-31T23:00:00.000+01:00"),
        TotalRequests_Old[],
        else: TotalRequests_New[]
    )

| fieldsAdd FailedRequests =
    if(
        datapointStart[] < toTimestamp("2026-03-31T23:00:00.000+01:00"),
        FailedRequests_Old[],
        else: FailedRequests_New[]
    )

This allows the final metric to behave as one continuous calculation, even though the underlying filter logic changes after a specific point in time.

Why this is useful

This pattern is especially useful when you need to preserve historical reporting while adapting the query to a new architecture, renamed endpoints, split services, or improved filtering logic.

In this case, the query also limits the calculation to business hours:

| fieldsAdd TotalRequests_BH =
    if(
        getHour(datapointStart[], timezone: "CET") >= 9
        and getHour(datapointStart[], timezone: "CET") <= 16,
        TotalRequests[],
        else: null
    )

After that, it calculates the success average based only on business-hour traffic:

| fieldsAdd SucAvg =
    if(
        somaTotalRequests_BH > 0,
        (somaTotalRequests_BH - somaFailedRequests_BH) / somaTotalRequests_BH * 100,
        else: null
    )

Pro Tip

When you need to change the logic of a timeseries after a specific date, avoid trying to place start() directly inside the metric selector filter. Instead, calculate both metric versions first, expose datapointStart = start(), and then use if() to select the correct array values after the timeseries is created.

This keeps the visualization clean, avoids duplicated dashboard tiles, and lets you maintain a single historical metric line even when the filtering logic changes over time.

Max Lopes
1 REPLY 1

AntonPineiro
DynaMight Guru
DynaMight Guru

Thank you! :take_my_money:

❤️ Emacs ❤️ Vim ❤️ Bash ❤️ Perl

Featured Posts