This guide provides insights into migrating Kubernetes metrics to Grail, so you can smoothly transition to Latest Dynatrace.
Notebooks,
Dashboards, and other Dynatrace apps.
Notebooks or
Dashboards to test and validate your converted DQL queries.
Notebooks or
Dashboards.To convert a Classic Kubernetes metric key:
The following tables list Classic Kubernetes metric keys and their Grail equivalents, organized by mapping type. Use the section that matches how your Classic metric maps to Grail.
For more information about metric mapping, see New concepts.
This section identifies Classic metrics that have a direct Grail equivalent. These identical metrics have the same level of detail and dimensions available. The only difference is the metric key.
| Classic metric key | Grail metric key |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The Grail metrics that supersede the Classic metrics often offer an increased level of detail compared to the Classic metrics.
builtin:kubernetes.containers and builtin:kubernetes.events, have been extended with additional dimensions.If a Grail metric now provides more detailed dimensions, such as at the container level, the data can be aggregated back to a higher level (such as workload levels). This aggregation can be useful if you want to re-use existing filters.
| Classic metric keys | Grail metric key |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The following DQL query returns the amount of memory consumed at the workload level, based on aggregated container-level data.
timeseries memory_working_set = sum(dt.kubernetes.container.memory_working_set)by: {k8s.cluster.name,k8s.namespace.name,k8s.workload.name}
The following Classic metric keys are replaced by a similar, but not identical, Grail metric. These metric keys are closely related and any deviations in the output are minor.
| Classic metric key | Grail metric key |
|---|---|
|
|
|
|
Dynatrace Classic metrics used millicores as the unit of measure, while the equivalent Grail metrics use nanoseconds per minute. Therefore, to get the same output value for these metrics, you'll need to use DQL to calculate the difference between these units. The sections below list the specific metrics and provide example DQL calculations.
Some Classic metric keys have a direct Grail equivalent, while for others you need to compute the output from multiple Grail metrics.
| Classic metric key | Grail metric keys |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
For each Classic metric key, this section provides the equivalent DQL queries, including calculations to convert to nanoseconds per minute.
builtin:containers.cpu.throttledMilliCorestimeseries {throttled_time = avg(dt.containers.cpu.throttled_time, rollup: sum, rate: 1m)}| fieldsAddns_per_min = 60 * 1000 * 1000 * 1000, milli_core_per_core = 1000| fieldsAddthrottled_milli_cores = throttled_time[] * milli_core_per_core / ns_per_min| summarize {throttled_milli_cores = sum(throttled_milli_cores[] )}, by: { timeframe, interval }
builtin:containers.cpu.usageUserMilliCorestimeseries {usage_user_time = avg(dt.containers.cpu.usage_user_time)}| fieldsAddns_per_min = 60 * 1000 * 1000 * 1000, milli_core_per_core = 1000| fieldsAddusage_user_milli_cores = usage_user_time[] * milli_core_per_core / ns_per_min| summarize {usage_user_milli_cores = sum(usage_user_milli_cores[] )}, by: { timeframe, interval }
builtin:containers.cpu.usageSystemMilliCorestimeseries {usage_system_time = avg(dt.containers.cpu.usage_system_time)}| fieldsAddns_per_min = 60 * 1000 * 1000 * 1000, milli_core_per_core = 1000| fieldsAddusage_system_milli_cores = usage_system_time[] * milli_core_per_core / ns_per_min| summarize {usage_system_milli_cores = sum(usage_system_milli_cores[] )}, by: { timeframe, interval }
builtin:containers.cpu.usageMilliCorestimeseries {usage_user_time = avg(dt.containers.cpu.usage_user_time), usage_system_time = avg(dt.containers.cpu.usage_system_time)}| fieldsAddns_per_min = 60 * 1000 * 1000 * 1000, milli_core_per_core = 1000| fieldsAddusage_milli_cores = (usage_user_time[] + usage_system_time[] )* milli_core_per_core / ns_per_min| summarize {usage_milli_cores = sum(usage_milli_cores[] )}, by: { timeframe, interval }
builtin:containers.cpu.usagePercenttimeseries {// for total usage, user and system cpu usage are addeduserCpuUsage = avg(dt.containers.cpu.usage_user_time), systemCpuUsage = avg(dt.containers.cpu.usage_system_time)// cpu logical counts are the fallback, if the throttling ratio doesn't exist, cpuLogicalCount = avg(dt.containers.cpu.logical_cores)}// filter statement ...// leftOuter join allows the throttling ratio to be null| join [timeseries {throttlingRatio = avg(dt.containers.cpu.throttling_ratio)// same filter statement as above ...}], on: { interval, timeframe}, fields: { throttlingRatio}, kind:leftOuter| fieldsAdd// sum of system and user cpu usagenumerator = userCpuUsage[] + systemCpuUsage[]// throttling ratio, or as a fallback cpu logical count., denominator = coalesce(throttlingRatio, cpuLogicalCount), nanoseconds_per_minute = 60 * 1000 * 1000 * 1000| fieldsinterval, timeframe, cpuUsagePercent = 100.0 * numerator[] / ( denominator[] * nanoseconds_per_minute)
builtin:containers.cpu.usageTimetimeseries {usageUserTime = avg(dt.containers.cpu.usage_user_time), usageSystemTime = avg(dt.containers.cpu.usage_system_time)}, by: { dt.entity.container_group_instance},| fieldsinterval, timeframe, usageTime = usageSystemTime[] + usageUserTime[]
builtin:containers.memory.limitPercenttimeseries {limit_bytes = avg(dt.containers.memory.limit_bytes),physical_total_bytes = avg(dt.containers.memory.physical_total_bytes)}| fieldsAddlimit_percent = (limit_bytes[] / physical_total_bytes[] ) * 100| summarize {limit_percent = sum(limit_percent[] )}, by: { timeframe, interval }
builtin:containers.memory.usagePercenttimeseries {memoryLimits = avg(dt.containers.memory.limit_bytes), totalPhysicalMemory = avg(dt.containers.memory.physical_total_bytes), residentSetBytes = avg(dt.containers.memory.resident_set_bytes)}, by: { dt.entity.container_group_instance}| fieldsAdddenominator = if (arrayFirst(memoryLimits) > 0,then: memoryLimits,else: totalPhysicalMemory)| fieldsdt.entity.container_group_instance, interval, timeframe, memoryUsagePercent = 100 * residentSetBytes[] / denominator[]