Skip to content

Commit cdf1434

Browse files
feat: Update workbook with grid layout and add deploy-workbook.bicep
- Updated token-usage-workbook.json with grid layout for graphs - Added deploy-workbook.bicep for standalone workbook deployment to any RG Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 0843d31 commit cdf1434

2 files changed

Lines changed: 49 additions & 44 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Standalone deployment for LLM Token Usage Workbook
2+
// Connects to an existing Application Insights instance from any content processing RG
3+
4+
targetScope = 'resourceGroup'
5+
6+
@description('Full resource ID of the Application Insights instance to query.')
7+
param appInsightsResourceId string
8+
9+
@description('Azure region for the workbook resource.')
10+
param location string = resourceGroup().location
11+
12+
var workbookId = guid(resourceGroup().id, 'token-usage-workbook')
13+
14+
resource workbook 'Microsoft.Insights/workbooks@2022-04-01' = {
15+
name: workbookId
16+
location: location
17+
kind: 'shared'
18+
properties: {
19+
displayName: 'LLM Token Usage Dashboard'
20+
category: 'workbook'
21+
sourceId: appInsightsResourceId
22+
serializedData: loadTextContent('token-usage-workbook.json')
23+
}
24+
}
25+
26+
output workbookName string = workbook.name
27+
output workbookId string = workbook.id

infra/dashboards/token-usage-workbook.json

