You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-`rg_location`: Azure region (default: `Region.EAST_US_2`)
176
176
-`index`: Deployment index for resource naming (default: 1)
177
177
-`deployment`: Selected infrastructure type (reference INFRASTRUCTURE enum options)
178
178
-`api_prefix`: Prefix for APIs to avoid naming collisions
@@ -407,6 +407,7 @@ Check `docs/README.md` for local preview instructions and styling notes. The pag
407
407
- Existing cells must keep a unique `metadata.id` value.
408
408
- New cells do not need a `metadata.id` value unless an editor or tool assigns one.
409
409
- Keep notebook JSON logically structured and valid. Do not emit partial notebook fragments when a full notebook document is required.
410
+
- Place **all**`import` statements at the top of every code cell, before any other code. Never nest imports inside `if` / `else` / `try` blocks within a cell. Ruff's `PLC0415` does not flag imports inside module-level conditionals, so this must be enforced manually.
410
411
- When describing notebook changes to users, refer to cells by visible cell number (Cell 1, Cell 2, etc.), not by internal cell IDs.
Copy file name to clipboardExpand all lines: .github/python.instructions.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,6 +20,7 @@ This ensures all code changes comply with the project's linting standards from t
20
20
- Use explicit imports (avoid `from module import *`), especially in notebooks, to prevent `F403/F405`.
21
21
- Keep lines within the configured length limit (see `pyproject.toml`), and wrap long strings or calls.
22
22
- Avoid f-strings without placeholders (e.g., `F541`).
23
+
-**Ruff gap:**`PLC0415` (`import-outside-toplevel`) only flags imports inside functions and classes. It does **not** flag imports inside module-level `if` / `else` / `try` blocks. Ruff will not catch those, so the top-of-file import rule below must be enforced manually.
23
24
24
25
## Goals
25
26
@@ -35,7 +36,7 @@ This ensures all code changes comply with the project's linting standards from t
35
36
## Style and Conventions
36
37
37
38
- Prefer Python 3.12+ features unless otherwise required.
38
-
- Keep all imports at the top of the file.
39
+
- Keep **all** imports at the top of the file. Do not place `import` statements inside `if` / `else` / `try` blocks or inside functions. Hoist them even when only one branch uses the module. Ruff `PLC0415` will catch function-scope imports but will **not** catch imports inside module-level conditional blocks, so apply this rule manually.
39
40
- Use type hints and concise docstrings (PEP 257).
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -67,7 +67,7 @@ It's quick and easy to get started!
67
67
|[AuthX][sample-authx]| Authentication and role-based authorization in a mock HR API. | All infrastructures |
68
68
|[AuthX Pro][sample-authx-pro]| Authentication and role-based authorization in a mock product with multiple APIs and policy fragments. | All infrastructures |
69
69
|[Azure Maps][sample-azure-maps]| Proxying calls to Azure Maps with APIM policies. | All infrastructures |
70
-
|[Costing][sample-costing]| Track and allocate API costs per business unit using APIM subscriptions, Log Analytics, and Cost Management. | All infrastructures |
70
+
|[Costing][sample-costing]| Track and allocate API costs per business unit using APIM subscriptions, Entra ID application tracking, and AI Gateway token/PTU tracking via Log Analytics and Cost Management.| All infrastructures |
71
71
|[Egress Control][sample-egress-control]| Control APIM outbound internet traffic by routing it through a Network Virtual Appliance (NVA) in a hub/spoke topology. | appgw-apim, appgw-apim-pe |
72
72
|[General][sample-general]| Basic demo of APIM sample setup and policy usage. | All infrastructures |
73
73
|[Load Balancing][sample-load-balancing]| Priority and weighted load balancing across backends. | apim-aca, afd-apim-pe |
<p>Track and allocate API costs per business unit using subscriptions, Log Analytics, and Cost Management.</p>
449
+
<p>Track and allocate API costs per business unit using subscriptions, Entra ID application tracking, and AI Gateway token/PTU tracking via Log Analytics and Cost Management.</p>
Copy file name to clipboardExpand all lines: samples/costing/README.md
+70-37Lines changed: 70 additions & 37 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Samples: APIM Costing & Showback
2
2
3
-
This sample demonstrates how to track and allocate API costs using Azure API Management with Azure Monitor, Application Insights, Log Analytics, and Cost Management. This setup enables organizations to determine the cost of API consumption per business unit, department, or application.
3
+
This sample demonstrates how to track and allocate API costs using Azure API Management with Azure Monitor, Application Insights, Log Analytics, and Cost Management. It supports three complementary approaches: **subscription-based** tracking (using APIM subscription keys), **Entra ID application** tracking (using the `emit-metric` policy with JWT `appid` claims), and **AI Gateway token/PTU** tracking (using the `emit-metric` policy to capture per-client token consumption when APIM acts as an AI Gateway). All approaches share a single Azure Monitor Workbook with tabbed views.
4
4
5
5
⚙️ **Supported infrastructures**: All infrastructures (or bring your own existing APIM deployment)
6
6
@@ -9,10 +9,13 @@ This sample demonstrates how to track and allocate API costs using Azure API Man
9
9
## 🎯 Objectives
10
10
11
11
1.**Track API usage by caller** - Use APIM subscription keys to identify business units, departments, or applications
12
-
2.**Capture request metrics** - Log subscriptionId, apiName, operationName, and status codes
13
-
3.**Aggregate cost data** - Combine API usage metrics with Azure Cost Management data
14
-
4.**Visualize showback data** - Create Azure Monitor Workbooks to display cost allocation by caller
15
-
5.**Enable cost governance** - Establish patterns for consistent tagging and naming conventions
12
+
2.**Track API usage by Entra ID application** - Use the `emit-metric` policy to extract `appid`/`azp` JWT claims and emit per-caller custom metrics
13
+
3.**Capture request metrics** - Log subscriptionId, apiName, operationName, and status codes
14
+
4.**Aggregate cost data** - Combine API usage metrics with Azure Cost Management data
15
+
5.**Visualize showback data** - Create Azure Monitor Workbooks with tabbed views for both approaches
16
+
6.**Enable cost governance** - Establish patterns for consistent tagging and naming conventions
8.**Track AI token consumption per client** - When APIM is used as an AI Gateway, capture prompt, completion, and total token usage per calling application, enabling per-client cost attribution for PTU or pay-as-you-go OpenAI deployments
16
19
17
20
## ✅ Prerequisites
18
21
@@ -50,46 +53,35 @@ Users who only need to **view** the deployed Azure Monitor Workbook (not deploy
50
53
51
54
## ⚙️ Configuration
52
55
53
-
### Important: Sample Index
56
+
### Deployment Index
54
57
55
-
The `create.ipynb` notebook passes a**`sampleIndex` parameter** to the Bicep template. This parameter ensures unique resource naming when deploying multiple instances of this sample. The notebook automatically provides this value; you only need to verify it matches your deployment scenario:
58
+
The `create.ipynb` notebook passes an**`index` parameter** to the Bicep template. This parameter ensures unique resource naming when deploying multiple instances of this sample. The notebook automatically provides this value; you only need to verify it matches your deployment scenario:
56
59
57
60
```python
58
-
sample_index=2#Increment this for multiple sample deployments
61
+
index=1#Match your infrastructure deployment index
59
62
```
60
63
61
-
This index is used in resource names (e.g., `appi-cost-2-xxxx`, `log-cost-2-xxxx`) to avoid naming conflicts when running multiple instances of the sample.
64
+
This index is used in resource names (e.g., `appi-cost-1-xxxx`, `log-cost-1-xxxx`) to avoid naming conflicts.
62
65
63
-
### Option A: Use a repository infrastructure (recommended)
66
+
### Running the Sample
64
67
65
68
1. Navigate to the desired [infrastructure](../../infrastructure/) folder (e.g., [simple-apim](../../infrastructure/simple-apim/)) and follow its README.md to deploy.
66
69
2. Open `create.ipynb` and set:
67
70
```python
68
-
infrastructure =INFRASTRUCTURE.SIMPLE_APIM# Match your deployed infra
69
-
index =1# Match your infra index
70
-
sample_index =1# Increment for multiple sample deployments
71
+
deployment =INFRASTRUCTURE.SIMPLE_APIM# Match your deployed infra
72
+
index =1# Match your infra index
71
73
```
72
74
3. Run All Cells.
73
75
74
-
### Option B: Bring your own existing APIM
75
-
76
-
You can use any existing Azure API Management instance. The sample only adds diagnostic settings and sample resources to your APIM - it does **not** modify your existing APIs or policies.
77
-
78
-
1. Open `create.ipynb` and **uncomment** the two lines in the User Configuration section:
79
-
```python
80
-
existing_rg_name ='your-resource-group-name'
81
-
existing_apim_name ='your-apim-service-name'
82
-
```
83
-
2. Set the correct Azure subscription: `az account set -s <subscription-id>`
84
-
3. Run All Cells.
85
-
86
76
**What the sample deploys into your resource group:**
87
77
- Application Insights instance
88
78
- Log Analytics Workspace
89
79
- Storage Account (for cost exports)
90
80
- Diagnostic Settings on your APIM (routes gateway logs to Log Analytics)
91
81
- Azure Monitor Workbook
92
-
- A sample API (`cost-tracking-api`) with 5 business unit subscriptions
82
+
- Sample APIs with 4 business unit subscriptions
83
+
- Entra ID tracking API with `emit-metric` policy (optional)
84
+
- AI Gateway token tracking API with `emit-metric` policy (optional)
93
85
94
86
**What it does NOT touch:**
95
87
- Your existing APIs, policies, or subscriptions
@@ -109,6 +101,19 @@ Organizations often need to allocate the cost of shared API Management infrastru
109
101
110
102
This sample focuses on **producing cost data**, not implementing billing processes. You determine costs; how you use that information (showback reports, chargeback, budgeting) is a separate business decision.
111
103
104
+
### Three Tracking Approaches
105
+
106
+
| Aspect | Subscription-Based | Entra ID Application | AI Gateway Token/PTU |
|**Cost Management export**| Yes (storage account) | No (metrics-based) | No (metrics-based) |
113
+
|**Best for**| Dedicated subscriptions per BU | OAuth client-credentials flows, shared subscriptions | AI Gateway scenarios (Azure OpenAI, PTU capacity planning) |
114
+
115
+
All three approaches are deployed together. Toggle `enable_entraid_tracking` and `enable_token_tracking` in the notebook to include or exclude each flow.
116
+
112
117
## 🛩️ Lab Components
113
118
114
119
This lab deploys and configures:
@@ -118,15 +123,14 @@ This lab deploys and configures:
- Cost allocation table (base + variable cost per BU)
124
-
- Base vs variable cost stacked bar chart
125
-
- Cost breakdown by API
126
-
- Request count and distribution charts
127
-
- Success/error rate analysis
128
-
- Response code distribution
129
-
-**Live Pricing Integration** - Auto-detects your APIM SKU and fetches current pricing from the [Azure Retail Prices API](https://learn.microsoft.com/rest/api/cost-management/retail-prices/azure-retail-prices)
126
+
-**Sample API & Subscriptions** - 4 subscriptions representing different business units
127
+
-**Entra ID Tracking API** (optional) - A second API with the `emit-metric` policy that extracts `appid` from JWT tokens and emits `caller-requests` custom metrics
128
+
-**AI Gateway Token Tracking API** (optional) - A third API with the `emit-metric` policy that parses Azure OpenAI response bodies to extract `prompt_tokens`, `completion_tokens`, and `total_tokens`, emitting `caller-tokens` custom metrics with `CallerId`, `TokenType`, and `Model` dimensions
-**Subscription-Based Costing tab**: Cost allocation table (base + variable cost per BU), base vs variable cost stacked bar chart, cost breakdown by API, request count and distribution charts, success/error rate analysis, response code distribution, business unit drill-down
131
+
-**Entra ID Application Costing tab**: Usage by caller ID (bar chart + table), cost allocation by caller (table + pie chart), hourly request trend by caller
132
+
-**AI Gateway Token/PTU tab**: Token consumption by client (prompt vs completion bar chart), token cost allocation table with configurable per-1K-token rates, token/cost distribution pie charts, hourly token trend with PTU capacity threshold line, prompt vs completion area chart, model breakdown table
133
+
-**SKU-Based Pricing** - Automatically derives base monthly cost, overage rate, and included request allowance from the deployed APIM SKU using built-in pricing data (sourced from the [Azure API Management pricing page](https://azure.microsoft.com/pricing/details/api-management/), March 2026)
130
134
-**Budget Alerts** (optional) - Per-BU scheduled query alerts when request thresholds are exceeded
131
135
132
136
### Cost Allocation Model
@@ -153,10 +157,10 @@ This lab deploys and configures:
153
157
154
158
After running the notebook, you will have:
155
159
156
-
1.**Application Insights** showing real-time API requests
160
+
1.**Application Insights** showing real-time API requests and `caller-requests` custom metrics (Entra ID)
157
161
2.**Log Analytics** with queryable `ApiManagementGatewayLogs` (resource-specific table)
158
162
3.**Storage Account** receiving cost export data
159
-
4.**Azure Monitor Workbook**displaying cost allocation and usage analytics
163
+
4.**Azure Monitor Workbook**with tabbed views for both subscription-based and Entra ID cost allocation
160
164
5.**Portal links** printed in the notebook's final cell for quick access
161
165
162
166
### Cost Management Export
@@ -181,6 +185,30 @@ The deployed workbook provides a comprehensive view of API cost allocation and u
The Entra ID tab shows cost attribution by calling application, using the `emit-metric` policy's `caller-requests` custom metric.
193
+
194
+

195
+
196
+

197
+
198
+

199
+
200
+
### AI Gateway Token/PTU Tab
201
+
202
+
The AI Gateway tab shows per-client token consumption and estimated costs when APIM is used as an AI Gateway in front of Azure OpenAI or other LLM backends. It uses the `emit-metric` policy's `caller-tokens` custom metric with `CallerId`, `TokenType` (prompt/completion/total), and `Model` dimensions.
203
+
204
+

0 commit comments