# Custom Logging in Power Automate

Handling errors gracefully within your flow logic is important. Fortunately, there is plenty of guidance to be found on the subject:

* [Error Handling - THE FLYING POLYMATH](https://www.flyingpolymath.com/post/error-handling-in-power-automate-for-the-business-user)
    
* [Try Catch - D365 Demystified](https://d365demystified.com/2022/01/20/try-catch-error-handling-using-scope-in-power-automate/)
    
* [Error Handling Standards - Matthew Devaney](https://www.matthewdevaney.com/power-automate-coding-standards-for-cloud-flows/power-automate-standards-error-handling/)
    

How can we investigate exceptions without wading through countless pages of flow run history?

If integrating with [Azure Application Insights](https://learn.microsoft.com/en-us/power-platform/admin/app-insights-cloud-flow) is not in scope and the information available within the [Automation Center](https://learn.microsoft.com/en-us/power-platform/release-plan/2024wave1/power-automate/automation-center-monitor-manage-all-automations-related-assets) is not granular or specific enough, consider custom event logging.

## Scenarios / Use Cases

<div data-node-type="callout">
<div data-node-type="callout-emoji">🏭</div>
<div data-node-type="callout-text">Performing bulk content operations and a certain percentage of failures is expected</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">📆</div>
<div data-node-type="callout-text">Building a solution that involves chronological activities and events</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">🧺</div>
<div data-node-type="callout-text">Collecting flow errors in a centralized location, instead of relying on “push” notifications</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">🤖</div>
<div data-node-type="callout-text">Providing visibility to runs from higher environments or from a service account context</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">🖥</div>
<div data-node-type="callout-text">Displaying flow outcome data adjacent to the automation context (for SPO scenarios)</div>
</div>

## Log List Examples

### Approval Event History

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735761262537/441478ff-d5ef-47a0-bd2a-ffcb692af42b.png align="center")

### Scheduled Automation

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735762931024/12a90626-2740-405c-98eb-e84deca7f186.png align="center")

### Bulk Content Sync

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735762844036/51ac9590-b307-4d76-bc86-b21f24bef99a.png align="center")

## Creating a Log or Event List

### Columns

There’s no perfect recipe, but I usually include a column for each of these values:

* Run outcome (success, error, warning, etc.)
    
* Outcome details
    
* Associated item title
    
* Associated item ID
    
* Flow run ID
    

Then, add additional columns **for your specific logging scenario**, as needed.

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Keep in mind, simplicity is the goal here. Use single-line text columns whenever possible - avoid choice fields or complex data types (lookup columns, etc.)</div>
</div>

For ALM scenarios, you may find adding these helpful:

* Flow name
    
* Solution name
    
* Environment
    

### Configuration Tips

1. Disable search on the list (advanced settings) or restrict list permissions to only the relevant individuals/audiences
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735765616171/b2fd104d-1aa6-40b4-a98f-ee6b0cb47074.png align="center")
    
2. Index any columns that might be needed for sorting/filtering
    
3. Include a multi-line plain text column, if you’d like to store JSON output
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735764688679/9a988e4b-d5a4-4617-ac1f-72ff0c5312d5.png align="center")
    
4. Create view(s) and add [custom column formatting](https://learn.microsoft.com/en-us/sharepoint/dev/declarative-customization/column-formatting), if that helps readability
    
5. Examine the list after log entries start to populate - you may think of another field or two worth capturing
    

### Cloning an Existing List

Assuming custom logging proves useful, you may want to create more lists in the future. You can use an existing list as a template, to speed creation. Some options:

* [ShareGate](https://sharegate.com/microsoft-migration) migration tool
    
* *Use an existing list* option in the SharePoint UI (under site contents)
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735765649874/050dbbc0-0fde-4d87-8d3a-699304bebdc3.png align="center")
    
* Microsoft Lists
    

## Adding Logging Actions

Once your list is ready, it’s time to add some flow logic. New log entries will be added using a [*Create Item*](https://learn.microsoft.com/en-us/connectors/sharepointonline/#create-item) action.

There are two general approaches for adding logging steps - both achieve the same result, but have different considerations.

### Add to Existing Flow(s)

You can sprinkle logging actions within your **existing** flow logic, utilizing copy/paste.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735765917259/21830ba7-69e8-482e-b112-8cd074611504.png align="center")

| **Pros** | **Cons** |
| --- | --- |
| Simple, fast approach | If the list schema changes, you may need to update (and find) all previously-added actions |
| No additional licensing cost | Cannot add additional actions later (like sending notifications) unless done manually |
| Can store complex data types, JSON |  |
| Uses existing SharePoint Online connection / reference (if present) |  |

### **Create Standalone Logging Flow**

Alternatively, you can create a separate flow (HTTP trigger or [child solution flow](https://learn.microsoft.com/en-us/power-automate/create-child-flows)) to store your logging steps:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735765881733/9a7898f1-6c86-4ded-942f-6848c0e68564.png align="center")

Once created, invoke it from existing flow(s) as needed:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735767554600/e8b1cbff-3b89-4ce4-a175-5cb53f893307.png align="center")

| **Pros** | **Cons** |
| --- | --- |
| Much easier to extend later, if needed | Additional setup time and complexity |
| Can handle complex data types (HTTP trigger only) | Requires premium licensing (HTTP trigger only) |
| One logging flow can be shared by multiple solutions / flows | Need to collect and send parent workflow context |
| Option to run asynchronously - won’t hold up parent flow |  |

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Don’t forget a <strong>Response</strong> action (for HTTP trigger flows) or <strong>Respond to Power Apps or Flow</strong> action (for child solution flows)</div>
</div>

## Other Notes

* Consider disabling retry policies whenever a standalone logging flow gets invoked or a Create Item log action is called. You don’t want to hold up a parent flow run in the unlikely event that logging hits a snag.
    
* For logging hierarchical flow outcomes, consider creating an entry for when the parent begins, ends, and every child iteration in between. Store a shared identifier (like parent flow run ID) to help group entries later.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1735768845180/6457ef32-43ab-4bbf-a215-f09932ffd049.png align="center")
    
* Calculating overall flow run duration, error and success totals, etc. can add additional value to the last log entry for a given flow run. Don’t spend the time adding that logic unless the extra insight is worth it, however.
    
* You can use the logging technique described on this page to store errors / exceptions only, or you can include successful outcomes and other event types, depending on the situation.
