Try it free

Upgrade from Classic service metrics to Grail

  • Dynatrace Classic
  • Upgrade guide
  • 5-min read

Use this guide to convert Classic service metric selectors to Dynatrace Query Language (DQL) and understand how each service metric maps to its Grail equivalent, so you can smoothly transition to Latest Dynatrace.

Why upgrade?

  • Simplified metric landscape: Over 100 Classic service metrics are consolidated into a handful of Metrics on Grail. Instead of tracking separate metric keys for each variant, you use a single metric with dimensions and filters to reach the same level of detail.
  • Advanced query capabilities: Metrics on Grail use DQL, which lets you filter, aggregate, join, and transform data in a single query.
  • Access in latest Dynatrace apps: Metrics on Grail work natively in Notebooks Notebooks, Dashboards Dashboards, and other Dynatrace apps, giving you additional analysis and visualization options.
  • Flexible endpoint analysis: Endpoints replace key requests in Grail. Unlike key requests, endpoints don't require upfront configuration, as you filter by endpoint.name directly in your query.

What will you do?

  • Look up your Classic service metric key and find its Grail equivalent.
  • Adapt your metric selector queries to DQL using the provided examples.
  • For convergent metrics, apply dimensions and filters to a single Grail-based metric to reach the same granularity as your Classic metric.
  • Identify which Classic metrics are unsupported and explore the available DQL approximations.

Before you begin

Prerequisites

  • A list of your existing Classic metric selectors that use Classic service metrics.
  • Access to Notebooks Notebooks or Dashboards Dashboards to test and validate your converted DQL queries.

Prior knowledge

  • Familiarity with Metrics Classic and metric selector syntax.
  • Basic understanding of DQL concepts.
  • Familiarity with creating DQL queries in Notebooks Notebooks or Dashboards Dashboards.
  • Understanding of the metric mapping types used in this guide: convergent and unsupported.

How to upgrade

To upgrade your Classic service metric selectors to DQL:

  1. Automatically convert your metric selectors using the built-in converter in Data Explorer.
  2. For metrics that can't be converted automatically, convert manually using the mapping tables.
  3. Verify your converted queries to confirm results match your expected Classic metric data.

Because there isn't an exact, one-to-one mapping between Classic metric selectors and DQL queries, some queries will require manual adjustments during the conversion.

Automatically convert

Use Data Explorer Data Explorer and Dashboards Dashboards to convert your existing Classic metric selector queries into DQL.

  1. Go to Data Explorer Data Explorer to create and run your query.

    Data Explorer showing a Classic metric selector query in standard mode
    Data Explorer showing a Classic metric selector query in standard mode
  2. Select Open with… in the upper-right corner of the Result section.

  3. Follow the displayed instructions to:

    • Add the DQL query as a tile to a new or existing Dashboard.
    • Open the DQL query in a new or existing Notebook.
  4. View the query in Dashboards Dashboards or Notebooks Notebooks and verify the output.

    Notebook showing the automatically converted DQL query result
    Notebook showing the automatically converted DQL query result

Here is a before-and-after of the Classic metric selector and the DQL query:

  • Classic metric selector

    builtin:host.cpu.usage:splitBy("dt.entity.host"):sort(value(auto,descending)):limit(20)
  • Equivalent DQL query

    timeseries usage = avg(dt.host.cpu.usage), by: { dt.entity.host }
    | fieldsAdd entityName(dt.entity.host)
    | sort arrayAvg(usage) desc
    | limit 20

Manually convert

If your Classic metric selector is not automatically convertible, you can manually convert your Classic metric selector to a DQL query.

  1. Find your Classic metric key in the metric key reference below or in Built-in Metrics on Grail.
  2. Identify its Grail equivalent and the dimensions or filters needed to match your Classic metric.
  3. Replace your Classic metric selector with the corresponding DQL query, using the examples in Convergent metrics and Unsupported metrics as a reference.

Verify your converted queries

Whether you've automatically or manually converted your Classic metrics, run your DQL queries in Notebooks Notebooks or Dashboards Dashboards and verify that the results align with your expected Classic metric data.

Metric key reference

The following tables list Classic service metric keys and their Grail equivalents, when available.

  • Convergent metrics have a direct Grail equivalent.
  • Unsupported metrics have no dedicated Grail metric and require either an OpenPipeline- or DQL-based alternative.

For information about metric mapping, see New concepts.

Convergent metrics

The sections below group together different convergent metrics, with a DQL example showing how to filter by the relevant dimension and a mapping table listing the Classic keys.

If you don't find the required Classic metric key in the tables below, refer to Built-in Metrics on Grail.

HTTP status codes

To convert Classic service metrics for HTTP 4xx and HTTP 5xx error responses, use the dt.service.request.count Grail-based metric filtered by http.response.status_code.

DQL query example: HTTP 400 status code

The following DQL query returns the rate of requests with an HTTP 4xx response status code. This is equivalent to the Classic metric builtin:service.errors.fourxx.rate.

