Allocate your DPS costs

  • How-to guide
  • 16-min read

Cost Allocation is exclusively available for Dynatrace SaaS environments with a Dynatrace Platform Subscription (DPS) licensing agreement that was signed after April 2023.

Dynatrace Cost Allocation lets you allocate Dynatrace DPS usage to customer-defined cost centers, products, or both. This gives you a transparent and detailed account of each cost center’s Dynatrace expenditures, helping your organization optimize its budgets.

You can customize the use of these fields to fit your company's organizational framework:

  • Data is collected from all OneAgents deployed on hosts or Kubernetes pods.

  • Additionally, ingested telemetry data (traces and logs) can be collected in certain infrastructure setups (e.g., via Logs API or Kubernetes metadata enrichment).

  • Costs can be allocated to customer-defined cost centers, products, or both.

  • Data can be

    • Analyzed in Dynatrace via DQL, Dashboards Dashboards, or Notebooks Notebooks.
    • Exported for viewing and editing in separate tools such as Excel and Power BI.

The figure below shows how different components in a given Dynatrace environment can be assigned to different cost centers and products.

Cost Allocation overview showing assignment of cost centers and products

Concepts

Cost center

A specific cost center within your organization. This is defined according to your organizational structure. Costs in Dynatrace can be allocated to specific cost centers.

Host tag

The parameter that assigns a host to a specific cost center or product. For more information, see Define tags and metadata for hosts.

Host property

Sometimes used as a synonym for "host tag." For more information, see Define tags and metadata for hosts.

Product

A single product, or group of products, offered by your organization. Costs in Dynatrace can be allocated to specific products.

Telemetry data

Generic term to refer to any single data point that is one of the following: log, trace, metric, or event.

Required permissions

To view or edit Cost Allocation information, your Dynatrace account needs at least one of the permissions as indicated in the table below. More information about these permissions is available at Role-based permissions.

Account Management permissions

What you want to doView accountView and manage account and billing information
View Cost Allocation Allow List
Edit Cost Allocation Allow List
View usage/costs extract in Account Management

Environment-level permissions

The default policy "Read System Events" needs to be assigned to the relevant user group. The actual policy statement is provided in the code block below.

//Grail read data
ALLOW storage:buckets:read WHERE storage:table-name = "dt.system.events";
ALLOW storage:system:read;

If you will be using lookup tables to access Grail data, you will additionally need the permissions described in Lookup data in Grail.

Supported capabilities

The table below describes the rate card capabilities for which Cost Allocation is available.

In the case that Cost Allocation is not available for the given capability, an alternative best practice is recommended.

Category

Capability

DPS Cost Allocation

Alternative best practice

Host Monitoring

Full-Stack Monitoring

Infrastructure Monitoring

Foundation & Discovery

Mainframe Monitoring

Classic metrics

Container Monitoring

Kubernetes Monitoring

Classic metrics

Application Security Protection

Runtime Vulnerability Analytics

Runtime Application Protection

Security Posture Management

Notebook available via Account Management

Digital Experience Monitoring

Real User Monitoring

Classic metrics

Real User Monitoring with Session Replay

Classic metrics

Real User Monitoring Property

Classic metrics

Browser Monitor or Clickpath

Classic metrics

Third-Party Synthetic API Ingestion

Classic metrics

HTTP Monitor

Classic metrics

Metrics powered by Grail

Metrics - Ingest

Notebook available via Account Management

Metrics - Retain

Notebook available via Account Management

Metrics - Query

Notebook available via Account Management

Logs powered by Grail

Logs - Ingest

Logs - Retain

Notebook available via Account Management

Logs - Query

Notebook available via Account Management

Traces powered by Grail

Traces - Ingest

Traces - Retain

Notebook available via Account Management

Traces - Query

Notebook available via Account Management

Events powered by Grail

Events - Ingest

Notebook available via Account Management

Events - Retain

Notebook available via Account Management

Events - Query

Notebook available via Account Management

AppEngine Functions

AppEngine Functions - Small

Notebook available via Account Management

Automation

AutomationWorkflow

Notebook available via Account Management

Platform extensions

Custom Metrics Classic

Please switch to Metrics powered by Grail

Log Monitoring Classic

Please switch to Logs powered by Grail

Custom Traces Classic

Please switch to Traces powered by Grail

Custom Events Classic

Please switch to Events powered by Grail

Serverless Functions Classic

Please switch to AppEngine Functions

We're continuously extending Cost Allocation support to cover additional Dynatrace capabilities. For complete details regarding your licensing agreement, please contact your Dynatrace account manager. For more details about specific capabilities, see Monitoring consumption per capability.

Set up Cost Allocation

This section describes how to set up Cost Allocation in your Dynatrace environment.

For tips on how to allocate shared costs, where a single host is used by multiple cost centers or products, see Handling shared costs.

Identify allowed cost centers and products

To configure Cost Allocation you need to explicitly define the cost centers and products to which costs are allocated. Up to 250 cost centers and 250 products can be defined.

The definitions are managed in two separate allow lists: the Cost center allow list and the Product allow list. You can configure these either via Account Management or via the Dynatrace API, as described below.

Changes to the allow lists are not applied retroactively. If you remove a cost center or product from its allow list, historical reports will still show the usage and costs associated with the value before it was removed.

Via Account Management

To find the two allow lists, go to Account Management > Subscription > Cost management. The allow lists are visible in the Cost center allow list and Product allow list sections.

To add a new cost center or product, select Cost center and follow the steps.

Account management cost center allow list for Cost Allocation host tags

Via the API

Both the cost center and product allow lists can be configured via the Account Management API as described in Dynatrace Platform Subscription API - manage cost allocation.

Configure Cost Allocation for host-based deployments

To set up Cost Allocation in a host-based deployment, configure OneAgent according to the steps in Configure Cost Allocation for OneAgent.

Cost Allocation is configured at the host level. One host can be allocated to a maximum of one cost center and one product.

Configure Cost Allocation for Kubernetes deployments

