In this blog, I will demonstrate new diagnostics features of the new SDK (April 2012, v2.0) in a sample application. All the diagnostics instrumentation will be done on built-in features by modifying configuration settings. This is well aligned with “Configure before Customize” approach.
1: using System.Linq;
2: using System.Web.Mvc;
3: using ToDoCommon;
4: using ToDoData.Models;
5:
6: namespace ToDoListWeb2.Controllers
7: {
8: //[Authorize]
9: //[InitializeSimpleMembership]
10: public class TaskController : Controller
11: {
12: //
13: // GET: /Home/
14:
15: public ActionResult Index()
16: {
17: Util.TestTrace2();
18: using (var context = new ToDoContext())
19: return View(context.ToDoItems.ToList());
20: }
21:
22: //
23: // GET: /Home/Details/5
24:
25: public ActionResult Details(int id = 0)
26: {
27: using (var context = new ToDoContext())
28: return View(context.ToDoItems.Find(id));
29: }
30: }
31: }
1: @model IEnumerable<ToDoData.Models.ToDoItem>
2:
3: @{
4: ViewBag.Title = "Index";
5: Layout = "~/Views/Shared/_Layout.cshtml";
6: }
7:
8: <h2>Index</h2>
9:
10: <p>
11: @Html.ActionLink("Create New", "Create")
12: </p>
13: <table>
14: <tr>
15: <th>
16: @Html.DisplayNameFor(model => model.Name)
17: </th>
18: <th>
19: @Html.DisplayNameFor(model => model.Description)
20: </th>
21: <th>
22: @Html.DisplayNameFor(model => model.Rank)
23: </th>
24: <th>
25: @Html.DisplayNameFor(model => model.IsComplete)
26: </th>
27: <th></th>
28: </tr>
29:
30: @foreach (var item in Model) {
31: <tr>
32: <td>
33: @Html.DisplayFor(modelItem => item.Name)
34: </td>
35: <td>
36: @Html.DisplayFor(modelItem => item.Description)
37: </td>
38: <td>
39: @Html.DisplayFor(modelItem => item.Rank)
40: </td>
41: <td>
42: @Html.DisplayFor(modelItem => item.IsComplete)
43: </td>
44: <td>
45: @Html.ActionLink("Edit", "Edit", new { id=item.ItemId }) |
46: @Html.ActionLink("Details", "Details", new { id=item.ItemId }) |
47: @Html.ActionLink("Delete", "Delete", new { id=item.ItemId })
48: </td>
49: </tr>
50: }
51:
52: </table>
1: using System;
2: using System.Diagnostics;
3: using System.Text;
4: using Microsoft.WindowsAzure.ServiceRuntime;
6: namespace ToDoCommon
8: public class Util
9: {
10: public static void TestTrace2(string info = "")
12: Trace.TraceInformation("Dummy entry. Trace.TraceInformation from {0} {1}",
13: RoleEnvironment.CurrentRoleInstance.Role.Name, info);
14: Trace.TraceWarning("Dummay entry. Trace.TraceWarning from {0} {1}",
15: RoleEnvironment.CurrentRoleInstance.Role.Name, info);
16: try
17: {
18: throw new ArgumentException("Dummy exception", new ArgumentException("Inner dummy exception..."));
19: }
20: catch (Exception ex)
21: {
22: var sb =
23: new StringBuilder(string.Format("Dummy entry. Trace.TraceError from {0} {1}",
24: RoleEnvironment.CurrentRoleInstance.Role.Name, info));
25: sb.AppendLine();
26: var innerEx = ex.InnerException;
27: while (innerEx != null)
28: {
29: sb.AppendFormat("\t Inner Exc Message: {0}\r\n", innerEx.Message);
30: innerEx = innerEx.InnerException;
32:
33: sb.AppendLine("StackTrace: " + ex.StackTrace);
34: Trace.TraceError(sb.ToString());
35: }
36: }
37: }
38: }
Ok, time to run the cloud service. Then browse the Task page where some dummy traces are passed to listener as sampled just above this.
All the diagnostics logs are written to files in "C:\Users\[your_user_account]\AppData\Local\” path. Please note, you need change your folder settings, since the AppData is hidden. Here, DevelopmentStorage and dftmp folder are the locations where all the application related logs are written.
From the folder above, the logs matching selected log level (Error by default) are persisted into the storage table (WADLogsTable, etc). To see the entries, you can use different tools (storage explorer, etc.), I am going to use VS for this purpose as well. To do that, click on View on VS’ top menu, then Server Explorer (or Ctrl + W). On the Server Explorer panel, click on Windows Azure Storage then Development (local run), then Tables and "WADLogsTable" (storage table name).
As you can see, diagnostics are already enabled for both web and worker roles. If you look at the web.config in the web application, you will see that a trace listener called 'AzureDiagnostics' also added (web role and the associated web application runs on different processes).
You can see that from GUI as well by right click on a role then Properties:
Now, we know the reason why error-type logs are written only, because, by default, it is set to 'Errors only'. Diagnostics settings here are reflected in the diagnostics configuration file called 'diagnostics.wadcfg'.
Now, if you want to change the settings, please follow the steps picture below:
(1): Role diagnostics configuration window
For example, when I change log level to Information and enable both Event and Performance counters logs, I am able to see all the logs (except Verbose) for application, performance and events, as seen below:
And you can change the setting while your application running (alive!)
Please note that before going to deploy the solution, in regards to diagnostics feature context and the image (1) - "Role diagnostics configuration window" above:
I have deployed the solution here. As said, before and sampled in picture below, I am able to see the diagnostic data from VS and to change the configuration settings –alive- if needed.
Software applications in general should have diagnostics enabled. This is exclusively critical for those running in Azure, because they are most likely a composite of applications running in different platforms and networks/locations. Health of the system (the overall application) is dependent on health of each its subsystems and to identify the cause of bugs (and, no mistake they occurs) when alive, you need to instrument your solution with meaningful diagnostics features, at least when passing the message one domain to another.
I have written several blogs about diagnostics features: