Introduction
Monitoring Azure applications is no longer the developer's sole
responsibility. Often times the devOp is actually the one who is in charge of the stability
and functionality of the cloud application.
The Windows Azure platform provides a great diagnostic mechanism
called Windows Azure Diagnostics (check this
article on more info).
As you may know an Azure application's main component is
the virtual machine that actually runs the code. Let's go over Windows Azure Roles types very quickly: We have the Web role which is the web site hosting the IIS server, and the Worker
role which execute tasks periodically.
Problem explained
As an operator of the application I would like to be notified
immediately when an error occurs. Responding quickly is very crucial. Once notified I can start debugging the application and identify the root cause.
The solution
I already know that Windows Azure Diagnostics can
collect Windows events from my role instances. All I need to do is to analyze the data at
a specific sampling
rate and send some sort of notification, preferably an email, to the person in
charge. Thus aiming for very fast problem resolution.
In the code below I will demonstrate how you can create a basic error notification mechanism.
Using the code
Let’s review the tasks we need to achieve:
- Collect
Windows event logs using Windows Azure Diagnostics (
Microsoft.WindowsAzure.Diagnostics.Management namespace) - Retrieve log errors from WADWindowsEventLogsTable
- Send email notification
Collect Windows event logs using Windows Azure Diagnostics
Remote configuring
Windows event logs
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics.Management;
const string storageAccoutName = "INSERT-AZURE-STORAGE-NAME";
const string privateKey = "INSERT-STORAGE-PRIVATE-KEY";
const string deploymentId = "INSERT-DEPLOYMENT-ID";
const string roleName = "INSERT-ROLE-NAME";
const string roleInstanceName = "INSERT-ROLE-INSTANCE";
var storageAccount = CloudStorageAccount.Parse(
String.Format(
"DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
storageAccoutName, privateKey));
var diagnosticManager = storageAccount.CreateDeploymentDiagnosticManager(deploymentId);
RoleInstanceDiagnosticManager roleDiagManager =
diagnosticManager.GetRoleInstanceDiagnosticManager(roleName, roleInstanceName);
var currentConfiguariton = roleDiagManager.GetCurrentConfiguration();
currentConfiguariton.WindowsEventLog.DataSources.Add("Application!*");
currentConfiguariton.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
currentConfiguariton.WindowsEventLog.ScheduledTransferLogLevelFilter = Microsoft.WindowsAzure.Diagnostics.LogLevel.Error;
roleDiagManager.SetCurrentConfiguration(currentConfiguariton);
The code above starts the persistence of Windows event logs to the
Azure storage. I used Cloud Storage Manager to verify that logs are written to
WADWindowsEventLogsTable.

Retrieve log errors from WADWindowsEventLogsTable
In the following code I'm constructing a LINQ query to WADWindowsEventLogsTable and fetching only the error logs. I can call this method periodically (using some sort of timer) to be acknowledged on new errors in my application.
public List<EventLogData> QueryEventLogData(LogLevel logLevel, string deploymentid, string roleName,
string roleInstanceName, DateTime startPeriod, DateTime endPeriod)
{
EventLogDataContext context =
new EventLogDataContext(accountStorage.TableEndpoint.ToString(),
accountStorage.Credentials);
var data = context.PerfData;
CloudTableQuery<EventLogData> query = null;
query = (from d in data
where d.PartitionKey.CompareTo("0" + startPeriod.Ticks) >= 0
&& d.PartitionKey.CompareTo("0" + endPeriod.Ticks) <= 0
&& d.Level == (int)logLevel
&& d.EventTickCount >= startPeriod.Ticks
&& d.EventTickCount <= endPeriod.Ticks
&& d.DeploymentId == deploymentid
&& d.Role == roleName
&& d.RoleInstance == roleInstanceName
select d).AsTableServiceQuery<EventLogData>();
List<EventLogData> selectedData = new List<EventLogData>();
try
{
selectedData = query.Execute().ToList<EventLogData>();
}
catch
{
}
return selectedData;
} Two important columns to focus on in WADWindowsEventLogsTable are the
ProviderName column which is the application source of the error and
the
Description column which is the error message.
Send email notification
In order to send mails, I used
the System.Net.Mail namespace. I configured it to send via SMTP from my
GMail account. But it can be easily configured to use other emailing services as well.
public static void sendEmail(string messageSubject, string messageBody, EmailClientConfiguration emailConfig)
{
try
{
MailMessage msg = new MailMessage()
{
Subject = messageSubject,
From = new MailAddress(emailConfig.From)
};
msg.To.Add(new MailAddress(emailConfig.To));
msg.Body = messageBody;
using (SmtpClient smpt = new SmtpClient()
{
Host = emailConfig.SMTPHost,
Port = 25,
EnableSsl = true,
Credentials = new NetworkCredential(emailConfig.UserName, emailConfig.Password)
})
{
smpt.Send(msg);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Just for testing I've created a small WinForms application (the UI code is omitted from the source code).
The following is the email message I received:
Summary
In this article I demonstrated how you can address critical monitoring tasks by focusing on specific diagnostics data. You can leverage this solution to other use cases which applies to your
Azure
application.
Shay Yannay is a Senior Software Developer and Windows Azure Domain Expert.
He is experienced with designing and developing highly scalable, distributed, 24x7 availability complex system. Shay also specializes in performance management & diagnostics of multi-tier applications.
He is passionate about the cloud technologies and trends, specifically with Microsoft Azure.
He currently works for Dell as an Azure Specialist.
Shay holds a B.Sc in Communication Systems Engineering from the Ben-Gurion university.
Personal Blog: http://shayyannay.wordpress.com