To set up Cost Allocation in a Kubernetes-based deployment, configure Kubernetes according to the steps in Configure Cost Allocation for Kubernetes.

Cost Allocation is supported for different Kubernetes deployment models.

Configure Cost Allocation for telemetry ingest

With Dynatrace, you can enrich telemetry data with Cost Allocation attributes (dt.cost.costcenter, dt.cost.product) as metadata. Telemetry enrichment with Cost Allocation attributes is possible for all supported ingest methods–whether logs, traces, metrics, or events.

These attributes are stored in Grail and are available through Dashboards Dashboards, Notebooks Notebooks, Account Management, and the Dynatrace API. You can use these attributes to allocate usage to the your user-defined products and cost centers.

For more information on how to enrich telemetry data according to your use case, see Ingest data.

How to get started

No matter which method you use to ingest data, here's how to get going with Cost Allocation telemetry enhancement:

  1. Get an inventory of your ingest channels. List all the ways your organization sends logs and traces into Dynatrace. This could be via OneAgent, the log ingest API, cloud forwarders, log shippers, OpenTelemetry, or any one of the supported ingest methods.

  2. Review the documentation for your ingest method. Check the official Dynatrace documentation to find method-specific configuration and enrichment options.

  3. Map metadata opportunities: Identify your specific cost centers and products and then explicitly define them in Account Management. For more information, see Identify allowed cost centers and products.

Integrate Cost Allocation metadata

Don’t worry about perfection on day one. Start tagging now, even if it's just for one ingest channel. You can refine and expand to other ingest channels and telemetry types as your FinOps maturity grows.

Our available dashboard Cost Allocation pre-made dashboard can help you identify other ingest channels that you could consider enhancing with Cost Allocation data.

  1. For each ingest channel:

    • Review how metadata can be added. Depending on your ingest method, this could be via OneAgent configuration, API payload, cloud tag mapping, Kubernetes annotations, etc.
    • Implement tagging in your pipelines, scripts, or agent settings.
  2. Test your setup:

    • Send sample data and verify that cost allocation tags are present in Grail.

    • Use the pre-made dashboard to confirm that these tags are visible.

      Usage tracking for logs and traces is written every 15 minutes. So, it might take up to 15 minutes until you will see any results.

  3. Document your approach: Record which channels and tagging methods you use. This will help with future audits and troubleshooting.

Best practices

This section provides best practices for setting up Cost Allocation.

Cost center and product names

How you name your cost centers and products is up to you. We recommend:

  • For cost centers: Use the organizational level to which the costs belong.
  • For products: Use the application or product group to which the costs belong.

Values can be provided as text or numerical strings. If you have both, we recommend to use both the text-based name and the ID, separated by a comma (,) or slash (/). This lets you separate the name and ID after a data export.

Examples:

Host

Cost center

Product

Host 1

dt.cost.costcenter=BusinessUnit1/Bu1

dt.cost.product=AppName/AppID

Host 2

dt.cost.costcenter=BusinessUnit2/Bu2

dt.cost.product=AppName/AppID

Host 3

dt.cost.costcenter=BusinessUnit2/Bu2

dt.cost.product=AppName/AppID

Handling shared costs

If your host shares services, Cost Allocation doesn't support costs billed to separate cost centers or products. However, you can create a cost center or product for that host and then allocate its costs outside of Dynatrace.

  1. Create a cost center or product for both entities, such as dt.cost.product="Webpage_MobileApp" for a host that should be allocated to both the webpage product and the mobile app product.
  2. When you want to analyze past data, retrieve the data from Account Management and import them into an Excel or Power BI board.
  3. You can take the host's total costs and split them according to your requirements.

DPS licensing consumption and related costs are based on 15-minute increments. Reports are generated daily, so you won't be able to see usage accrued in the previous <24 hours.

Analyze Cost Allocation data

To analyze Cost Allocation data, you can

Analyze in Dynatrace

Cost Allocation data is stored in Dynatrace Grail as billing usage events. These events can be analyzed

  • In Dashboards Dashboards and Notebooks Notebooks. Dynatrace provides a built-in Dashboard, DPS Cost Allocation usage & costs. Examples from this dashboard are provided below.
  • Via DQL queries. Example DQL queries are provided below.

Visit the Dynatrace DPS Cost Allocation community to see how other Dynatracers analyze their Cost Allocation data.

Analyze in Dashboards and Notebooks

To analyze Cost Allocation data, you can use the pre-made dashboard.

The pre-made dashboard is enough to get you going right away, but it is really intended as just a starting point. Please adapt the dashboard to fit to your needs and use-case scenarios.

Known limitations

The dashboard does not automatically account for included trace amounts. Therefore, the costs shown are actually higher than what you will be billed for.

This will be updated in a future release of the dashboard.

