Skip to content

Commit f4dc10a

Browse files
New doc about debugging canvas apps with the live monitor
1 parent 9ac1b5f commit f4dc10a

1 file changed

Lines changed: 270 additions & 0 deletions

File tree

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
---
2+
title: Debugging canvas apps with Live monitor and Trace
3+
description: Learn how to debug canvas apps across users and environments using Live monitor and the Trace function.
4+
author: carlosff
5+
ms.subservice: troubleshoot
6+
ms.topic: how-to
7+
ms.custom: canvas
8+
ms.date: 01/15/2026
9+
ms.author: carlosff
10+
search.audienceType:
11+
- maker
12+
contributors:
13+
- carlosff
14+
---
15+
16+
# Debugging canvas apps with Live monitor and Trace
17+
18+
You can use the [Live monitor](/power-apps/maker/monitor-canvasapps) together with the [Trace function](/power-platform/power-fx/reference/function-trace) to quickly diagnose issues in canvas apps—even those issues that appear only for certain users or in specific environments. The live monitor shows real-time events—network calls, data operations, errors, performance details—while Trace lets you emit structured diagnostic records that help you follow the values from behavior formulas at key moments in your app's logic.
19+
20+
This article builds on [Debugging canvas apps with Live monitor](/power-apps/maker/monitor-canvasapps) and [Collaborative troubleshooting using Live Monitor](/power-apps/maker/monitor-collaborative-debugging). Review those pages first if you're new to Live monitor.
21+
22+
## Why combine Live monitor and Trace
23+
24+
Live monitor gives you visibility into platform-level activity: data operations (`getRows`, `createRow`, `patch`), control evaluations, errors (HTTP status codes like 404 or 429), timing, and delegation indicators. By adding targeted Trace calls in your [behavior formulas](power-apps/maker/canvas-apps/working-with-formulas#manage-app-behavior) (for example, `OnSelect`, `OnVisible`, `OnStart`), you enrich those platform events with domain context: which user, which environment, which screen, entity counts, business flags, elapsed times, and any information that may help you better understand what the app is doing when it runs. Together they answer both "what happened" and "why it happened."
25+
26+
## Scenario 1: Works for one user but not another
27+
28+
Let's start with a common scenario that we see in many support requests: User A can submit orders successfully, while User B sees intermittent failures and the UI behaves differently (a discount checkbox is disabled for User B). You suspect the underlying data (for example, a missing role assignment or a flag value) differs between their accounts.
29+
30+
### Goal
31+
Capture what the app believes about the current user (email, roles, customer selection, discount eligibility) and correlate it with the data operations the platform performs.
32+
33+
### Steps
34+
35+
1. Open the app in Power Apps Studio.
36+
2. Add Trace calls in the `OnSelect` of the submit button (or in the logic that encapsulates submit).
37+
3. Save / publish the app.
38+
4. Open the Live monitor for the published app.
39+
5. To invite User A, select the 'Connect user' option
40+
6. As the User A runs through the app, you see the out-of-the-box events from the live monitor instrumented with the new Trace calls.
41+
7. Open a new instance of the Live monitor for the published app. Do the same for User B (invite the user, then have them play the app). You can now see the runtime details for that user.
42+
8. Compare the values, and try to find the difference that caused the app to behave incorrectly for one of the users.
43+
44+
**Example `OnSelect` formula with Trace**
45+
46+
```powerfx
47+
// Emit pre-submit context
48+
Trace(
49+
"Debug: Before Submit",
50+
TraceSeverity.Information,
51+
{
52+
user: User().Email,
53+
customerId: ddCustomer.Selected.Id,
54+
cartCount: CountRows(colCart),
55+
orderCountForCustomer: CountIf(Orders, Customer = ddCustomer.Selected),
56+
isVIP: ddCustomer.Selected.'VIP Flag',
57+
env: Param("env"),
58+
screen: App.ActiveScreen.Name
59+
}
60+
);
61+
62+
// Perform data operations (simplified)
63+
ForAll(colCart,
64+
Patch(Orders, Defaults(Orders), {
65+
Customer: ddCustomer.Selected,
66+
Product: ThisRecord.Product,
67+
Quantity: ThisRecord.Quantity
68+
})
69+
);
70+
71+
// Post-submit trace with elapsed time and any collected errors
72+
Trace(
73+
"Debug: After Submit"
74+
TraceSeverity.Information,
75+
{
76+
orderCountForCustomer: CountIf(Orders, Customer = ddCustomer.Selected)
77+
}
78+
);
79+
```
80+
81+
### Analyze
82+
83+
In Live monitor, filter by the Trace event type (or search for the name of the button, or for "Debug:" in the info). Compare User A vs User B:
84+
85+
* Do they have different `isVIP` values? That information could change the calculation for discounts.
86+
* Are cart counts identical? If not, upstream logic differs.
87+
* Are error traces present only for User B? Expand the event to inspect error payload details.
88+
89+
Then correlate Trace events with adjacent `getRows` / `patch` operations. If User B triggers extra data calls (perhaps a non-delegable `Filter` forcing multiple network requests), you can see them directly in the event table.
90+
91+
## Scenario 2: Works in one environment but not another
92+
93+
Your app behaves correctly in the **Test** environment but fails when deployed to **Production**: a gallery loads no items and submission is slow. Differences in the data between the two environments may be the cause—even though the app is the same, the data that comes through it can be different on different environments.
94+
95+
### Goal
96+
Surface environment-specific metadata and counts, then compare the sequence and status codes of data operations between environments. In this example, the app has one screen with a form where a **Product** selected from a gallery can be updated—and the update works on **Test** but fails in **Production**.
97+
98+
### Steps
99+
100+
1. On the test environment, add an `OnVisible` Trace on the affected screen (for example, order entry screen) to emit information about the selected product:
101+
102+
```powerfx
103+
Trace(
104+
"Debug: OnVisible on " & App.ActiveScreen.Name,
105+
TraceSeverity.Information,
106+
{
107+
recordId: varSelectedProduct.Id,
108+
hasDiscount: varSelectedProduct.HasDiscount,
109+
relatedOrders: CountIf(Orders, ProductId = varSelectedProduct.Id)
110+
}
111+
);
112+
```
113+
114+
2. Deploy the app with the new traces in the production environment.
115+
3. Open Live monitor in **Test** and then in **Production**; capture and export logs if needed (use the export option in Live monitor).
116+
117+
### Analyze network events
118+
119+
In the event list:
120+
121+
* Compare initial `getRows` for `Products` across environments—does one return 0 results or error codes (404 if table missing, 403 if access denied, 429 if throttled)?
122+
* Look for repeated `getRows` calls that may indicate a non-delegable formula being reevaluated.
123+
* In the trace emitted for the screen's OnVisible property, do the products have different values for `relatedOrders` or `hasDiscount`?
124+
125+
If you find a difference—for example, in the hasDiscount property for varSelectedProduct—you can go back to the place where that variable was created, and add more Trace calls to see how it was populated.
126+
127+
If there are errors in the network calls (such as 4xx responses), check whether the tables / flows / connectors are set up correctly in both the **Test** and **Production** environment.
128+
129+
## Viewing data flowing over the network
130+
131+
Live monitor surfaces each data operation event with:
132+
133+
* Operation type (`getRows`, `createRow`, `patch`, `removeRow`)
134+
* Data source (Dataverse table, connector name)
135+
* Timing (start/finish, duration)
136+
* Result (success, error status code like 429 for throttling)
137+
* Delegation hints (non-delegable operations cause client-side processing and more data traffic)
138+
139+
Select an event to inspect details and correlate them with nearby Trace events to understand *why* the operation occurred. For example, a `getRows` surge following a Trace with `phase: "ApplyFilters"` may indicate an inefficient filter expression.
140+
141+
> [!TIP]
142+
> When you see HTTP 429 (throttling), look at preceding network events to see whether a loop, or repeated evaluation triggered excessive operations (similar to the analysis in [Debugging canvas apps with Live monitor](/power-apps/maker/monitor-canvasapps)). Optimize formulas or introduce caching (collections) to reduce churn.
143+
144+
## Using Trace effectively
145+
146+
The [Trace function](/power-platform/power-fx/reference/function-trace) writes a structured record to Live monitor. Key points:
147+
148+
* Works only in behavior properties (for example, `OnSelect`, `OnChange`, `OnVisible`, `OnStart`).
149+
* Accepts simple text values, but also a record payload—where we can include more details for the information being traced.
150+
* TraceSeverity helps filter (Information, Warning, Error). Use Error severity sparingly for true failures.
151+
* Minimal performance impact when used judiciously; remove or guard traces in production if they become noisy.
152+
153+
### Tracing data property values (debug-only buttons)
154+
155+
Because Trace can't be placed directly inside data properties (like a label's `Text`), you can surface those values through temporary debug-only controls. It's also useful to trace the values that are used to calculate the data property, as they may indicate why the value isn't the expected one.
156+
157+
1. Add a button `btnDebugSnapshot` with `Visible = Param("debug") = "true"`.
158+
2. In its `OnSelect`, call Trace with a snapshot record.
159+
3. When playing the app under the live monitor, add a query string parameter (`&debug=true`) to show the button.
160+
161+
**Example debug snapshot button**
162+
163+
```powerfx
164+
// Visible property: Param("debug") = "true"
165+
// OnSelect:
166+
Trace(
167+
"Debug: Label value: " & Label1.Text,
168+
TraceSeverity.Information,
169+
{
170+
kind: "DataSnapshot",
171+
user: User().Email,
172+
customerCount: CountRows(Customers),
173+
productCount: CountRows(Products),
174+
maxPrice: Max(Products, Price),
175+
selectedProductId: If(!IsBlank(galProducts.Selected), galProducts.Selected.ProductId)
176+
}
177+
);
178+
```
179+
180+
> [!NOTE]
181+
> Guard debug-only controls with query string parameters (like `debug=true`) or role checks so end users don't see them. While **Trace** calls have minimum performance impact, those "debug controls" do add some complexity to the app, so you should remove them before finalizing the app once they aren't needed anymore.
182+
183+
## When Live monitor can't be used
184+
185+
Some hosted or embedded scenarios (for example, SharePoint integrated forms, custom pages, certain custom portal embeddings) don't support opening Live monitor alongside the app. In these cases, consider alternatives:
186+
187+
| Alternative | Use case | Notes |
188+
|-------------|----------|-------|
189+
| [Application Insights integration](/power-apps/maker/canvas-apps/application-insights) | Centralized telemetry & performance | Requires setup; emits traces and metrics outside Power Apps. |
190+
| Dataverse logging table | Ad-hoc diagnostics, audit trails | Create a `Debug Logs` table; use guarded Trace-like logic that uses `Patch` to create records when `Param("debug")="true"`. |
191+
| SharePoint list logging | Lightweight environments without Dataverse | Use `Collect` / `Patch` to a list; prune entries to control size. |
192+
| On-screen diagnostics panel | Immediate user feedback | Only for secure audiences; remove before broad rollout. |
193+
194+
**Example: Writing a debug record to Dataverse when Live monitor isn't available**
195+
196+
```powerfx
197+
If(Param("debug") = "true",
198+
Patch(
199+
'Debug Logs',
200+
Defaults('Debug Logs'),
201+
{
202+
Title: "BeforeSubmit",
203+
UserEmail: User().Email,
204+
CartCount: CountRows(colCart),
205+
Timestamp: Now(),
206+
Payload: JSON({customerId: ddCustomer.Selected.Id})
207+
}
208+
)
209+
);
210+
```
211+
212+
**Example: creating a diagnostics panel on the screen when Live monitor isn't available**
213+
214+
1. In places where a `Trace` call would be made, change it to a `Collect` call to a local collection
215+
2. Add a text control to the screen, only visible for certain users or depending on a query string parameter, that displays the locally collected traces
216+
217+
```powerfx
218+
// "Tracing" data to the collection
219+
If(
220+
Param("debug") = "true",
221+
Collect(
222+
debugTraces,
223+
{
224+
Timestamp: Now(),
225+
Data: $"Before submit for {User().Email} with {CountRows(colCart)} items in the cart"
226+
}
227+
)
228+
)
229+
```
230+
231+
Add this label to the screen, which shows the traces that can be copied and viewed outside the app
232+
```yaml
233+
- TextCanvas1:
234+
235+
Properties:
236+
Height: =200
237+
Size: =12
238+
Text: |-
239+
=Concat(
240+
debugTraces,
241+
$"[{Text(Timestamp,"hh:mm:ss.fff")}] {Data}",
242+
Char(10))
243+
Visible: =Param("debug") = "true"
244+
Width: =200
245+
X: =Parent.Width - 220
246+
Y: =20
247+
```
248+
249+
> [!NOTE]
250+
> Once you understand the issue, remove the debug controls (or make them invisible) to prevent users from accidentally seeing them if they open the app with the debug query string parameter.
251+
252+
## Checklist for effective debugging
253+
254+
1. Reproduce with Live monitor open (Studio or published session).
255+
2. Add Trace calls at key phases (start, decision, end, error handlers) when further details are needed.
256+
3. Use query string parameters (`Param`) to tag environment or enable debug controls.
257+
4. Compare traces across users/environments; look for divergent flags or counts.
258+
5. Correlate Trace phases with network events (throttling, errors, extra calls).
259+
7. Remove or guard Trace calls before broad deployment if verbose.
260+
261+
## Next steps
262+
263+
[Collaborative debugging with Live monitor](/power-apps/maker/monitor-collaborative-debugging)
264+
[Advanced monitoring](/power-apps/maker/monitor-advanced)
265+
[Live monitor overview](/power-apps/maker/monitor-overview)
266+
[Trace function reference](/power-platform/power-fx/reference/function-trace)
267+
268+
### See also
269+
270+
[Debugging canvas apps with Live monitor](/power-apps/maker/monitor-canvasapps)

0 commit comments

Comments
 (0)