// calculate HTTP 4xx response status code request rate
timeseries {total = sum(dt.service.request.count), interval:1m}
| join [
timeseries {fourXX = sum(dt.service.request.count, default: 0.0), interval:1m},
filter: http.response.status_code >= 400 and http.response.status_code<=499
], kind:leftOuter, prefix: "httpState.", on:{ timeframe }
| fieldsAdd {rate4xx = httpState.fourXX[] / total[] * 100}
| fields rate4xx, timeframe, interval
DQL query example: 5xx status code

The following DQL query returns the rate of requests with HTTP response status code 5xx. This is equivalent to the Classic metric builtin:service.errors.fivexx.rate.

// calculate HTTP 5xx response status code request rate
timeseries {total = sum(dt.service.request.count), interval:1m}
| join [
timeseries {fiveXX = sum(dt.service.request.count, default: 0.0), interval:1m},
filter:http.response.status_code >= 500 and http.response.status_code <= 599
], kind:leftOuter, prefix: "httpState.", on:{ timeframe }
| fieldsAdd {rate5xx = httpState.fiveXX[] / total[] * 100}
| fields rate5xx, timeframe, interval
Metric key (Classic)Metric key (Grail)Filter by

builtin:service.errors.fourxx.rate

dt.service.request.count

filter:{http.response.status_code >= 400 and http.response.status_code <= 499}

builtin:service.errors.fivexx.rate

dt.service.request.count

filter:{http.response.status_code >= 500 and http.response.status_code <= 599}

Failure and success

To convert the Classic service metrics that track the count and rate of successful versus failed requests, use the dt.service.request.count Grail-based metric filtered by failed == false or failed == true.

DQL query example

The following DQL query returns the count of successful requests to MY_SERVICE-00000—an equivalent of builtin:service.errors.total.successCount.

timeseries sum(dt.service.request.count), interval:1m,
by:{dt.entity.service, failed},
filter:{
dt.entity.service == "<MY_SERVICE-00000>"
and failed == false
}
Metric key (Classic)Metric key (Grail)Filter by
  • builtin:service.errors.client.successCount
  • builtin:service.errors.server.successCount
  • builtin:service.errors.total.successCount
  • builtin:service.successes.server.rate
  • builtin:service.errors.server.count
  • builtin:service.errors.server.rate
  • builtin:service.errors.total.rate

dt.service.request.count

  • filter:{failed == false}
  • filter:{failed == true}

Failure and success of HTTP error responses

To convert Classic service metrics that track the count of HTTP error responses and their complements (non-error requests), use the dt.service.request.count Grail-based metric filtered by both failed and http.response.status_code.

DQL query example

The following DQL query returns the count of failed requests to MY_SERVICE-00000 with HTTP response status code 4xx—an equivalent of builtin:service.errors.fourxx.count.

timeseries sum(dt.service.request.count), interval:1m,
by:{dt.entity.service, failed, http.response.status_code},
filter:{
dt.entity.service == "<MY_SERVICE-00000>"
and failed == true
and http.response.status_code >= 400
and http.response.status_code <= 499
}
Metric key (Classic)Metric key (Grail)Filter by
  • builtin:service.errors.fourxx.count
  • builtin:service.errors.fourxx.successCount
  • builtin:service.errors.fivexx.count
  • builtin:service.errors.fivexx.successCount

dt.service.request.count

Use both filters:

  • filter:{failed == false} or filter:{failed == true}
  • filter:{http.response.status_code >= 400 and http.response.status_code <= 499} or filter:{http.response.status_code >= 500 and http.response.status_code <= 599}

Key requests

To convert Classic service metrics related to key requests, use the dt.service.request.failure_count, dt.service.request.response_time, and dt.service.request.count Grail-based metrics filtered by different parameters.

From key requests to endpoints

Endpoints replace key requests in Grail. To learn more about endpoint.name, see Semantic Dictionary.

DQL query example

The following DQL query example returns the total number of failed requests to /orange.jsf with an HTTP 5xx response status code. This is the equivalent of builtin:service.keyRequest.errors.fivexx.rate.

timeseries sum(dt.service.request.count), interval:1m,
by:{endpoint.name, http.response.status_code},
filter:{
endpoint.name == "/orange.jsf"
and http.response.status_code >= 500
and http.response.status_code <= 599
}
Metric key (Classic)Metric key (Grail)Filter by
  • builtin:service.keyRequest.errors.client.count
  • builtin:service.keyRequest.errors.client.rate

dt.service.request.failure_count

filter:{endpoint.name == "<key_request_name>"}

  • builtin:service.keyRequest.response.client
  • builtin:service.keyRequest.response.server
  • builtin:service.keyRequest.response.time

dt.service.request.response_time

filter:{endpoint.name == "<key_request_name>"}

  • builtin:service.keyRequest.count.client
  • builtin:service.keyRequest.count.server
  • builtin:service.keyRequest.count.total

dt.service.request.count

