Logging all unhandled exceptions in .NET

a year ago

With most applications its easy to get started on logging.

  • Install a logging framework like NLog or log4net.
  • Put try catches around your main program logic and include contextual information with the exception.
  • If its a web application use a logging middleware for your web framework.

However this will not log unhandled exceptions from places you couldn’t forsee. So let’s log these just in case anything goes wrong.

Any exceptions which crash the application can be handled using the UnhandledException event.

AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
Log.Exception((Exception)args.ExceptionObject);
};

This will help you diagnose fatal errors. Unfortunately not all exceptions are fatal, and if you have any timers, unawaited async or unhandled task pool exceptions these can cause your application to behave unexpectedly without you knowing about it.

You can use the UnobservedTaskException to catch some of those ones:

TaskScheduler.UnobservedTaskException += (sender, args) =>
{
if (!args.Observed)
{
Log.Exception(args.Exception);
}
};

If you know any other events or ways to get more of these unexpected errors please let me know!



Attaching and formatting drives with Azure ARM and PowerShell

a year ago

Setting up a virtual machine in Azure using ARM has been made straightforward, even with one-click deployments. If you have any services that need a bigger disk, there are a few more moving parts to get it working. This is based on the custom script quickstart template and Ed Wilsons formatting script article

Attach a disk

To attach a data disk to the virtual machine you can use the following configuration just below the osDisk definition.

{
"dataDisks":[{
"lun":0,
"name":"datadisk",
"diskSizeGB":1000,
"createOption":"Empty",
"vhd":{
"Uri":"[variables('dataDiskUri')]"
}
}]
}
  • lun (Logical Unit Number) should be unique for each attached disk and starts from zero.
  • diskSizeGB has a maximum of 1000 (1 TB) in Azure currently.
  • createOption should be “Empty” for a new disk.
  • vhd.Uri is the full path you want the blob created in.

If we deployed the template with this now, we will get a raw unformatted disk with no drive label. You can view it in Disk Manager or by running the following PowerShell on the box.

Get-Disk | Where partitionstyle -eq 'raw'

We need one more resource to complete the deployment and give us a formatted disk. We can use the CustomScriptExtension to run a PowerShell script which will format any raw attached disks (in case you want to do multiple drives).

{
"type":"Microsoft.Compute/virtualMachines/extensions",
"name":"[concat(variables('vmName'),'/InitialiseDisks')]",
"apiVersion":"2015-05-01-preview",
"location":"[resourceGroup().location]",
"dependsOn":[
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
],
"properties":{
"publisher":"Microsoft.Compute",
"type":"CustomScriptExtension",
"typeHandlerVersion":"1.2",
"settings":{
"fileUris":[
"[variables('initialiseDisksScript')]"
],
"commandToExecute":"[concat('powershell -ExecutionPolicy Unrestricted -file ',parameters('scriptName'))]"
}
}
}
  • dependsOn will need to be the resource path for our virtual machine to ensure this extension is run after its provisioned.
  • fileUris is an array of any files we want downloaded and made available to execute. This needs to be a path to an azure blob, unfortunately you cannot link to any other domains like github.
  • commandToExecute is a cmd.exe command, so we need to call out to powershell to invoke our script. The working directory will have your downloaded file already there, so you don’t need the full path to execute it, just the name.

You will need to upload the following script to a blob:

Get-Disk | `
Where partitionstyle -eq 'raw' | `
Initialize-Disk -PartitionStyle MBR -PassThru | `
New-Partition -AssignDriveLetter -UseMaximumSize | `
Format-Volume -FileSystem NTFS -NewFileSystemLabel "datadisk" -Confirm:$false