The Power Apps trace function is one of the lesser-known gems in the developer’s toolbox. It allows you to send custom messages behind the scenes to log user activity, performance, potential errors and more.
In this article, you’ll learn how to use the function and how useful it is. It’s one of those things that can become a standard development pattern if you know what it can do.
Table of Contents
ToggleOverview
When we want users to know they’ve had a successful or failed interaction, we tend to use the notify function. We can customise the message presented and select a different option to colour the toast notification as per our requirements. But what if we want to log information without presenting it to the user?
The Power Apps trace function sends telemetry to Monitor and Azure App Insights. This means we can log information that might be pertinent to us as developers or IT support, less so for the app users. Examples might be:
– length of time it takes to run a large block of Power Fx
– length of time to retrieve a large volume of data
– track user journey through the application
– track errors for key functionality, such as patching records or calling an API
The trace function looks like:
Trace( Message [, TraceSeverity [, CustomRecord [, TraceOptions ] ] ] )
I’ll translate what that means in the real world shortly, but first a quick introduction to…
Monitor
For the examples in this article, I’ll refer to and access Monitor. This is a built-in tool that allows developers and makers to record the telemetry of a session or a series of interactions in an app. It’s great for debugging code or issues when an app is in production.
There are two ways to access Monitor:
As a maker
In the Power App maker studio, select Advanced tools, then select Open monitor:
This will open a new browser tab. Any testing you do of your app whilst in edit mode will be logged here:
This is where we can send our custom messages and logs using the Power Apps trace function.
As a user
Navigate to make.powerapps.com. In the relevant environment, find the app you want to record telemetry for. Click on the ellipsis, then Details, then Monitor:
When the new browser tab opens, select Play published app:
You’ll see some other cool options there too, designed to share your session & monitor details with others.
This way of accessing Monitor is ideal for helping IT support or developers understand user issues. You can even download the Monitor logs for further analysis. This is another epic reason to use the Power Apps trace function for detailed monitoring and information.
Simple trace
Let’s start small. We can add a very simple trace with a custom message and the exact time it was generated:
Trace($"Here is my message {Now()}")
With a fresh Monitor session open, we can see the message has been logged:
Clicking on that row will show the following side pane. We can see the message there too, along with other information such as what control and property was used to generate the trace:
Trace with severity
The Power Apps trace function can be extended with a severity. There are currently four available options.
Critical
For a critical message, you’ll need the following addition to your Power Fx:
Trace(
$"Here is my message {Now()}",
TraceSeverity.Critical
)
In Monitor, Error will show in the Result column. The line will also have an indicator to the far left to show there’s been an error:
Error
For an error message, you’ll need the following:
Trace(
$"Here is my message {Now()}",
TraceSeverity.Error
)
In Monitor, the appearance is exactly the same as for a critical trace. I compared the JSON for the two line entries side by side, literally have no idea what the difference is! So critical or error, you choose – it seems they both do the same.
Warning
For warning, it’s:
Trace(
$"Here is my message {Now()}",
TraceSeverity.Warning
)
In Monitor, we’ll get a different icon to the left. Warning will be the entry in the Result column:
Information
Lastly, we have information. I bet you can’t guess what the syntax will be:
Trace(
$"Here is my message {Now()}",
TraceSeverity.Information
)
From a Monitor perspective, there’s no icon & you’ll have Success shown in the Result column. Given that other app operations will return success, I’d rather an information trace said ‘information’:
Trace with severity and custom record
This is where you can get really creative. You can build a custom response as part of the Power Apps trace function to log any additional information you want. This can be hardcoded, variables or other functions.
In this example, I’m combining the Host function, hardcoded text, user information and an output of a variable that’s captured processing time of some Power Fx:
Trace(
$"Here is my message {Now()}",
TraceSeverity.Error,
{
OSType: Host.OSType,
SessionID: Host.SessionID,
Message: "It's completely FUBAR",
User: User().FullName,
ProcessDuration: $"{gvStart} seconds"
}
)
Monitor doesn’t show this additional information in the main logs. You have to click on the relevant line to show the side pane, that will show the custom record:
Keep it dry
With the Power Apps trace function, you can design ways to increase reusability. We can load a default, repeatable configuration via our OnStart property to preload some or all of our custom messages. This is handy if you have a variety of apps in your organisation, want to create a consistent experience and avoid duplicate, hard-coded entries.
To show this in more detail, I’ve constructed a SharePoint list. This will hold our repeatable messages that will be seen by IT Service Desks colleagues. The messages will help them answer the right questions or know where to route any queries. The list is a simple construct of Single Line of Text fields, except for Internal ID which is a number. The list can be managed centrally, makers will only need read-only access:
We can store some pre-canned Power Fx to plug into the OnStart of our apps to load in the SharePoint list. In the code, we can take the text entry of the Severity column to map it to the relevant severity in the trace function:
ClearCollect(
colTracePatterns,
AddColumns(
ShowColumns(
'Trace Patterns',
"InternalID",
"Title",
"Severity",
"Category",
"SupportLine",
"HintforSupport"
),
"Trace Severity",
// Map text of Severity to column to trace severities
Switch(
Severity,
"Information",TraceSeverity.Information,
"Warning",TraceSeverity.Warning,
"Critical",TraceSeverity.Critical,
"Error",TraceSeverity.Error
)
)
)
Any time we want to load standard text for a particular row, we can do so via a lookup. We can still include other properties in the custom message. In the example below, let’s retrieve data for ID 102, a functionality-based error.
This is a good use case for the With function too, so we’re not repeating the lookup to get values for title, severity, internal code etc. The lookup happens once & we can reference that for data:
// Use With to get relevant data
With(
{
tvTraceInfo: LookUp(
colTracePatterns,
InternalID = 102
)
},
// Take title, severity & static info from With output
Trace(
tvTraceInfo.Title,
tvTraceInfo.'Trace Severity',
{
// Static info from SPO list/collection
InternalCode: tvTraceInfo.InternalID,
Category: tvTraceInfo.Category,
SupportLine: tvTraceInfo.SupportLine,
SupportHint: tvTraceInfo.HintforSupport,
// Dynamic info from current session/user
OSType: Host.OSType,
SessionID: Host.SessionID,
User: User().FullName
}
)
);
Here we can see our custom message in the Monitor logs:
Combine with error functions
In the final example, we’ll combine the above logic with one of the error functions. Please note this is a preview feature so not recommended for production apps. That said, this is the ONLY preview feature I personally always use in production apps, it’s very reliable. But use at your own risk and/or in accordance with your internal standards and best practise.
In the example below, I have a patch statement that will create a new record in a data source. I’ll use IfError to evaluate whether the patch has been successful, setting an integer variable to record the outcome. I can then use that variable to feed into my Power Apps trace function:
// Patch record back to data source
IfError(
Patch(
ResponseJSONLarges,
Defaults(ResponseJSONLarges),
{
pop_name: "ABC123",
JSONResponse: JSON(colQuestions)
}
),
// Set error code if the brown stuff has hit the fan
Set(gvTraceCode,102),
// Set error code if all is tickety boo
Set(gvTraceCode,999)
);
// Use With to get relevant data, inject gvTraceCode variable set in IfError above
With(
{
tvTraceInfo: LookUp(
colTracePatterns,
InternalID = gvTraceCode
)
},
// Take title, severity & static info from With output
Trace(
tvTraceInfo.Title,
tvTraceInfo.'Trace Severity',
{
// Static info from SPO list/collection
InternalCode: tvTraceInfo.InternalID,
Category: tvTraceInfo.Category,
SupportLine: tvTraceInfo.SupportLine,
SupportHint: tvTraceInfo.HintforSupport,
// Dynamic info from current session/user
OSType: Host.OSType,
SessionID: Host.SessionID,
User: User().FullName
}
)
);
Et voilà :
Hopefully this insight into the Power Apps trace function has proved useful. It’s a really good support tool for monitoring performance, bottlenecks and errors.
Thanks for reading! If you liked this article and want to receive more helpful tips about Power Platform every week, don’t forget to subscribe 😊