The dashboard is available:

  • In the built-in environment.

  • As a JSON file, which you can upload to any other Dynatrace environment.

    1. Copy the JSON contents from the code block below and save them to a file on your computer.

      Cost Allocation pre-made dashboard JSON contents
      {
      "version": 19,
      "variables": [
      {
      "version": 2,
      "key": "Capability",
      "type": "query",
      "visible": true,
      "editable": true,
      "input": "fetch dt.system.events\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter $SupportedCapabilitiesOnly == \"no\" OR isNotNull(dt.cost.costcenter) OR isNotNull(dt.cost.product)\n| fields event.type\n| dedup event.type",
      "multiple": true
      },
      {
      "version": 2,
      "key": "CostCenter",
      "type": "query",
      "visible": true,
      "editable": true,
      "input": "fetch dt.system.events\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| lookup [\n load \"/lookups/CA/userdata\"\n], sourceField:user.email, lookupField:user.email\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, lookup.dt.cost.costcenter, \"unassigned\")\n| summarize count(), by: {dt.cost.costcenter}\n| fieldsKeep dt.cost.costcenter\n// | fieldsAdd dt.cost.product = coalesce(dt.cost.product, lookup.dt.cost.product, \"unassigned\")\n",
      "multiple": true,
      "defaultValue": ["3420b2ac-f1cf-4b24-b62d-61ba1ba8ed05*"]
      },
      {
      "version": 2,
      "key": "Product",
      "type": "query",
      "visible": true,
      "editable": true,
      "input": "fetch dt.system.events\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| lookup [\n load \"/lookups/CA/userdata\"\n], sourceField:user.email, lookupField:user.email\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, lookup.dt.cost.product, \"unassigned\")\n| summarize count(), by: {dt.cost.product}\n| fieldsKeep dt.cost.product",
      "multiple": true,
      "defaultValue": ["3420b2ac-f1cf-4b24-b62d-61ba1ba8ed05*"]
      },
      {
      "version": 2,
      "key": "unassigned",
      "type": "text",
      "visible": false,
      "editable": true,
      "defaultValue": "unassigned"
      },
      {
      "version": 2,
      "key": "SupportedCapabilitiesOnly",
      "type": "csv",
      "visible": false,
      "editable": true,
      "input": "yes,no",
      "multiple": false,
      "defaultValue": "yes"
      },
      {
      "version": 2,
      "key": "resolution",
      "type": "csv",
      "visible": true,
      "editable": true,
      "input": "1d,1w,1h",
      "multiple": false,
      "defaultValue": "1h"
      },
      {
      "version": 2,
      "key": "ratecard_data",
      "type": "code",
      "visible": false,
      "editable": true,
      "input": "/*\n* This will run JavaScript in the DYNATRACE\n* serverless environment.\n* To generate variable options return string array.\n*/\nexport default async function () {\n return `[\n {\"key\":\"AUTOMATIONS\",\"name\":\"Automation Workflow\",\"price\":\"0.13\",\"currencyCode\":\"USD\"},\n {\"key\":\"BUSINESS_EVENTS_ANALYZE\",\"name\":\"Events - Query\",\"price\":\"0.0035\",\"currencyCode\":\"USD\"},\n {\"key\":\"BUSINESS_EVENTS_INGEST\",\"name\":\"Events - Ingest & Process\",\"price\":\"0.2\",\"currencyCode\":\"USD\"},\n {\"key\":\"BUSINESS_EVENTS_RETAIN\",\"name\":\"Events - Retain\",\"price\":\"0.0007\",\"currencyCode\":\"USD\"},\n {\"key\":\"COMPUTE\",\"name\":\"AppEngine Functions - Small\",\"price\":\"0.001\",\"currencyCode\":\"USD\"},\n {\"key\":\"EVENTS\",\"name\":\"Custom Events Classic\",\"price\":\"0.000002\",\"currencyCode\":\"USD\"},\n {\"key\":\"FOUNDATION_AND_DISCOVERY\",\"name\":\"Foundation & Discovery\",\"price\":\"0.01\",\"currencyCode\":\"USD\"},\n {\"key\":\"FULLSTACK_MONITORING\",\"name\":\"Full-Stack Monitoring\",\"price\":\"0.01\",\"currencyCode\":\"USD\"},\n {\"key\":\"INFRASTRUCTURE_MONITORING\",\"name\":\"Infrastructure Monitoring\",\"price\":\"0.04\",\"currencyCode\":\"USD\"},\n {\"key\":\"KUBERNETES_OPERATIONS\",\"name\":\"Kubernetes Platform Monitoring\",\"price\":\"0.002\",\"currencyCode\":\"USD\"},\n {\"key\":\"LOG_MANAGEMENT_ANALYZE\",\"name\":\"Log Management & Analytics - Query\",\"price\":\"0.0035\",\"currencyCode\":\"USD\"},\n {\"key\":\"LOG_MANAGEMENT_INGEST\",\"name\":\"Log Management & Analytics - Ingest & Process\",\"price\":\"0.2\",\"currencyCode\":\"USD\"},\n {\"key\":\"LOG_MANAGEMENT_RETAIN\",\"name\":\"Log Management & Analytics - Retain\",\"price\":\"0.0007\",\"currencyCode\":\"USD\"},\n {\"key\":\"LOGS\",\"name\":\"Log Monitoring Classic\",\"price\":\"0.000001\",\"currencyCode\":\"USD\"},\n {\"key\":\"MAINFRAME_MONITORING\",\"name\":\"Mainframe Monitoring\",\"price\":\"0.1\",\"currencyCode\":\"USD\"},\n {\"key\":\"METRICS\",\"name\":\"Custom Metrics Classic\",\"price\":\"0.000002\",\"currencyCode\":\"USD\"},\n {\"key\":\"RUNTIME_APPLICATION_PROTECTION\",\"name\":\"Runtime Application Protection\",\"price\":\"0.00225\",\"currencyCode\":\"USD\"},\n {\"key\":\"RUNTIME_VULNERABILITY_ANALYTICS\",\"name\":\"Runtime Vulnerability Analytics\",\"price\":\"0.00225\",\"currencyCode\":\"USD\"},\n {\"key\":\"SECURITY_POSTURE_MANAGEMENT\",\"name\":\"Security Posture Management\",\"price\":\"0\",\"currencyCode\":\"USD\"},\n {\"key\":\"SERVERLESS\",\"name\":\"Serverless Functions Classic\",\"price\":\"0.000004\",\"currencyCode\":\"USD\"},\n {\"key\":\"SYNTHETIC_MONITORING_BROWSER\",\"name\":\"Browser Monitor or Clickpath\",\"price\":\"0.009\",\"currencyCode\":\"USD\"},\n {\"key\":\"SYNTHETIC_MONITORING_HTTP\",\"name\":\"HTTP Monitor\",\"price\":\"0.001\",\"currencyCode\":\"USD\"},\n {\"key\":\"SYNTHETIC_MONITORING_THIRD_PARTY\",\"name\":\"Third-Party Synthetic API Ingestion\",\"price\":\"0.001\",\"currencyCode\":\"USD\"},\n {\"key\":\"TRACE_INGEST\",\"name\":\"Traces - Ingest \\& Process\",\"price\":\"0.2\",\"currencyCode\":\"USD\"},\n {\"key\":\"TRACE_QUERY\",\"name\":\"Traces - Query\",\"price\":\"0.0035\",\"currencyCode\":\"USD\"},\n {\"key\":\"TRACE_RETAIN\",\"name\":\"Traces - Retain\",\"price\":\"0.0007\",\"currencyCode\":\"USD\"},\n {\"key\":\"TRACES\",\"name\":\"Custom Traces Classic\",\"price\":\"0.0000014\",\"currencyCode\":\"USD\"},\n {\"key\":\"USER_SESSION_PROPERTIES\",\"name\":\"Real User Monitoring Property\",\"price\":\"0.0001\",\"currencyCode\":\"USD\"},\n {\"key\":\"USER_SESSION_REPLAYS\",\"name\":\"Real User Monitoring with Session Replay\",\"price\":\"0.009\",\"currencyCode\":\"USD\"},\n {\"key\":\"USER_SESSIONS\",\"name\":\"Real User Monitoring\",\"price\":\"0.00225\",\"currencyCode\":\"USD\"}\n]`\n}",
      "multiple": false
      }
      ],
      "tiles": {
      "33": {
      "type": "markdown",
      "content": "## Disclaimer\n* This is a POC dashboard and will continue to change.\n* ensure to adopt the ratecard_data variable\n* Usage of the Dashboard is free of charge"
      },
      "35": {
      "title": "List of usage and estimated costs per Capability and Product",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n ingested_bytes,\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {total_usage=sum(usage), total_cost=sum(cost)}, by:{capability=event.type, dt.cost.product}\n| sort total_cost desc",
      "visualization": "table",
      "visualizationSettings": {
      "table": {
      "sortBy": [{ "columnId": "[\"sum(cost)\"]", "direction": "descending" }],
      "columnWidths": { "[\"event.type\"]": 312 },
      "columnOrder": [
      "[\"capability\"]",
      "[\"dt.cost.product\"]",
      "[\"total_usage\"]",
      "[\"total_cost\"]"
      ]
      },
      "thresholds": [],
      "unitsOverrides": [
      {
      "identifier": "total_usage",
      "unitCategory": "amount",
      "baseUnit": "one",
      "displayUnit": null,
      "decimals": 0,
      "suffix": "",
      "delimiter": false,
      "added": 1754648177039
      },
      {
      "identifier": "total_cost",
      "unitCategory": "currency",
      "baseUnit": "usd",
      "displayUnit": null,
      "decimals": 2,
      "suffix": "",
      "delimiter": true,
      "added": 1754648199722
      }
      ]
      },
      "querySettings": {
      "maxResultRecords": 1000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "36": {
      "title": "Capability / Cost center Heatmap",
      "description": "",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n ingested_bytes,\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {sum(usage), sum(cost)}, by:{event.type,dt.cost.costcenter, dt.cost.product}",
      "visualization": "heatmap",
      "visualizationSettings": {
      "dataMapping": {
      "xAxis": "dt.cost.costcenter",
      "yAxis": "event.type",
      "bucketValue": "sum(cost)"
      },
      "axes": { "yAxis": { "showLabel": true } },
      "legend": { "ratio": 5 },
      "unitsOverrides": [
      {
      "identifier": "sum(cost)",
      "unitCategory": "currency",
      "baseUnit": "usd",
      "displayUnit": null,
      "decimals": 2,
      "suffix": "",
      "delimiter": false,
      "added": 1753286738031
      }
      ],
      "thresholds": []
      },
      "querySettings": {
      "maxResultRecords": 1000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "37": {
      "title": "Capabilities w/o dt.cost.* (unconfigured or not yet supported) incl. estimated costs and usage",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {{sum(usage), alias: total_usage}, {sum(cost), alias: total_costs}, {takeAny((dt.cost.product)), alias:pr}, {takeAny((dt.cost.costcenter)), alias:cc},{countDistinct(dt.cost.costcenter), alias:cnt_cc}, {countDistinct(dt.cost.product), alias:cnt_pr}}, by:{event.type}\n| filter cnt_cc == 1 and cnt_pr == 1 and pr == $unassigned\n| fieldsKeep event.type, total_usage, total_costs",
      "visualization": "table",
      "visualizationSettings": {
      "table": {
      "columnOrder": ["[\"event.type\"]", "[\"total_usage\"]", "[\"total_costs\"]"],
      "sortBy": [{ "columnId": "[\"event.type\"]", "direction": "descending" }],
      "columnWidths": { "[\"event.type\"]": 312 }
      },
      "thresholds": []
      },
      "querySettings": {
      "maxResultRecords": 1000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "38": {
      "title": "Billing Usage Events incl. user and ratecard lookup ",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n// | fieldsKeep wcfa.user.id,user.id, timestamp,event.type,dt.cost.costcenter,dt.cost.product,usage,cost,ratecard.currencyCode,event.id\n| fieldsAdd entityName(dt.entity.host)",
      "visualization": "table",
      "visualizationSettings": {
      "table": {
      "columnWidths": { "[\"dt.entity.host\"]": 188 },
      "sortBy": [{ "columnId": "[\"billed_gibibyte_hours\"]", "direction": "descending" }],
      "columnOrder": [
      "[\"timestamp\"]",
      "[\"dt.cost.costcenter\"]",
      "[\"dt.cost.product\"]",
      "[\"usage\"]",
      "[\"event.type\"]",
      "[\"event.id\"]",
      "[\"ratecard.currencyCode\"]",
      "[\"cost\"]",
      "[\"ratecard.name\"]",
      "[\"ratecard.price\"]",
      "[\"ratecard.key\"]",
      "[\"event.kind\"]",
      "[\"event.version\"]",
      "[\"dt.security_context\"]",
      "[\"event.provider\"]",
      "[\"usage.end\"]",
      "[\"usage.start\"]",
      "[\"dt.entity.host.name\"]",
      "[\"ingested_bytes\"]",
      "[\"ingested_spans\"]",
      "[\"licensing_type\"]",
      "[\"usage.bucket\"]"
      ]
      },
      "thresholds": []
      },
      "querySettings": {
      "maxResultRecords": 1000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "39": {
      "title": "Capability / Product Heatmap",
      "description": "",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n ingested_bytes,\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {sum(usage), sum(cost)}, by:{event.type,dt.cost.costcenter, dt.cost.product}",
      "visualization": "heatmap",
      "visualizationSettings": {
      "dataMapping": {
      "xAxis": "dt.cost.product",
      "yAxis": "event.type",
      "bucketValue": "sum(cost)"
      },
      "axes": { "yAxis": { "showLabel": true } },
      "legend": { "ratio": 5 },
      "unitsOverrides": [
      {
      "identifier": "sum(cost)",
      "unitCategory": "currency",
      "baseUnit": "usd",
      "displayUnit": null,
      "decimals": 2,
      "suffix": "",
      "delimiter": false,
      "added": 1753286738031
      }
      ],
      "thresholds": []
      },
      "querySettings": {
      "maxResultRecords": 1000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "40": {
      "title": "Estimated Costs per Capability and Cost Center",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {total_usage=sum(usage), total_cost=sum(cost)}, by:{capability=event.type,dt.cost.costcenter,timestamp = bin(timestamp, duration(parse($resolution,\"LONG:t\"),parse($resolution,\"LONG ALPHA:u\")))}\n| sort capability",
      "visualization": "lineChart",
      "visualizationSettings": {
      "chartSettings": {
      "xAxisScaling": "analyzedTimeframe",
      "fieldMapping": { "leftAxisValues": ["total_cost"] },
      "gapPolicy": "connect"
      },
      "autoSelectVisualization": false,
      "thresholds": [],
      "unitsOverrides": [
      {
      "identifier": "total_usage",
      "unitCategory": "amount",
      "baseUnit": "one",
      "displayUnit": null,
      "decimals": 0,
      "suffix": "",
      "delimiter": false,
      "added": 1754648177039
      },
      {
      "identifier": "total_cost",
      "unitCategory": "currency",
      "baseUnit": "usd",
      "displayUnit": null,
      "decimals": 2,
      "suffix": "",
      "delimiter": true,
      "added": 1754648199722
      }
      ],
      "dataMapping": { "displayedFields": ["capability", "dt.cost.costcenter"] }
      },
      "querySettings": {
      "maxResultRecords": 10000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 5,
      "defaultSamplingRatio": 10,
      "enableSampling": true
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "41": {
      "title": "Estimated Costs per Capability and Product",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {total_usage=sum(usage), total_cost=sum(cost)}, by:{capability=event.type,dt.cost.product,timestamp = bin(timestamp, duration(parse($resolution,\"LONG:t\"),parse($resolution,\"LONG ALPHA:u\")))}\n| sort capability",
      "visualization": "lineChart",
      "visualizationSettings": {
      "chartSettings": {
      "xAxisScaling": "analyzedTimeframe",
      "fieldMapping": { "leftAxisValues": ["total_cost"] },
      "gapPolicy": "connect"
      },
      "autoSelectVisualization": false,
      "thresholds": [],
      "unitsOverrides": [
      {
      "identifier": "total_usage",
      "unitCategory": "amount",
      "baseUnit": "one",
      "displayUnit": null,
      "decimals": 0,
      "suffix": "",
      "delimiter": false,
      "added": 1754648177039
      },
      {
      "identifier": "total_cost",
      "unitCategory": "currency",
      "baseUnit": "usd",
      "displayUnit": null,
      "decimals": 2,
      "suffix": "",
      "delimiter": true,
      "added": 1754648199722
      }
      ],
      "dataMapping": { "displayedFields": ["capability", "dt.cost.product"] }
      },
      "querySettings": {
      "maxResultRecords": 10000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "42": {
      "title": "Estimated Costs per Cost Center",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n ingested_bytes,\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {\n total_usage=sum(usage)\n , total_cost=sum(cost)\n }, by:{\n dt.cost.costcenter\n ,timestamp = bin(timestamp, duration(parse($resolution,\"LONG:t\"),parse($resolution,\"LONG ALPHA:u\")))\n }\n| sort dt.cost.costcenter",
      "visualization": "lineChart",
      "visualizationSettings": {
      "chartSettings": {
      "xAxisScaling": "analyzedTimeframe",
      "tooltip": { "seriesDisplayMode": "multi-line" },
      "fieldMapping": { "leftAxisValues": ["total_cost"] },
      "gapPolicy": "connect"
      },
      "autoSelectVisualization": false,
      "thresholds": [],
      "unitsOverrides": [
      {
      "identifier": "total_usage",
      "unitCategory": "amount",
      "baseUnit": "one",
      "displayUnit": null,
      "decimals": 0,
      "suffix": "",
      "delimiter": false,
      "added": 1754648177039
      },
      {
      "identifier": "total_cost",
      "unitCategory": "currency",
      "baseUnit": "usd",
      "displayUnit": null,
      "decimals": 2,
      "suffix": "",
      "delimiter": true,
      "added": 1754648199722
      }
      ],
      "dataMapping": { "displayedFields": ["dt.cost.costcenter"] }
      },
      "querySettings": {
      "maxResultRecords": 5000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "44": { "type": "markdown", "content": "# Usage and estimated Costs per Cost Center" },
      "45": { "type": "markdown", "content": "## Historical view of Products and Cost Centers" },
      "46": {
      "type": "markdown",
      "content": "# Insights into underlying data for data validation tasks"
      },
      "47": {
      "title": "Estimated Costs per capability",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n ingested_bytes,\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {total_usage=sum(usage), total_cost=sum(cost)}, by:{capability=event.type,timestamp = bin(timestamp, duration(parse($resolution,\"LONG:t\"),parse($resolution,\"LONG ALPHA:u\")))}\n| sort capability",
      "visualization": "lineChart",
      "visualizationSettings": {
      "chartSettings": {
      "xAxisScaling": "analyzedTimeframe",
      "fieldMapping": { "leftAxisValues": ["total_cost"] },
      "gapPolicy": "connect"
      },
      "autoSelectVisualization": false,
      "thresholds": [],
      "unitsOverrides": [
      {
      "identifier": "total_usage",
      "unitCategory": "amount",
      "baseUnit": "one",
      "displayUnit": null,
      "decimals": 0,
      "suffix": "",
      "delimiter": false,
      "added": 1754648177039
      },
      {
      "identifier": "total_cost",
      "unitCategory": "currency",
      "baseUnit": "usd",
      "displayUnit": null,
      "decimals": 2,
      "suffix": "",
      "delimiter": true,
      "added": 1754648199722
      }
      ],
      "dataMapping": { "displayedFields": ["capability"] }
      },
      "querySettings": {
      "maxResultRecords": 5000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "48": { "type": "markdown", "content": "--- \n ## Historical view of capabilities" },
      "49": {
      "type": "markdown",
      "content": "#### How this section is intended to be used for analysis:\n1. Check the overall capabilities for any suspicious capability\n2. Use the dashboard filters to only show these capabilities\n3. adjust the time range if needed to only see the relevant period\n4. move to the next graph to see if there is a specific dt.cost.costcenter or dt.cost.product contributing to the suspicious event \n5. filter for these cost centers and/or products\n6. find all identified entities of these cost centers and/or products which contributed to the existing costs/usage"
      },
      "50": {
      "title": "Estimated cost distribution per Capability",
      "description": "",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n ingested_bytes,\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {total_usage=sum(usage), total_cost=sum(cost)}, by:{capability=event.type}\n| sort total_cost desc",
      "visualization": "pieChart",
      "visualizationSettings": {
      "chartSettings": {
      "legend": { "position": "right" },
      "categoricalBarChartSettings": {
      "valueAxis": "total_cost",
      "valueAxisLabel": "total_cost",
      "categoryAxis": ["capability"],
      "categoryAxisLabel": "capability"
      },
      "circleChartSettings": {
      "valueType": "relative",
      "groupingThresholdType": "number-of-slices",
      "groupingThresholdValue": 20,
      "groupingName": "Other"
      }
      },
      "legend": { "ratio": 52 },
      "autoSelectVisualization": false,
      "thresholds": [],
      "unitsOverrides": [
      {
      "identifier": "total_usage",
      "unitCategory": "amount",
      "baseUnit": "one",
      "displayUnit": null,
      "decimals": 0,
      "suffix": "",
      "delimiter": false,
      "added": 1754648177039
      },
      {
      "identifier": "total_cost",
      "unitCategory": "currency",
      "baseUnit": "usd",
      "displayUnit": null,
      "decimals": 2,
      "suffix": "",
      "delimiter": true,
      "added": 1754648199722
      }
      ]
      },
      "querySettings": {
      "maxResultRecords": 1000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "51": {
      "title": "Estimated cost distribution per Capability and product",
      "description": "Showing only values above 5% of total costs",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n ingested_bytes,\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {total_usage=sum(usage), total_cost=sum(cost)}, by:{capability=event.type,dt.cost.product}\n| sort capability",
      "visualization": "pieChart",
      "visualizationSettings": {
      "chartSettings": {
      "legend": { "position": "right" },
      "colorPalette": "fireplace-inverted",
      "categoricalBarChartSettings": {
      "categoryAxis": ["capability", "dt.cost.product"],
      "categoryAxisLabel": "capability,dt.cost.product"
      },
      "circleChartSettings": {
      "valueType": "relative",
      "groupingThresholdType": "relative",
      "groupingThresholdValue": 5,
      "groupingName": "Other"
      }
      },
      "legend": { "ratio": 57 },
      "autoSelectVisualization": false,
      "thresholds": [],
      "unitsOverrides": [
      {
      "identifier": "total_usage",
      "unitCategory": "amount",
      "baseUnit": "one",
      "displayUnit": null,
      "decimals": 0,
      "suffix": "",
      "delimiter": false,
      "added": 1754648177039
      },
      {
      "identifier": "total_cost",
      "unitCategory": "currency",
      "baseUnit": "usd",
      "displayUnit": null,
      "decimals": 2,
      "suffix": "",
      "delimiter": true,
      "added": 1754648199722
      }
      ]
      },
      "querySettings": {
      "maxResultRecords": 1000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "52": {
      "title": "List of usage and estimated costs per Capability and Cost Center",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n ingested_bytes,\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {total_usage=sum(usage), total_cost=sum(cost)}, by:{capability=event.type,dt.cost.costcenter}\n| sort total_cost desc",
      "visualization": "table",
      "visualizationSettings": {
      "table": {
      "sortBy": [{ "columnId": "[\"sum(cost)\"]", "direction": "descending" }],
      "columnWidths": { "[\"event.type\"]": 312, "[\"total_cost\"]": 88 },
      "columnOrder": [
      "[\"capability\"]",
      "[\"dt.cost.costcenter\"]",
      "[\"total_usage\"]",
      "[\"total_cost\"]"
      ]
      },
      "thresholds": [],
      "unitsOverrides": [
      {
      "identifier": "total_usage",
      "unitCategory": "amount",
      "baseUnit": "one",
      "displayUnit": null,
      "decimals": 0,
      "suffix": "",
      "delimiter": false,
      "added": 1754648177039
      },
      {
      "identifier": "total_cost",
      "unitCategory": "currency",
      "baseUnit": "usd",
      "displayUnit": null,
      "decimals": 2,
      "suffix": "",
      "delimiter": true,
      "added": 1754648199722
      }
      ]
      },
      "querySettings": {
      "maxResultRecords": 1000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "53": { "type": "markdown", "content": "# Usage and estimated Costs per Product" },
      "54": {
      "title": "Estimated Costs per Product",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {\n total_usage=sum(usage)\n , total_cost=sum(cost)\n }, by:{\n dt.cost.product\n ,timestamp = bin(timestamp, duration(parse($resolution,\"LONG:t\"),parse($resolution,\"LONG ALPHA:u\")))\n }",
      "visualization": "lineChart",
      "visualizationSettings": {
      "chartSettings": {
      "xAxisScaling": "analyzedTimeframe",
      "tooltip": { "seriesDisplayMode": "multi-line" },
      "fieldMapping": { "leftAxisValues": ["total_cost"] },
      "gapPolicy": "connect"
      },
      "autoSelectVisualization": false,
      "thresholds": [],
      "unitsOverrides": [
      {
      "identifier": "total_usage",
      "unitCategory": "amount",
      "baseUnit": "one",
      "displayUnit": null,
      "decimals": 0,
      "suffix": "",
      "delimiter": false,
      "added": 1754648177039
      },
      {
      "identifier": "total_cost",
      "unitCategory": "currency",
      "baseUnit": "usd",
      "displayUnit": null,
      "decimals": 2,
      "suffix": "",
      "delimiter": true,
      "added": 1754648199722
      }
      ],
      "dataMapping": { "displayedFields": ["dt.cost.product"] }
      },
      "querySettings": {
      "maxResultRecords": 5000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "55": {
      "type": "markdown",
      "content": "## Historical view of the combination of Capability and Products or Cost Centers\nThis section works best when either Capability or Product/Cost Center is filtered"
      },
      "56": {
      "type": "markdown",
      "content": "## Change Log\n* v 3: Branched a version w/o lookup tables to ensure no related costs"
      },
      "57": {
      "title": "Estimated cost distribution per cost center",
      "description": "Showing only values above 5% of total costs",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n ingested_bytes,\n 1 //workflow count\n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n| summarize {total_usage=sum(usage), total_cost=sum(cost)}, by:{dt.cost.costcenter}\n| sort total_cost desc",
      "visualization": "pieChart",
      "visualizationSettings": {
      "chartSettings": {
      "legend": { "position": "right" },
      "colorPalette": "fireplace-inverted",
      "categoricalBarChartSettings": {
      "categoryAxis": ["dt.cost.costcenter", "capability"],
      "categoryAxisLabel": "dt.cost.costcenter,capability"
      },
      "circleChartSettings": {
      "valueType": "relative",
      "groupingThresholdType": "number-of-slices",
      "groupingThresholdValue": 10,
      "groupingName": "Other"
      }
      },
      "legend": { "ratio": 52 },
      "autoSelectVisualization": false,
      "thresholds": [],
      "unitsOverrides": [
      {
      "identifier": "total_usage",
      "unitCategory": "amount",
      "baseUnit": "one",
      "displayUnit": null,
      "decimals": 0,
      "suffix": "",
      "delimiter": false,
      "added": 1754648177039
      },
      {
      "identifier": "total_cost",
      "unitCategory": "currency",
      "baseUnit": "usd",
      "displayUnit": null,
      "decimals": 2,
      "suffix": "",
      "delimiter": true,
      "added": 1754648199722
      }
      ]
      },
      "querySettings": {
      "maxResultRecords": 1000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "58": {
      "title": "Used Ratecard (can be changed by editing the ratecard_data variable <---)",
      "type": "data",
      "query": "data json:$ratecard_data",
      "visualization": "table",
      "visualizationSettings": {
      "autoSelectVisualization": true,
      "table": { "sortBy": [{ "columnId": "[\"key\"]", "direction": "ascending" }] }
      },
      "querySettings": {
      "maxResultRecords": 1000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      },
      "59": {
      "title": "",
      "type": "data",
      "query": "fetch dt.system.events\n| lookup [\n data json:$ratecard_data\n], sourceField:event.type, lookupField:name, prefix: \"ratecard.\"\n| filter event.kind == \"BILLING_USAGE_EVENT\"\n| filter in(event.type, {$Capability})\n| fieldsAdd dt.cost.costcenter = coalesce(dt.cost.costcenter, $unassigned)\n| fieldsAdd dt.cost.product = coalesce(dt.cost.product, $unassigned)\n| filter in(dt.cost.product, {$Product})\n| filter in(dt.cost.costcenter, {$CostCenter})\n| fieldsAdd usage = coalesce(\n billed_host_hours, //Infra, F&D\n billed_gibibyte_hours, //Fullstack, Runtime Application Protection, Runtime Vulnerability Analytics\n billed_bytes / (1024*1024*1024), //ALL I/R/Q\n billed_invocations, //AppEngine\n //ingested_bytes, //Traces & Metrics\n 1 //workflow count \n )\n| fieldsAdd cost = usage * toDouble(ratecard.price)\n// | summarize {total_usage=sum(usage), total_cost=sum(cost)}, by:{capability=event.type}\n// | sort total_cost desc",
      "visualization": "table",
      "visualizationSettings": {
      "autoSelectVisualization": true,
      "table": { "columnWidths": { "[\"ratecard.name\"]": 231 } }
      },
      "querySettings": {
      "maxResultRecords": 1000,
      "defaultScanLimitGbytes": 500,
      "maxResultMegaBytes": 1,
      "defaultSamplingRatio": 10,
      "enableSampling": false
      },
      "davis": { "enabled": false, "davisVisualization": { "isAvailable": true } }
      }
      },
      "layouts": {
      "33": { "x": 0, "y": 0, "w": 12, "h": 3 },
      "35": { "x": 12, "y": 21, "w": 12, "h": 7 },
      "36": { "x": 0, "y": 28, "w": 12, "h": 4 },
      "37": { "x": 0, "y": 60, "w": 24, "h": 5 },
      "38": { "x": 0, "y": 56, "w": 24, "h": 4 },
      "39": { "x": 12, "y": 28, "w": 12, "h": 4 },
      "40": { "x": 0, "y": 52, "w": 12, "h": 4 },
      "41": { "x": 12, "y": 52, "w": 12, "h": 4 },
      "42": { "x": 0, "y": 39, "w": 12, "h": 4 },
      "44": { "x": 0, "y": 12, "w": 12, "h": 2 },
      "45": { "x": 8, "y": 43, "w": 8, "h": 2 },
      "46": { "x": 0, "y": 51, "w": 24, "h": 1 },
      "47": { "x": 0, "y": 34, "w": 12, "h": 5 },
      "48": { "x": 9, "y": 32, "w": 6, "h": 2 },
      "49": { "x": 12, "y": 34, "w": 11, "h": 5 },
      "50": { "x": 0, "y": 5, "w": 24, "h": 7 },
      "51": { "x": 12, "y": 14, "w": 12, "h": 7 },
      "52": { "x": 0, "y": 21, "w": 12, "h": 7 },
      "53": { "x": 12, "y": 12, "w": 12, "h": 2 },
      "54": { "x": 12, "y": 45, "w": 12, "h": 4 },
      "55": { "x": 6, "y": 49, "w": 13, "h": 2 },
      "56": { "x": 0, "y": 3, "w": 12, "h": 2 },
      "57": { "x": 0, "y": 14, "w": 12, "h": 7 },
      "58": { "x": 12, "y": 0, "w": 12, "h": 5 },
      "59": { "x": 0, "y": 65, "w": 23, "h": 5 }
      },
      "importedWithCode": false,
      "settings": {}
      }
    2. In Dynatrace, go to the target environment and open Dashboards Dashboards.

    3. Select Upload Upload and use the file browser to locate the JSON file that you just saved.

    4. The pre-made dashboard is now visible in Dashboards Dashboards.

The costs shown in the demo dashboard are based on manual cost assignments as provided in the DQL query. They are not automatically cross-checked with your rate card.

Use DQL queries

This section provides various DQL queries that you can use to achieve specific use cases.

Fetch all Billing Usage Events in full detail (including Cost Allocation fields)
fetch dt.system.events
| filter event.kind == "BILLING_USAGE_EVENT"
Fetch all Billing Usage Events for all supported host-related capabilities and show only their capability, Host ID, and Cost Allocation fields
fetch dt.system.events
| filter event.kind == "BILLING_USAGE_EVENT"
| fieldsKeep event.type, dt.entitiy.host, dt.cost.costcenter, dt.cost.product
Check if any Cost Allocation fields are already configured
fetch dt.system.events
| filter event.kind == "BILLING_USAGE_EVENT"
| summarize count = count(), by:{event.type,dt.cost.costcenter}

Export Cost Allocation data

If you want to view Cost Allocation data in a separate tool, such as Excel or Power BI, you can export the data.

You can export Cost Allocation data via Account Management or the API.

DPS licensing consumption and related costs are based on 15-minute increments. Reports are generated daily, so you won't be able to see usage accrued in the previous <24 hours.

Export Cost Allocation data via Account Management

In Account Management, you can download some or all Cost Allocation data from your current DPS subscription.

  1. Go to Account Management.
  2. Select License > Cost Management > Cost Allocation > Download cost allocation report.
  3. Select the Commitment period for the relevant subscription.
  4. Select the timeframe from which data should be exported: enter the appropriate dates for From and To.
  5. Select Request download.
  6. An email will be sent to the email account of the logged-in user. The email is sent from noreply@dynatrace.com, so you might want to check your whitelist to make sure that you can receive emails from this account. It contains a download link for the CSV file, which is valid for 24 hours.

Export Cost Allocation data via the API

All Cost Allocation data can be retrieved via the API.

Before using the API, you need to generate an Account Management API Token as described in Authentication for the Account Management API. Additionally, your user will need the permission View usage and consumption: account-uac-read.

Use the following API call to retrieve Cost Allocation data. Parameters are described in Dynatrace Platform Subscription API - GET cost allocation.

GET /v1/subscriptions/{subscription-uuid}/cost-allocation?field={field}\&environment-id={environment-id}

An example response is provided in the code block below.

{
"records": [
{ "date": "2024-04-01", "capability": "FULLSTACK_MONITORING","key": "department-A", "costs": 10, "usage": 2000 },
{ "date": "2024-04-01", "capability": "FULLSTACK_MONITORING","key": "department-B", "costs": 40, "usage": 8000 },
{ "date": "2024-04-01", "capability": "LOGS", "key": "department-A", "costs": 70, "usage": 700 },
{ "date": "2024-04-01", "capability": "LOGS", "key": "department-B", "costs": 20, "usage": 200 },
{ "date": "2024-04-01", "capability": "FULLSTACK_MONITORING", "key": "department-E", "costs": 10, "usage": 2000 },
{ "date": "2024-04-01", "capability": "FULLSTACK_MONITORING", "key": "department-F", "costs": 50, "usage": 10000 },
{ "date": "2024-04-01", "capability": "FULLSTACK_MONITORING", "key": null, "costs": 60, "usage": 12000 },
{ "date": "2024-04-01", "capability": "LOGS", "key": null, "costs": 10, "usage": 100 },
{ "date": "2024-04-02", "capability": "FULLSTACK_MONITORING", "key": "department-A", "costs": 10, "usage": 2000 },
{ "date": "2024-04-02", "capability": "FULLSTACK_MONITORING", "key": "department-B", "costs": 40, "usage": 8000 },
{ "date": "2024-04-02", "capability": "FULLSTACK_MONITORING", "key": "department-C", "costs": 70, "usage": 14000 },
{ "date": "2024-04-02", "capability": "LOGS", "key": null, "costs": 500, "usage": 5000 }
// more daily records
],
"nextPageKey": "...",
"environmentId": "tenant-A",
"field": "COSTCENTER"
}

Troubleshooting

If you can't find Cost Allocation data:

  • Make sure you have a Dynatrace Platform Service (DPS) SaaS license.

  • Check your OneAgent version. Cost Allocation is supported for versions 1.291+.

  • Confirm that host tags are in the allow list.

    • Are all tag names correct?
    • Are all tags in Infrastructure & Operations Infrastructure & Operations also in the allow list?
    • If any used tags are not in the allow list, add them as described in Add host tags. Make sure that they're set on the OneAgent directly (i.e., via the command line), and not in the browser.
  • Did you perform a restart? When in doubt, restart OneAgent or your Kubernetes pod(s). Then wait up to 30 minutes and try again.

Related tags
Dynatrace PlatformDynatrace SignetDynatrace Platform Subscription