filter:{endpoint.name == "<key_request_name>"}

  • builtin:service.keyRequest.errors.client.successCount
  • builtin:service.keyRequest.errors.server.successCount
  • builtin:service.keyRequest.successes.server.rate
  • builtin:service.keyRequest.errors.server.count
  • builtin:service.keyRequest.errors.server.rate

dt.service.request.count

  • filter:{endpoint.name == "<key_request_name>"}
  • filter:{failed == false} or filter:{failed == true}
  • builtin:service.keyRequest.errors.fivexx.rate
  • builtin:service.keyRequest.errors.fourxx.rate

dt.service.request.count

  • filter:{endpoint.name == "<key_request_name>"}
  • filter:{http.response.status_code >= 500 and http.response.status_code <= 599} or filter:{http.response.status_code >= 400 and http.response.status_code <= 499}
  • builtin:service.keyRequest.errors.fivexx.successCount
  • builtin:service.keyRequest.errors.fivexx.count
  • builtin:service.keyRequest.errors.fourxx.successCount
  • builtin:service.keyRequest.errors.fourxx.count

dt.service.request.count

  • filter:{endpoint.name == "<key_request_name>"}
  • filter:{failed == false} or filter:{failed == true}
  • filter:{http.response.status_code >= 500 and http.response.status_code <= 599} or filter:{http.response.status_code >= 400 and http.response.status_code <= 499}

Database child call count

To convert the builtin:service.dbChildCallCount metric, use the dt.service.database.query.count Grail metric.

DQL query example

The following DQL query returns the number of database calls made by MY_SERVICE-00000. This is the equivalent of builtin:service.dbChildCallCount.

timeseries calls = sum(dt.service.database.query.count), interval:1m,
by: { dt.smartscape.service, db.system, db.namespace },
filter: { dt.smartscape.service == "<MY_SERVICE-00000>" }
Metric key (Classic)Metric key (Grail)Filter by
  • builtin:service.dbChildCallCount

dt.service.database.query.count

None

Unsupported metrics

The Classic service metrics in this section have no direct equivalent in Grail.

  • To approximate some of these metrics, you can use OpenPipeline to extract custom metrics from span data. For details, see Extract metrics from spans and distributed traces.

  • The database metrics can be approximated using spans.

    DQL query example for Classic database metrics

    The following DQL query returns the count and the duration of database spans for each database service, and can be used similarly to the Classic metric builtin:service.dbChildCallTime.

    fetch spans, samplingRatio:1
    // get only database client span
    | filter span.kind == "client" and isNotNull(db.query.text)
    // calculate how frequently each span is sampled
    | fieldsAdd sampling.probability = (power(2, 56) - coalesce(sampling.threshold, 0)) * power(2, -56)
    | fieldsAdd sampling.multiplicity = 1/sampling.probability
    // calculate the number of database spans after sampling
    | fieldsAdd multiplicity = coalesce(sampling.multiplicity, 1)
    * coalesce(aggregation.count, 1)
    * dt.system.sampling_ratio
    // calculate the duration of database spans after sampling
    | fieldsAdd duration = coalesce(aggregation.duration_sum / aggregation.count, duration)
    // aggregate records with the same values, by service ID
    | summarize {
    operation_count_extrapolated = sum(multiplicity),
    operation_duration_avg_extrapolated = sum(duration * multiplicity) / sum(multiplicity)
    }, by: { entityName(dt.entity.service), db.namespace }

Database

  • builtin:service.dbChildCallTime
  • builtin:service.keyRequest.dbChildCallCount
  • builtin:service.keyRequest.dbChildCallTime
  • builtin:service.keyRequest.nonDbChildCallCount
  • builtin:service.keyRequest.nonDbChildCallTime
  • builtin:service.nonDbChildCallCount
  • builtin:service.nonDbChildCallTime

CPU

  • builtin:service.cpu.instance
  • builtin:service.cpu.perRequest
  • builtin:service.cpu.time
  • builtin:service.ioTime
  • builtin:service.keyRequest.cpu.perRequest
  • builtin:service.keyRequest.cpu.time
  • builtin:service.keyRequest.ioTime
  • builtin:service.keyRequest.lockTime
  • builtin:service.keyRequest.waitTime
  • builtin:service.lockTime
  • builtin:service.waitTime

Service method groups

  • builtin:service.cpu.group.perRequest
  • builtin:service.cpu.group.time
  • builtin:service.errors.group.client.count
  • builtin:service.errors.group.client.rate
  • builtin:service.errors.group.client.successCount
  • builtin:service.errors.group.server.count
  • builtin:service.errors.group.server.rate
  • builtin:service.errors.group.server.successCount
  • builtin:service.errors.group.total.count
  • builtin:service.errors.group.total.rate
  • builtin:service.errors.group.total.successCount
  • builtin:service.response.group.client
  • builtin:service.response.group.server
  • builtin:service.totalProcessingTime.group.totalProcessingTime

Other

  • builtin:service.calledFromNetworksCount
  • builtin:service.keyRequest.totalProcessingTime
  • builtin:service.totalProcessingTime

Related topics

  • Use DQL queries
  • Notebooks
Related tags
Dynatrace Platform