Lines changed: 22 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,18 @@
2525
},
2626
"typeSettings": {
2727
"selectableValues": [
28-
{"durationMs": 3600000},
29-
{"durationMs": 86400000},
30-
{"durationMs": 604800000},
31-
{"durationMs": 2592000000}
28+
{
29+
"durationMs": 3600000
30+
},
31+
{
32+
"durationMs": 86400000
33+
},
34+
{
35+
"durationMs": 604800000
36+
},
37+
{
38+
"durationMs": 2592000000
39+
}
3240
],
3341
"allowCustom": true
3442
}
@@ -54,9 +62,6 @@
5462
"query": "customEvents\r\n| where name == 'LLM_Token_Usage_Summary'\r\n| where timestamp > ago(7d)\r\n| extend process_id = tostring(customDimensions['process_id'])\r\n| extend input_tokens = toint(customDimensions['total_input_tokens'])\r\n| extend output_tokens = toint(customDimensions['total_output_tokens'])\r\n| extend total_tokens = toint(customDimensions['total_tokens'])\r\n| summarize input_tokens=max(input_tokens), output_tokens=max(output_tokens), total_tokens=max(total_tokens) by process_id\r\n| summarize\r\n TotalDocuments = count(),\r\n TotalInputTokens = sum(input_tokens),\r\n TotalOutputTokens = sum(output_tokens),\r\n TotalTokens = sum(total_tokens),\r\n AvgTokensPerDocument = round(avg(total_tokens), 0)",
5563
"size": 3,
5664
"title": "Overall Token Usage Summary",
57-
"timeContext": {
58-
"durationMs": 604800000
59-
},
6065
"timeContextFromParameter": "TimeRange",
6166
"queryType": 0,
6267
"resourceType": "microsoft.insights/components",
@@ -76,16 +81,13 @@
7681
"type": 3,
7782
"content": {
7883
"version": "KqlItem/1.0",
79-
"query": "customEvents\r\n| where name == 'LLM_Agent_Token_Usage'\r\n| where timestamp > ago(7d)\r\n| extend agent = tostring(customDimensions['agent_name'])\r\n| extend process_id = tostring(customDimensions['process_id'])\r\n| extend input_tokens = toint(customDimensions['input_tokens'])\r\n| extend output_tokens = toint(customDimensions['output_tokens'])\r\n| extend total_tokens = toint(customDimensions['total_tokens'])\r\n| summarize input_tokens=max(input_tokens), output_tokens=max(output_tokens), total_tokens=max(total_tokens) by agent, process_id\r\n| summarize\r\n InputTokens = sum(input_tokens),\r\n OutputTokens = sum(output_tokens),\r\n TotalTokens = sum(total_tokens),\r\n Invocations = count()\r\n by Step = agent\r\n| order by TotalTokens desc",
84+
"query": "customEvents\r\n| where name == 'LLM_Agent_Token_Usage'\r\n| where timestamp > ago(7d)\r\n| extend agent = tostring(customDimensions['agent_name'])\r\n| extend process_id = tostring(customDimensions['process_id'])\r\n| extend input_tokens = toint(customDimensions['input_tokens'])\r\n| extend output_tokens = toint(customDimensions['output_tokens'])\r\n| extend total_tokens = toint(customDimensions['total_tokens'])\r\n| summarize input_tokens=max(input_tokens), output_tokens=max(output_tokens), total_tokens=max(total_tokens) by agent, process_id\r\n| summarize\r\n InputTokens = sum(input_tokens),\r\n OutputTokens = sum(output_tokens),\r\n TotalTokens = sum(total_tokens),\r\n Invocations = count()\r\n by Step = agent\r\n| project Step, InputTokens, OutputTokens, TotalTokens, Invocations\r\n| order by TotalTokens desc",
8085
"size": 0,
8186
"title": "Token Usage by Pipeline Step",
82-
"timeContext": {
83-
"durationMs": 604800000
84-
},
8587
"timeContextFromParameter": "TimeRange",
8688
"queryType": 0,
8789
"resourceType": "microsoft.insights/components",
88-
"visualization": "barchart"
90+
"visualization": "table"
8991
},
9092
"name": "tokens-by-agent"
9193
},
@@ -96,9 +98,6 @@
9698
"query": "customEvents\r\n| where name == 'LLM_Token_Usage_Summary'\r\n| where timestamp > ago(7d)\r\n| extend process_id = tostring(customDimensions['process_id'])\r\n| extend input_tokens = toint(customDimensions['total_input_tokens'])\r\n| extend output_tokens = toint(customDimensions['total_output_tokens'])\r\n| summarize input_tokens=max(input_tokens), output_tokens=max(output_tokens), timestamp=min(timestamp) by process_id\r\n| summarize InputTokens = sum(input_tokens), OutputTokens = sum(output_tokens) by bin(timestamp, 1h)\r\n| order by timestamp asc",
9799
"size": 0,
98100
"title": "Token Usage Over Time (Hourly)",
99-
"timeContext": {
100-
"durationMs": 604800000
101-
},
102101
"timeContextFromParameter": "TimeRange",
103102
"queryType": 0,
104103
"resourceType": "microsoft.insights/components",
@@ -113,9 +112,6 @@
113112
"query": "customEvents\r\n| where name == 'LLM_Agent_Token_Usage'\r\n| where timestamp > ago(7d)\r\n| extend agent = tostring(customDimensions['agent_name'])\r\n| extend process_id = tostring(customDimensions['process_id'])\r\n| extend total_tokens = toint(customDimensions['total_tokens'])\r\n| summarize total_tokens=max(total_tokens) by agent, process_id\r\n| summarize TotalTokens = sum(total_tokens) by agent",
114113
"size": 0,
115114
"title": "Token Distribution by Agent",
116-
"timeContext": {
117-
"durationMs": 604800000
118-
},
119115
"timeContextFromParameter": "TimeRange",
120116
"queryType": 0,
121117
"resourceType": "microsoft.insights/components",
@@ -137,9 +133,6 @@
137133
"query": "let input_price_per_million = 2.50;\r\nlet output_price_per_million = 10.00;\r\ncustomEvents\r\n| where name == 'LLM_Token_Usage_Summary'\r\n| where timestamp > ago(7d)\r\n| extend process_id = tostring(customDimensions['process_id'])\r\n| extend input_tokens = toint(customDimensions['total_input_tokens'])\r\n| extend output_tokens = toint(customDimensions['total_output_tokens'])\r\n| summarize input_tokens=max(input_tokens), output_tokens=max(output_tokens), timestamp=min(timestamp) by process_id\r\n| summarize TotalInput = sum(input_tokens), TotalOutput = sum(output_tokens) by bin(timestamp, 1d)\r\n| extend InputCost = round(TotalInput * input_price_per_million / 1000000.0, 4)\r\n| extend OutputCost = round(TotalOutput * output_price_per_million / 1000000.0, 4)\r\n| extend TotalCost = InputCost + OutputCost\r\n| project Day = timestamp, TotalInput, TotalOutput, InputCost, OutputCost, TotalCost\r\n| order by Day desc",
138134
"size": 0,
139135
"title": "Estimated Daily Cost (GPT-4o Pricing: $2.50/1M input, $10.00/1M output)",
140-
"timeContext": {
141-
"durationMs": 2592000000
142-
},
143136
"timeContextFromParameter": "TimeRange",
144137
"queryType": 0,
145138
"resourceType": "microsoft.insights/components",
@@ -154,9 +147,6 @@
154147
"query": "let gpt4o_input = 2.50;\r\nlet gpt4o_output = 10.00;\r\nlet gpt4o_mini_input = 0.15;\r\nlet gpt4o_mini_output = 0.60;\r\ncustomEvents\r\n| where name == 'LLM_Model_Token_Usage'\r\n| where timestamp > ago(7d)\r\n| extend model = tostring(customDimensions['model_deployment_name'])\r\n| extend input_tokens = toint(customDimensions['input_tokens'])\r\n| extend output_tokens = toint(customDimensions['output_tokens'])\r\n| summarize TotalInput = sum(input_tokens), TotalOutput = sum(output_tokens) by model\r\n| extend InputPrice = case(model has \"mini\", gpt4o_mini_input, gpt4o_input)\r\n| extend OutputPrice = case(model has \"mini\", gpt4o_mini_output, gpt4o_output)\r\n| extend InputCost = round(TotalInput * InputPrice / 1000000.0, 4)\r\n| extend OutputCost = round(TotalOutput * OutputPrice / 1000000.0, 4)\r\n| extend TotalCost = InputCost + OutputCost\r\n| project Model = model, TotalInput, TotalOutput, InputCost, OutputCost, TotalCost\r\n| order by TotalCost desc",
155148
"size": 0,
156149
"title": "Estimated Cost by Model",
157-
"timeContext": {
158-
"durationMs": 2592000000
159-
},
160150
"timeContextFromParameter": "TimeRange",
161151
"queryType": 0,
162152
"resourceType": "microsoft.insights/components",
@@ -178,9 +168,6 @@
178168
"query": "customEvents\r\n| where name == 'LLM_Model_Token_Usage'\r\n| where timestamp > ago(7d)\r\n| extend model = tostring(customDimensions['model_deployment_name'])\r\n| extend input_tokens = toint(customDimensions['input_tokens'])\r\n| extend output_tokens = toint(customDimensions['output_tokens'])\r\n| extend total_tokens = toint(customDimensions['total_tokens'])\r\n| summarize\r\n InputTokens = sum(input_tokens),\r\n OutputTokens = sum(output_tokens),\r\n TotalTokens = sum(total_tokens),\r\n Invocations = count()\r\n by Model = model\r\n| order by TotalTokens desc",
179169
"size": 0,
180170
"title": "Token Usage by Model",
181-
"timeContext": {
182-
"durationMs": 604800000
183-
},
184171
"timeContextFromParameter": "TimeRange",
185172
"queryType": 0,
186173
"resourceType": "microsoft.insights/components",
@@ -195,9 +182,6 @@
195182
"query": "customEvents\r\n| where name == 'LLM_Agent_Token_Usage'\r\n| where timestamp > ago(7d)\r\n| extend agent = tostring(customDimensions['agent_name'])\r\n| extend model = tostring(customDimensions['model_deployment_name'])\r\n| extend input_tokens = toint(customDimensions['input_tokens'])\r\n| extend output_tokens = toint(customDimensions['output_tokens'])\r\n| extend total_tokens = toint(customDimensions['total_tokens'])\r\n| summarize\r\n InputTokens = sum(input_tokens),\r\n OutputTokens = sum(output_tokens),\r\n TotalTokens = sum(total_tokens),\r\n Invocations = count()\r\n by Step = agent, Model = model\r\n| order by TotalTokens desc",
196183
"size": 0,
197184
"title": "Step-to-Model Token Mapping",
198-
"timeContext": {
199-
"durationMs": 604800000
200-
},
201185
"timeContextFromParameter": "TimeRange",
202186
"queryType": 0,
203187
"resourceType": "microsoft.insights/components",
@@ -212,9 +196,6 @@
212196
"query": "customEvents\r\n| where name == 'LLM_Token_Usage_Summary'\r\n| where timestamp > ago(7d)\r\n| extend total_tokens = toint(customDimensions['total_tokens'])\r\n| extend process_id = tostring(customDimensions['process_id'])\r\n| extend file_name = tostring(customDimensions['file_name'])\r\n| summarize TotalTokens = max(total_tokens) by process_id, file_name\r\n| order by TotalTokens desc\r\n| take 20",
213197
"size": 0,
214198
"title": "Top 20 Token Consumers by Document",
215-
"timeContext": {
216-
"durationMs": 604800000
217-
},
218199
"timeContextFromParameter": "TimeRange",
219200
"queryType": 0,
220201
"resourceType": "microsoft.insights/components",
@@ -229,9 +210,6 @@
229210
"query": "customEvents\r\n| where name == 'LLM_Token_Usage_Summary'\r\n| where timestamp > ago(7d)\r\n| extend process_id = tostring(customDimensions['process_id'])\r\n| extend total_tokens = toint(customDimensions['total_tokens'])\r\n| extend input_tokens = toint(customDimensions['total_input_tokens'])\r\n| extend output_tokens = toint(customDimensions['total_output_tokens'])\r\n| extend mime_type = tostring(customDimensions['file_mime_type'])\r\n| extend file_type = case(\r\n mime_type has \"pdf\", \"PDF\",\r\n mime_type has \"image\", \"Image\",\r\n mime_type has \"word\" or mime_type has \"docx\", \"Word\",\r\n mime_type has \"excel\" or mime_type has \"xlsx\", \"Excel\",\r\n mime_type has \"text\", \"Text\",\r\n \"Other\")\r\n| summarize input_tokens=max(input_tokens), output_tokens=max(output_tokens), total_tokens=max(total_tokens), file_type=take_any(file_type) by process_id\r\n| summarize\r\n Documents = count(),\r\n TotalInputTokens = sum(input_tokens),\r\n TotalOutputTokens = sum(output_tokens),\r\n TotalTokens = sum(total_tokens),\r\n AvgTokensPerDoc = round(avg(total_tokens), 0)\r\n by FileType = file_type\r\n| order by TotalTokens desc",
230211
"size": 0,
231212
"title": "Token Usage by File Type",
232-
"timeContext": {
233-
"durationMs": 604800000
234-
},
235213
"timeContextFromParameter": "TimeRange",
236214
"queryType": 0,
237215
"resourceType": "microsoft.insights/components",
@@ -253,9 +231,6 @@
253231
"query": "customEvents\r\n| where name == 'LLM_Token_Usage_Summary'\r\n| where timestamp > ago(7d)\r\n| extend process_id = tostring(customDimensions['process_id'])\r\n| extend total_tokens = toint(customDimensions['total_tokens'])\r\n| summarize total_tokens=max(total_tokens) by process_id\r\n| summarize\r\n p50 = percentile(total_tokens, 50),\r\n p90 = percentile(total_tokens, 90),\r\n p95 = percentile(total_tokens, 95),\r\n p99 = percentile(total_tokens, 99),\r\n Max = max(total_tokens)",
254232
"size": 3,
255233
"title": "Token Usage Percentiles Per Document",
256-
"timeContext": {
257-
"durationMs": 604800000
258-
},
259234
"timeContextFromParameter": "TimeRange",
260235
"queryType": 0,
261236
"resourceType": "microsoft.insights/components",
@@ -278,9 +253,6 @@
278253
"query": "customEvents\r\n| where name == 'LLM_Token_Usage_Summary'\r\n| where timestamp > ago(7d)\r\n| extend process_id = tostring(customDimensions['process_id'])\r\n| extend total_tokens = toint(customDimensions['total_tokens'])\r\n| summarize total_tokens=max(total_tokens), timestamp=min(timestamp) by process_id\r\n| summarize\r\n DocumentsProcessed = count(),\r\n TotalTokens = sum(total_tokens),\r\n AvgTokensPerDoc = round(avg(total_tokens), 0),\r\n MaxTokensPerDoc = max(total_tokens)\r\n by Day = bin(timestamp, 1d)\r\n| order by Day desc",
279254
"size": 0,
280255
"title": "Daily Processing Volume with Token Usage",
281-
"timeContext": {
282-
"durationMs": 2592000000
283-
},
284256
"timeContextFromParameter": "TimeRange",
285257
"queryType": 0,
286258
"resourceType": "microsoft.insights/components",
@@ -289,8 +261,14 @@
289261
"name": "daily-volume"
290262
}
291263
],
264+
"isLocked": true,
265+
"defaultResourceIds": [
266+
"/subscriptions/1d5876cd-7603-407a-96d2-ae5ca9a9c5f3/resourcegroups/rg-content-processing-token1/providers/microsoft.insights/components/appi-cptoken1kbxf2",
267+
"/subscriptions/1d5876cd-7603-407a-96d2-ae5ca9a9c5f3/resourceGroups/rg-pgcpfeat/providers/Microsoft.Insights/components/appi-pgcpfeatuw333"
268+
],
292269
"fallbackResourceIds": [
293-
"Azure Monitor"
270+
"/subscriptions/1d5876cd-7603-407a-96d2-ae5ca9a9c5f3/resourcegroups/rg-content-processing-token1/providers/microsoft.insights/components/appi-cptoken1kbxf2",
271+
"/subscriptions/1d5876cd-7603-407a-96d2-ae5ca9a9c5f3/resourceGroups/rg-pgcpfeat/providers/Microsoft.Insights/components/appi-pgcpfeatuw333"
294272
],
295273
"fromTemplateId": "community-Workbooks/Common/Templates"
296-
}
274+
}

0 commit comments

Comments
 (0)