For any automation tool, logging is pretty important. Though I would also say readability of the logs is something one should also think about when writing code.
The general consensus in AA for logging is that one should use:
as the accepted ways of moving information to the different log types. Here I want to focus on Write-Error, and how one can structure its use to get good readable logs in AA. In addition I will speak to handling error situations in general as an extension to this. Specific how I combine the use of try/catch and Write-Error flow in Runbooks I author.
This pattern has evolved to compensate for some of the quirks of AA when it comes to logging. Specifically when one in addition use
-ErrorAction SilentlyContinue/Continue/Stop controlling the error behaviour when calling functions.
Let’s start with the following skeleton example:
Import-Module -Name AzureRM.Profile, AzureRM.Automation, AzureRM.Insights -ErrorAction Continue -ErrorVariable oErr
Write-Error -Message "Failed to load needed modules for Runbook" -ErrorAction Stop
Write-Error -Message "$($_.Exception.Message)" -ErrorAction Continue
Write-Error -Message "$($_.Exception)" -ErrorAction Continue
Write-Verbose -Message "Runbook ended at time: $(get-Date -format r)"
A couple things to note here. I use both -ErrorAction and -ErrorVariable when I call functions. For ErrorAction I use Continue, this is so that if calling the function generates an error it will send the error the way the function author designed it to look into the AA logs. In addition the code flow will continue after the error is thrown.
The ErrorVariable parameter comes into play because seldom the error coming from the function is friendly to the eyes. Therefore I add a capture of the potential error into a variable in addition. This makes me able to test if an error happened through the $oErr variable. I can then add a more friendly error description using Write-Error. Most of the time I want the code execution to stop when an error occurs, and this can be accomplished by adding -ErrorAction Stop. Usually this would be it and one could move on with life.
Though there are two main quirks in AA I need to compensate for. Just stopping the code flow of the Runbook with -ErrorAction Stop, one will get a successful status for the execution of the Runbook (No error show up in the Runbook execution logs in the portal). This is why I use a Try/Catch wrapper around my code, so when the Stop error action triggers the code flow will end up in the Catch section before exiting the Runbook. Here I make sure to first write the error again to the AA logs. This is to compensate for when using -ErrorAction Stop, the message in the Write-Error (“Failed to load needed modules for Runbook”) does NOT get written to the logs when running in Azure Automation.
So this is why I have another Write-Error call in the catch section to make sure the error message from the previous Write-Error call gets sent to the logs. In addition I make use of the Throw statement; this to make sure the Runbook ends up with a status of Failed. As mentioned previous just using -ErrorAction Stop, the Runbook will halt, though the status of the run will be set to Successful. I like to fail runbooks that has errors in them, so it is easy to check the status at a glance in the portal.
I like to call this the “Stop on Error” pattern. In my next post i will examine the “Continue on Error” pattern.
That’s it for this time.