Зачем нужны журналы приложения windows azure sdk microsoft servicehosting serviceruntime

Windows Azure SDK предоставляет разработчикам интерфейс программирования приложений, необходимый для разработки, развертывания и управления

Аннотация: Windows Azure SDK предоставляет разработчикам интерфейс
программирования приложений, необходимый для разработки, развертывания и управления масштабируемых сервисов в Windows Azure. В данной лекции мы
рассмотрим основные возможности Windows Azure SDK.

Цель данной лекции – ознакомиться с комплектом средств разработки Windows Azure SDK.

Windows Azure SDK предоставляет разработчикам интерфейс программирования приложений, необходимый для разработки, развертывания и управления масштабируемых сервисов в Windows Azure.

Azure Cloud Fabric и службы Azure Storage не поддерживают разработку или отладочные операции в облаке, поэтому Azure SDK позволяет делать это локально в виде приложений Development Fabric (DF) и Development Storage (DS), которые устанавливает Windows Azure SDK. Вместе с SDK также устанавливаются коллекция приложений примеров и библиотеки упакованных классов для облегчения программирования приложений.

Должны быть установлены .NET Framework 3.5 SP1 и SQL Express 2005 или 2008, также необходимо включить ASP.NET и WCF HTTP Activation для IIS 7.0 для Windows Server 2008, Windows Vista SP2, или Windows 7 RC или позже для установки и запуска SDK. Заметки к выпуску включают инструкции для настройки этих опций. Использование SDK не является обязательным, потому что есть возможность пользоваться любыми операционными системами и языками программирования, которые поддерживают HTTP запросы и ответы. Однако, вы увидите что использование SDK интерфейсов прикладного программирования .NET и библиотек для приложений и хранилищ позволяет наиболее просто работать с HTTP напрямую.

После того, как вы установили Azure SDK, Вы должны скачать и установить инструменты Windows Azure для Visual Studio для добавления шаблонов проектов Web Cloud Sevice, Worker Cloud Service, Web and Worker Cloud Service Workflow Service. Вы можете скачать текущую версию Windows Azure SDK и Windows Azure Tools для Visual Studio с главной страницы Windows Azure по ссылке www.microsoft.com/azure/windowsazure.mspx.

После установки Windows Azure Tools в Visual Studio появляются шаблоны Cloud Service в диалоге создания нового проекта. При выборе узла Cloud Service открываются New Cloud Service, который позволяет добавить ASP.NET Web Roles, Worker Roles или CGI Web Roles для нового проекта. Windows Azure SDK позволяет добавить более чем одну роль для каждого типа Cloud Service. Каждая роль использует отдельный экземпляр Windows Azure CPU, так минимальная стоимость запуска проекта в облаке будет примерно 4 * $0.12 = $0.48 в час.

Создание нового проекта Cloud Service в Visual Studio

Рис.
5.1.
Создание нового проекта Cloud Service в Visual Studio

Добавив указанные роли и нажав ОК, откроется новое решение с проектами WebRole и Worker-Role
в Solution Explorer как показано на
рис.
5.2.

Узел Roles содержит элементы WebRole, которые указывают на каждую WebRole, которая обеспечивает пользовательский интерфейс ASP.NET для приложения и каждый WorkerRole для вычислительный операций, которые не требуют пользовательского интерфейса или используют страниц ASP.NET WebRole вместо этого.

Solution Explorer Cloud Service

Рис.
5.2.
Solution Explorer Cloud Service

В зависимости от типа Cloud Service проекты включают пространство имен Microsoft.ServiceHosting.ServiceRuntime,
которое содержит классы, указанные в таблице ниже.

Класс Описание
RoleEntryPoint Обеспечивает методы для управления инициализацией, запуском и остановкой методов сервиса, так же используется для мониторинга состояния сервиса.
RoleException Сообщает об ошибках когда происходят недопустимые операции внутри роли
RoleManager Обеспечивает методы для журналирования сообщений и поступающих предупреждений, извлекает настройки конфигурации сервиса и возвращает местоположение ресурса
RoleStatus Информирует о текущем статусе роли: Healthy, NonExistent, Started, Starting, Stopped, Stopping или
Unhealthy

Проекты, которые используют шаблон WebRole определяют веб страницу ASP.NET Default.aspx как начальную точку для пользовательского интерфейса приложения в облаке.

Это сервис объединяет библиотеку класса Common из приложения-образца HelloFabric для содействия в журналировании проблем приложения. Журналы приложения – это практичные средства откладки приложений, запущенных в Cloud Fabric. Для чтения журналов, вы должны скопировать их в Blob массив использую инструментарий портала.

Образец проекта StorageClient включает библиотеку класса StorageClient, которая обеспечивает в объединении с библиотекой .NET Client для сервиса данных ADO.NET, интерфейсный класс Microsoft .NET для HTTP операций над Azure Blob, Queue и Table Storage сервисами. Этот проект также включает консольное приложение, которые позволяет Вам тестировать возможности библиотеки. Консольное приложение C# запускается в Development Fabric с Development Storage.

При установке Windows Azure SDK не устанавливаются образцы приложений, которые включены в Program FilesMicrosoft Windows Azure SDKv1.0samples.zip. Установите образцы, разархивировав samples.zip в директорию, где Вы имеете права на запись. В таблице ниже можно найти описание некоторых образцов приложений.

Для запуска примера CloudDrive необходим PowerShell.

Директория, в которую было извлечено содержимое архива samples.zip также содержит следующие три пакетных файла (cmd), которые можно запустить из командной строки:

  • buildall.cmd строит все образцы проектов без использования Visual Studio:
  • createtables.cmd вызывает buildall.cmd и создает базу данных и таблицы, необходимые для образцов, которые используют Table Storage.
  • rundevstore.cmd вызывает createtables.cmd и запускает разработку хранилища, размещая его в базе данных, созданной createtables.cmd.

В состав Development Fabric входят следующие исполняемые файлы: DFAgent.exe , DFLoadBalancer.exe, DFMonitor.exe и DFService.exe, которые по умолчанию устанавливаются программой установки Azure SDK в каталог Program FilesWindows Azure SDKv1.0bindevfabric. После запуска Development Fabric в диспетчере задач вы можете увидеть эти четыре процесса. Сделать это можно выполнив:

  • Выберите ПрограммыWindows Azure SDKDevelopment Fabric для запуска службы Development Fabric и его пользовательского интерфейса DFUI.exe
  • Правый щелчок мыши по значку Development Fabric в области уведомлений панели задач и выбрать запуск службы Development Fabric (
    рис.
    5.3)
  • Скомпилировать и запустить приложение Azure в Visual Studio.

 Сообщения, отображаемые нажатии правой кнопкой мыши по значку Development Fabric в области уведомлений панели задач

Рис.
5.3.
Сообщения, отображаемые нажатии правой кнопкой мыши по значку Development Fabric в области уведомлений панели задач

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.

Requirements:

  • Windows Azure SDK v2.0, Windows Azure .NET Developer Center. This includes azure emulators (compute and storage) as well.
  • Storage Explorer (Optional): Azure Storage Explorer tool from Neudesic, http://azurestorageexplorer.codeplex.com/.
  • Azure cloud service, please refer to this link http://www.windowsazure.com/en-us/manage/services/cloud-services/
  • Azure storage account, please refer to this link http://www.windowsazure.com/en-us/manage/services/storage/
  • And an IDE, I am using Visual Studio (VS) 2012.

The Solution

  • Started VS

  • File –> New Projects
  • Selected “Cloud” template
clip_image001

  • Added 2 projects from left selection targeting .NET 4.5 and Windows Azure SDK v2.0
clip_image002
  • Renamed the projects by clicking on top of the selected project names
clip_image003
  • Selected a template for web application

clip_image004
  • Added a task controller to the web app

   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: }
  • Added respective Views
 

   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>
  • Created a dummy test method in a utility class

   1: using System;
   2: using System.Diagnostics;
   3: using System.Text;
   4: using Microsoft.WindowsAzure.ServiceRuntime;
   5:  
   6: namespace ToDoCommon
   7: {
   8:     public class Util
   9:     {
  10:         public static void TestTrace2(string info = "")
  11:         {
  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}rn", innerEx.Message);
  30:                     innerEx = innerEx.InnerException;
  31:                 }
  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.

clip_image005

Where are the Logs?

All the diagnostics logs are written to files in «C:Users[your_user_account]AppDataLocal” 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).

clip_image006

How it works?

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).

clip_image007

You can see that from GUI as well by right click on a role then Properties:

clip_image008

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’.

How-to Change Settings

Now, if you want to change the settings, please follow the steps picture below:

clip_image009

(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:

clip_image010

clip_image011

And you can change the setting while your application running (alive!)

And Deployment

Please note that before going to deploy the solution, in regards to diagnostics feature context and the image (1) – «Role diagnostics configuration window» above:

  • You need to update storage account accordingly. You should use a separate diagnostic storage table for PROD environment
  • Set the log level for errors initially, when troubleshooting, you can set the level accordingly depending on implemented diagnostics features on your application (Information, Verbose, etc.).
  • Set the buffer size and transfer intervals (less buffer/interval means, less amount of data and more often data transfer from the local folder to storage table. Please refer this link fore more details: http://msdn.microsoft.com/en-us/library/windowsazure/dn186185.aspx.

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.

image 

Conclusion

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:

  • Part 4: this post – Configuration based diagnostics features of Windows Azure SDK 2.0
  • Part 3: Customized diagnostics features of Windows Azure SDK 2.0
  • Part 2: Diagnostics of Azure Web Sites – Custom Logging, Windows Azure SDK 1.8
  • Part 1: Diagnostics of Windows Azure Web Sites – Built-in Diagnostic Features (configuring diagnostics features directly from Azure Management dashboard)

Helpful links:

  • Announcing the release of Windows Azure SDK 2.0 for .NET
  • Enabling Diagnostics in Windows Azure
  • Walkthrough to Configure System Center Management Pack for Windows Azure Fabric Preview for SCOM 2012 SP1 (with a MetricsHub Bonus)

NOTE: Samples in this file apply only to packages that follow Azure SDK Design Guidelines. Names of such packages usually start with Azure. The samples make use of the SecretClientOptions type, but the same functionality is available for any of the Azure. packages that contain client options types that derive from ClientOptions, e.g. BlobClientOptions, TextAnalyticsClientOptions, etc.

Logging

The Azure SDK libraries produce various log messages that include information about:

  1. Requests and responses
  2. Authentication attempts
  3. Retries

The simplest way to see the logs is to enable the console logging using the AzureEventSourceListener.

// Setup a listener to monitor logged events.
using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

Azure Event Source Listener lifetime

In order for the AzureEventSourceListener to collect logs, it must be in scope and active while the client library is in use. If the listener is disposed or otherwise out of scope, logs cannot be collected. Generally, we recommend creating the listener as a top-level member of the class where the Event Hubs client being inspected is used.

Capture logs to trace

Logging can also be enabled for Trace in the same manner as console logging.

// Setup a listener to monitor logged events.
using AzureEventSourceListener listener = AzureEventSourceListener.CreateTraceLogger();

Changing log level

The CreateConsoleLogger and CreateTraceLogger methods have an optional parameter that specifies a minimum log level to display messages for.

using AzureEventSourceListener consoleListener = AzureEventSourceListener.CreateConsoleLogger(EventLevel.Warning);
using AzureEventSourceListener traceListener = AzureEventSourceListener.CreateTraceLogger(EventLevel.Informational);

Enabling content logging

By default only URI and headers are logged. To enable content logging, set the Diagnostics.IsLoggingContentEnabled client option:

SecretClientOptions options = new SecretClientOptions()
{
    Diagnostics =
    {
        IsLoggingContentEnabled = true
    }
};

Logging redacted headers and query parameters

Some sensitive headers and query parameters are not logged by default and are displayed as «REDACTED», to include them in logs use the Diagnostics.LoggedHeaderNames and Diagnostics.LoggedQueryParameters client options.

SecretClientOptions options = new SecretClientOptions()
{
    Diagnostics =
    {
        LoggedHeaderNames = { "x-ms-request-id" },
        LoggedQueryParameters = { "api-version" }
    }
};

You can also disable redaction completely by adding a "*" to collections mentioned above.

SecretClientOptions options = new SecretClientOptions()
{
    Diagnostics =
    {
        LoggedHeaderNames = { "*" },
        LoggedQueryParameters = { "*" }
    }
};

Custom logging callback

The AzureEventSourceListener class can also be used with a custom callback that allows log messages to be written to destination of your choice.

using AzureEventSourceListener listener = new AzureEventSourceListener(
    (args, message) => Console.WriteLine("[{0:HH:mm:ss:fff}][{1}] {2}", DateTimeOffset.Now, args.Level, message),
    level: EventLevel.Verbose);

When targeting .NET Standard 2.1, .NET Core 2.2, or newer, you might instead use args.TimeStamp to log the time the event was written instead of rendered, like above. It’s in UTC format, so if you want to log the local time like in the example call ToLocaleTime() first.
For help diagnosing multi-threading issues, you might also log args.OSThreadId which is also available on those same targets.

More information about the args parameter for the callback can be found in the EventWrittenEventArgs documentation.

Applying filtering logic

The custom callback can be used with the listener to help filter log messages to reduce volume and noise when troubleshooting.

In the following example, Verbose messages for the Azure-Identity event source are captured and written to Trace. Log messages for the Azure-Messaging-EventHubs event source are filtered to capture only a specific set to aid in debugging publishing, which are then written to the console.

using AzureEventSourceListener listener = new AzureEventSourceListener((args, message) =>
{
    if (args.EventSource.Name.StartsWith("Azure-Identity") && args.Level == EventLevel.Verbose)
    {
        Trace.WriteLine(message);
    }
    else if (args.EventSource.Name.StartsWith("Azure-Messaging-EventHubs"))
    {
        switch (args.EventId)
        {
            case 3:   // Event Publish Start
            case 4:   // Event Publish Complete
            case 5:   // Event Publish Error
                Console.WriteLine(message);
                break;
        }
    }
}, EventLevel.LogAlways);

Capture filtered logs to a file

For scenarios where capturing logs to Trace or console isn’t ideal, log information can be streamed into a variety of targets, such as Azure Storage, databases, and files for durable persistence.

The following example demonstrates capturing error logs to a text file so that they can be analyzed later, while capturing non-error information to console. Its important to note that a simple approach is used for illustration. This form may be helpful for troubleshooting, but a more robust and performant approach is recommended for long-term production use.

using Stream stream = new FileStream(
    "<< PATH TO FILE >>",
    FileMode.OpenOrCreate,
    FileAccess.Write,
    FileShare.Read);

using StreamWriter streamWriter = new StreamWriter(stream)
{
    AutoFlush = true
};

using AzureEventSourceListener listener = new AzureEventSourceListener((args, message) =>
{
    if (args.EventSource.Name.StartsWith("Azure-Identity"))
    {
        switch (args.Level)
        {
            case EventLevel.Error:
                streamWriter.Write(message);
                break;
            default:
                Console.WriteLine(message);
                break;
        }
    }
}, EventLevel.LogAlways);

Logging in ASP.NET Core applications

If your are using Azure SDK libraries in ASP.NET Core application consider using the Microsoft.Extensions.Azure package that provides integration with Microsoft.Extensions.Logging library. See Microsoft.Extensions.Azure readme for more details.

ActivitySource support

Azure SDKs released after October 2021 include experimental support for ActivitySource, which is a simplified way to create and listen to activities added in .NET 5.
Azure SDKs produce the following kinds of Activities:

  • HTTP calls: every HTTP call originating from Azure SDKs
  • client method calls: for example, BlobClient.DownloadTo or SecretClient.StartDeleteSecret.
  • messaging events: Event Hubs and Service Bus message creation is traced and correlated with its sending, receiving, and processing.

Because ActivitySource support is experimental, the shape of Activities may change in the future without notice. This includes:

  • the kinds of operations that are tracked
  • relationships between telemetry spans
  • attributes attached to telemetry spans

More detailed distributed tracing convention can be found at https://github.com/Azure/azure-sdk/blob/main/docs/tracing/distributed-tracing-conventions.yml .

ActivitySource support can be enabled through either of these three steps:

  • Set the AZURE_EXPERIMENTAL_ENABLE_ACTIVITY_SOURCE environment variable to true.
  • Set the Azure.Experimental.EnableActivitySource context switch to true in your application code:
AppContext.SetSwitch("Azure.Experimental.EnableActivitySource", true);
  • Add the RuntimeHostConfigurationOption setting to your .csproj.
 <ItemGroup>
    <RuntimeHostConfigurationOption Include="Azure.Experimental.EnableActivitySource" Value="true" />
  </ItemGroup> 

You’ll need System.Diagnostics.DiagnosticSource package with version 5.0 or later consume Azure SDK Activities.

 <ItemGroup>
    <PackageReference Include="System.Diagnostics.DiagnosticSource" Version="5.0.1" />
  </ItemGroup> 

The following sample shows how ActivityListener can be used to listen to Azure SDK Activities.

using ActivityListener listener = new ActivityListener()
{
    ShouldListenTo = a => a.Name.StartsWith("Azure"),
    Sample = (ref ActivityCreationOptions<ActivityContext> _) => ActivitySamplingResult.AllData,
    SampleUsingParentId = (ref ActivityCreationOptions<string> _) => ActivitySamplingResult.AllData,
    ActivityStarted = activity => Console.WriteLine("Start: " + activity.DisplayName),
    ActivityStopped = activity => Console.WriteLine("Stop: " + activity.DisplayName)
};
ActivitySource.AddActivityListener(listener);

var secretClient = new SecretClient(new Uri("https://example.com"), new DefaultAzureCredential());
secretClient.GetSecret("<secret-name>");

Distributed tracing

Azure SDKs are instrumented for distributed tracing using ApplicationsInsights or OpenTelemetry.

ApplicationInsights with Azure Monitor

Application Insights, a feature of Azure Monitor, is an extensible Application Performance Management (APM) service for developers and DevOps professionals. Use it to monitor your live applications. It will automatically detect performance anomalies, and includes powerful analytics tools to help you diagnose issues and to understand what users actually do with your app

If your application already uses ApplicationInsights, automatic collection of Azure SDK traces is supported since version 2.12.0 (Microsoft.ApplicationInsights on NuGet).

To setup ApplicationInsights tracking for your application follow the Start Monitoring Application guide.

OpenTelemetry with Azure Monitor, Zipkin and others

OpenTelemetry relies on ActivitySource to collect distributed traces. Follow steps in ActivitySource support section before proceeding to OpenTelemetry configuration.

Follow the OpenTelemetry configuration guide to configure collecting distribute tracing event collection using the OpenTelemetry library.

Sample

To see an example of distributed tracing in action, take a look at our sample app that combines several Azure SDKs.

Setting x-ms-client-request-id value sent with requests

By default x-ms-client-request-id header gets a unique value per client method call. If you would like to use a specific value for a set of requests use the HttpPipeline.CreateClientRequestIdScope method.

var secretClient = new SecretClient(new Uri("http://example.com"), new DefaultAzureCredential());

using (HttpPipeline.CreateClientRequestIdScope("<custom-client-request-id>"))
{
    // The HTTP request resulting from the client call would have x-ms-client-request-id value set to <custom-client-request-id>
    secretClient.GetSecret("<secret-name>");
}

If you’re running your Windows Azure application on your local machine using the Visual Studio Development Fabric, it’s easy to figure out problems by simply putting a breakpoint in your code and using the debugger.  If your app is running in the cloud, using the debugger is impossible. 

This is where Azure’s logging features come in handy. 

The most straightforward way to get logging into your app is by using the RoleManager object in the Microsoft.ServiceHosting.ServiceRuntime namespace.  RoleManager has a static method called WriteToLog that takes a name of the eventLog and the message.

RoleManager.WriteToLog(string eventLogName, string message)

The supported values for eventLogName are Critical, Error, Warning, Information, and Verbose.

Here’s a simple sample of writing to the log from the code behind of an ASP.NET page running in an Azure Web Role.

protected void m_lbtnWriteMessageToLog_Click(
    object sender, EventArgs e)
{
    RoleManager.WriteToLog(
        “Information”,
        String.Format(“The time is now: {0}”, DateTime.Now));
}

If you want to see the logging in action while you’re running in the Development Fabric, locate the Development Fabric icon in your system tray, right-click the icon and choose Show Development Fabric UI.

image

You should now see the Development Fabric window and you can then drill in to locate the role that’s doing the logging.  In this case, I only have a WebRole and, as you can see in the diagram, it’s running two instances.

image

From here you can drill in to the role instances and see the log window and the log messages. 

image

Now, let’s say that you’ve deployed your app to Staging or Production and it’s running in the cloud.  You don’t have this nice log window anymore so how do you access your Windows Azure logs? 

First, you’ll log in to the Azure Services Developer Portal for your application.  If you’ve deployed your application, you should see the Production and/or Staging environment displayed along with buttons to Suspend, Configure, and Delete your app. 

To access your logs, begin by clicking the Configure button.

image

This will bring you in to the Service Tuning page and at the top, you’ll see a section that says Event Logs.  The Event Logs section of this page will allow you to copy your logs from your application out to a Blob store in your Azure Services Storage Account.  You choose the Storage Account you want to use and give it a Container Name (or leave the default auto-generated value), and then click Copy Logs.

image

The Container Name is the name of the Blob container that will hold your log files.  After a few minutes, the log files will be finished copying to your storage account.

Ok.  Now what?  How do you actually read the logs, right?

To get the logs, you can use the CloudDrive application that comes with the Windows Azure Services SDK.  CloudDrive is a PowerShell plugin that allows you to access your blob and queue storage account from the command line.  By default, the application source code is stored at C:Program FilesMicrosoft Service Hosting SDKv1.0samplesCloudDrive

Run the buildme.cmd file to compile the CloudDrive app.  Then you need to add your credentials to the MountDrive.ps1 file in the Scripts directory (C:Program FilesMicrosoft Service Hosting SDKv1.0samplesCloudDrivescripts). 

image

You need to update the values that are circled in the image above.  You can get these values by logging into your Azure Services Developer Portal and selecting your Storage account.  You should see a section on the page called Cloud Storage that looks similar to the image below.

image

Open MountDrive.ps1 in a text editor.

At the top of MountDrive.ps1, you need to set the values for $Account and $Key.  The $Key value is your Primary Access Key from the Cloud Storage portal.  Your account name is the first section of the Endpoint url.  The endpoint for my blob store is http://benday.blob.core.windows.net so my account name is benday

At the bottom of MountDrive.ps1, you need to set the endpoint values for the Blob store and the Queue store.  As shown above, the endpoints for my account are http://benday.blob.core.windows.net and http://queue.blob.core.windows.net.

Save MountDrive.ps1 and exit the text editor.

You’ve now finished configuring CloudDrive.  You can run it by running runme.cmd in C:Program FilesMicrosoft Service Hosting SDKv1.0samplesCloudDrive. 

This will load up PowerShell and show you the configured Azure Storage repositories.  (see below)

image

Now let’s retrieve the log files.

Type cd Blob: in to the PowerShell window and hit Enter.  (HINT: don’t forget the colon (‘:’) after the word Blob and remember that Blob is case-sensitive!)

If you type dir, you’ll see a list of the Blobs in your store.

image

You should see the name of the blob container that you specified in the portal when you clicked the Copy Logs button.  Type in “cd name_of_your_blob” and hit enter to get into the container.  Continue doing dir and cd commands until you can see a file that starts with Events_UTC.

image

Now you need to copy this file to your local machine. 

Type copy-cd Events_UTC_filename c: and press Enter.  This will copy the log file to the root of your C: drive.

Now you can open the file using notepad and see the contents.

image 

So…what have we accomplished?  First, you added some logging calls to your Azure application.  Then you viewed the logs while running your app in the Development Fabric.  Then you accessed the logs for a hosted service using CloudDrive.

Now you’re all set to debug your deployed Azure application.

-Ben

— Looking for help making decisions about or adopting Windows Azure?  Need Windows Azure training or mentoring?  Contact me via http://www.benday.com.

Лекция 5. Windows Azure SDK.

Краткая аннотация лекции:

Windows Azure SDK предоставляет разработчикам интерфейс программирования приложений, необходимый для разработки, развертывания и управления масштабируемых сервисов в Windows Azure. В данной лекции мы рассмотрим основные возможности Windows Azure SDK.

Цель лекции:

Цель данной лекции – ознакомиться с комплектом средств разработки Windows Azure SDK.

Текст лекции:

Windows Azure SDK предоставляет разработчикам интерфейс программирования приложений, необходимый для разработки, развертывания и управления масштабируемых сервисов в Windows Azure.

Azure Cloud Fabric и службы Azure Storage не поддерживают разработку или отладочные операции в облаке, поэтому Azure SDK позволяет делать это локально в виде приложений Development Fabric (DF) и Development Storage (DS), которые устанавливает Windows Azure SDK. Вместе с SDK также устанавливаются коллекция приложений примеров и библиотеки упакованных классов для облегчения программирования приложений.

Должны быть установлены .NET Framework 3.5 SP1 и SQL Express 2005 or 2008, также необходимо включить ASP.NET и WCF HTTP Activation для IIS 7.0 для Windows Server 2008, Windows Vista SP2,or Windows 7 RC или позже для установки и запуска SDK. Заметки к выпуску включают инструкции для настройки этих опций. Использование SDK не является обязательным, потому что есть возможность пользоваться любыми операционными системами и языками программирования, которые поддерживают HTTP запросы и ответы. Однако, вы увидите что использование SDK интерфейсов прикладного программирования .NET и библиотек для приложений и хранилищ позволяет наиболее просто работать с HTTP напрямую.

Рекомендуемые материалы

После того, как вы установили Azure SDK, Вы должны скачать и установить инструменты Windows Azure для Visual Studio для добавления шаблонов проектов Web Cloud Sevice, Worker Cloud Service, Web and Worker Cloud Service Workflow Service. Вы можете скачать текущую версию Windows Azure SDK и Windows Azure Tools для Visual Studio с главной страницы Windows Azure по ссылке www.microsoft.com/azure/windowsazure.mspx.

После установки Windows Azure Tools в Visual Studio появляются шаблоны Cloud Service в диалоге создания нового проекта. При выборе узла Cloud Service открываются New Cloud Service, который позволяет добавить ASP.NET Web Roles, Worker Roles or CGI Web Roles для нового проекта. Windows Azure SDK позволяет добавить более чем одну роль для каждого типа Cloud Service. Каждая роль использует отдельный экземпляр Windows Azure CPU, так минимальная стоимость запуска проекта в облаке будет примерно 4 * $0.12 = $0.48 в час.

Рисунок 5.1 Создание нового проекта Cloud Service в Visual Studio

Добавив указанные роли и нажав ОК, откроется новое решение с проектами WebRole и WorkerRole в Solution Explorer как показано на рисунке 6.2.

Узел Roles содержит элементы WebRole, которые указывают на каждую WebRole, которая обеспечивает пользовательский интерфейс ASP.NET для приложения и каждый WorkerRole для вычислительный операций, которые не требуют пользовательского интерфейса или используют страниц ASP.NET WebRole вместо этого.

Рисунок 5.2 Solution Explorer Cloud Service

В зависимости от типа Cloud Service проекты включают пространство имен Microsoft.ServiceHosting.ServiceRuntime, которое содержит классы, указанные в таблице ниже.

Класс

Описание

RoleEntryPoint

Обеспечивает методы для управления инициализацией, запуском и остановкой методов сервиса, так же используется для мониторинга состояния сервиса.

RoleException

Сообщает об ошибках когда происходят недопустимые операции внутри роли

RoleManager

Обеспечивает методы для журналирования сообщений и поступающих предупреждений, извлекает настройки конфигурации сервиса и возвращает местоположение ресурса

RoleStatus

Информирует о текущем статусе роли: Healthy, NonExistent, Started, Starting, Stopped, Stopping или

Unhealthy

Проекты, которые используют шаблон WebRole определяют веб страницу ASP.NET Default.aspx  как начальную точку для пользовательского интерфейса приложения в облаке.

Это сервис объединяет библиотеку класса Common из приложения-образца HelloFabric для содействия в журналировании проблем приложения. Журналы приложения – это практичные средства откладки приложений, запущенных в Cloud Fabric. Для чтения журналов, вы должны скопировать их в Blob массив использую инструментарий портала.

Образец проекта StorageClient  включает библиотеку класса StorageClient, которая обеспечивает в объединении с библиотекой .NET Client для сервиса данных ADO.NET, интерфейсный класс Microsoft .NET для HTTP операций над Azure Blob, Queue и Table Storage сервисами. Этот проект также включает консольное приложение, которые позволяет Вам тестировать возможности библиотеки. Консольное приложение C# запускается в Development Fabric с Development Storage.

При установке Windows Azure SDK не устанавливаются образцы приложений, которые включены в Program FilesMicrosoft Windows Azure SDKv1.0samples.zip. Установите образцы, разархивировав samples.zip в директорию, где Вы имеете права на запись. В таблице ниже можно найти описание некоторых образцов приложений.

Для запуска примера CloudDrive необходим PowerShell.

Директория, в которую было извлечено содержимое архива samples.zip также содержит следующие три пакетных файла (cmd), которые можно запустить из командной строки:

· buildall.cmd строит все образцы проектов без использования Visual Studio:

· createtables.cmd вызывает buildall.cmd и создает базу данных и таблицы, необходимые для образцов, которые используют Table Storage.

· rundevstore.cmd вызывает createtables.cmd и запускает разработку хранилища, размещая его в базе данных, созданной createtables.cmd.

В состав Development Fabric входят следующие исполняемые файлы: DFAgent.exe, DFLoadBalancer.exe, DFMonitor.exe и DFService.exe, которые по умолчанию устанавливаются программой установки Azure SDK в каталог Program FilesWindows Azure SDKv1.0bindevfabric. После запуска Development Fabric в диспетчере задач вы можете увидеть эти четыре процесса. Сделать это можно выполнив:

· Выберите ПрограммыWindows Azure SDKDevelopment Fabric для запуска службы Development Fabric и его пользовательского интерфейса DFUI.exe

· Правый щелчок мыши по значку Development Fabric в области уведомлений панели задач и выбрать запуск службы Development Fabric (Изображение 6-4)

· Скомпилировать и запустить приложение Azure в Visual Studio.

Рисунок 5.3. Сообщения, отображаемые нажатии правой кнопкой мыши по значку Development Fabric в области уведомлений панели задач.

Рисунок 5.4 показывает пользовательский интерфейс DFUI. Когда вы запускаете или останавливаете отладку, соответствующие приложения появляются или пропадают из пользовательский интерфейс DFUI.

Рисунок 5.4. Пользовательский интерфейс приложения Development Fabric.

Платформа Windows Azure поддерживает три типа масштабируемых хранилищ:

· Неструктурированные данные (blob)

· Структурированные данные (таблицы)

· Сообщение между приложениями и сервисами (очереди)

Запуская rundevstore.exe или собирая и запуская пользовательский код Azure в Visual Studio, запускаются все три сервиса, даже если Ваш проект требует только один сервис и отображается в пользовательском интерфейсе Development Storage

Для защиты от потери данных, облако Azure хранит блобы, таблицы и очереди в минимум трех раздельных контейнерах в одном центре обработки данных. Инструмент геолокации Azure позволяет дублировать данные в нескольких центрах обработки данных Microsoft для уменьшения последствий восстановления после катастроф и для повышения производительности в специфичных географических регионах.

Приложение Azure, которые Вы запускаете в Development Framework, могут иметь доступ к локальным данным в Development Storage или к данным, загруженным в облако Azure. Приложение обращается к определенному порту и данным, расположенным в определенных местах в файле конфигурации проекта ServiceConfiguration.cscfg.

Файл конфигурации проекта Azure ServiceDefinition.csdef определяет стандартные точки входа и настройки конфигурации, которые хранятся в файле ServiceConfiguration.cscfg. В распечатке 6.1 показано содержимое файла ServiceDefinition.csdef по умолчанию, когда Вы создаете проект Azure, используя один из стандартных шаблонов Windows Azure Tools для Visual Studio (отмечены важные значения).

Распечатка 6.1 Содержимое файла ServiceDefinition.csdef

<ServiceDefinition name=»SampleWebCloudService»

xmlns=»http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition»>

<WebRole name=»WebRole»>

<InputEndpoints>

<!— Must use port 80 for http and port 443 for https

when running in the cloud —>

<InputEndpoint name=»HttpIn» protocol=»http» port=»80″ />

</InputEndpoints>

<ConfigurationSettings>

<Setting name=»AccountName»/>

<Setting name=»AccountSharedKey»/>

<Setting name=»BlobStorageEndpoint»/>

<Setting name=»QueueStorageEndpoint»/>

<Setting name=»TableStorageEndpoint»/>

</ConfigurationSettings>

</WebRole>

</ServiceDefinition>

Значение InputEndpoint применяется только для хранилищ в облаке.

Распечатка 6.2 показывает содержимое файла ServiceConfiguration.cscfg для веб приложения SampleWebCloudService с конфигураций по умолчанию для Development Storage (выделено):

Распечатка 6.2 Содержимое файла ServiceConfiguration.cscfg

<?xml version=»1.0″?>

<ServiceConfiguration serviceName=»SampleWebCloudService»

xmlns=»http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration»>

<Role name=»WebRole»>

<Instances count=»1″/>

<ConfigurationSettings>

<Setting name=»AccountName» value=»devstoreaccount1″/>

<Setting name=»AccountSharedKey» value=»Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ

1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==»/>

<Setting name=»BlobStorageEndpoint» value=»http://127.0.0.1:10000/»/>

<Setting name=»QueueStorageEndpoint» value=»http://127.0.0.1:10001/»/>

<Setting name=»TableStorageEndpoint» value=»http://127.0.0.1:10002/»/>

<!—<Setting name=»AccountName» value=»oakleaf»/>

<Setting name=»AccountSharedKey» value=»3elV1ndd . . . Coc0AMQA==» />

<Setting name=»BlobStorageEndpoint»

value=»http://blob.core.windows.net» />

<Setting name=»QueueStorageEndpoint»

value=»http://queue.core.windows.net» />

<Setting name=»TableStorageEndpoint»

value=»http://table.core.windows.net» />

—>

</ConfigurationSettings>

</Role>

</ServiceConfiguration>

Описания элементов файла конфигурации ServiceConfiguration.csfg:

· Instances count – количество экземпляров вашего приложения, которое будет создано в облаке, когда вы развернете его.

· AccountName– имя, ассоциированное с Вашим Hosted Service, с которым в создавали учетную запись, для Development Storage это devstoreaccount1.

· AccountSharedKey шифрует несколько элементов в HTTP запросе.

· BlobStorageEndpoint– это публичный постоянный Universal Resource Identifier (URI). Для Developer Storage это адрес интерфейса компьютера loopback (localhost = 127.0.0.1) с TCP портом по умолчанию 10000.

· QueueStorageEndpoint для хранилища в облаке это публичный постоянный URI. Для Developer Storage это интерфейса компьютера loopback с TCP портом по умолчанию 10001.

· TableStorageEndpoint публичный постоянный Universal Resource Identifier (URI). Для Developer Storage это адрес интерфейса компьютера loopback с TCP портом по умолчанию 10002.

Значения конечных точек в пользовательском интерфейсе Development Storage представлены на рисунке 6-6. Вы можете настроить собственные номера TCP портов если при использовании значений по умолчанию возникает конфликт с текущей конфигурацией.

Краткие итоги:

Обратите внимание на лекцию «1.3 Аналитическое построение математической модели».

В данной лекции мы полечили первоначальные сведения о работе с Windows Azure SDK. Рассмотрели процедуру создание Cloud Service, пользовательский интерфейс Development Fabric

Ключевые термины:

Литература:

1. http://www.microsoft.com/windowsazure/

2. http://www.microsoft.com/faculty

Предположим, производитель хочет сделать информацию о продукте доступной для своей дилерской сети и непосредственно для заказчиков. Размещение данных в SQL Azure Database позволит сделать их доступными для приложений, выполняемых на стороне дилеров, и для ориентированных на заказчиков веб-приложений, которые выполняются на стороне производителя.

Компания с клиентской базой данных, реплицированной в географически удаленных местах, должна использовать компонент Huron для синхронизации этих реплик. Возможно, в каждой из географических точек требуется собственная копия данных для повышения производительности, обеспечения доступности или по каким-то иным причинам. Автоматическая синхронизация может сделать такое обязательное распределение менее проблематичным.

Идет ли речь о приложении Windows Azure, обеспечении большей доступности данных, синхронизации этих данных или о чем-то еще, службы данных в Интернете могут оказаться очень полезными. По мере появления новых технологий в рамках SQL Azure организации будут получать возможность использования Интернета для выполнения все большего количества задач, ориентированных на работу с данными.

Выполнение приложений и хранение данных в Интернете относятся к важным аспектам вычислительной сетевой среды. Однако они далеко не исчерпывают ее возможности. Другая возможность заключается в обеспечении инфраструктуры служб на базе «облака», которые могут использоваться локальными приложениями или вебприложениями. Заполнить этот пробел и призваны службы .NET Services.

Первоначально известные как BizTalk Services, службы .NET Services предлагают функции для решения общих проблем инфраструктуры при создании распределенных приложений. На рисунке 4.5 показаны их основные компоненты.

Рисунок 4.5 Службы .NET Services обеспечивают инфраструктуру в «облаке», которая может быть использована для веб-приложений и локальных приложений.

Службы .NET Services состоят из следующих компонентов.

Управление доступом. Получающий все большее распространение подход к удостоверениям заключается в том, что каждый пользователь должен предоставить приложению маркер, содержащий некоторый набор утверждений. На основании этих утверждений приложение решает, что раз-

61

решено делать пользователю. Эффективное осуществление этой процедуры в масштабах компании требует федерации удостоверений, которая позволяет принимать утверждения, сделанные в одной области удостоверений, в другой области. Может также потребоваться преобразование утверждений, изменяющее их при передаче из одной области удостоверений в другую. Служба управления доступом обеспечивает реализацию обеих функций на основе «облака».

Шина служб. Предоставление служб приложений в Интернете гораздо труднее, чем может показаться. Задача шины служб — упростить эту процедуру, позволяя приложениям предоставлять конечные точки вебслужб, доступ к которым может быть получен другими приложениями — локальными или работающими в «облаке». Каждой предоставленной конечной точке присваивается URI, который клиенты могут использовать для поиска службы и получения доступа к ней. Шина служб также решает проблему преобразования сетевых адресов и прохождения через межсетевые

экраны без открытия новых портов для предоставленных приложений. Приведем несколько примеров использования службы .NET Services.

Независимый поставщик ПО, который поставляет приложение, необходимое заказчикам из разных организаций, может использовать службу управления доступом для упрощения разработки и эксплуатации приложения. Например, этот компонент .NET Services может преобразовывать различные утверждения, применяемые в разных организациях с различными технологиями идентификации в согласованный набор, подходящий для приложения независимого поставщика ПО. Такое преобразование позволяет также разгрузить механизм федерации удостоверений за счет службы управления доступом, освобождая независимых поставщиков ПО от необходимости выполнения собственной локальной программы федерации.

Предположим, предприятие хочет открыть доступ к одному из своих приложений торговым партнерам. Оно может распределить функции приложения с помощью веб-служб SOAP или RESTful и зарегистрировать их конечные точки с помощью шины служб. Затем торговые партнеры могут использовать шину для поиска конечных точек и доступа к службам. Это позволяет снизить риски, связанные с предоставлением приложения, поскольку не требует открытия новых портов в межсетевом экране компании. Организация может также использовать службу управления доступом, предназначенную для работы с шиной служб, для рационализации сведений о проверке подлинности, отправленной приложению ее партнерами.

Так же как в случае Windows Azure, предоставляется портал, доступный с помощью браузера, чтобы дать заказчикам возможность использовать службы .NET Services с помощью Windows Live ID. Цель корпорации Microsoft, достигаемая с помощью

.NET Services, совершенно очевидна: обеспечить полезную «облачную» инфраструктуру для распределенных приложений.

Программное обеспечение как Сервис (SaaS)

Программное обеспечение как сервис (Software as a service, SaaS) или программное обеспечение по требованию (Software on Demand, SoD) — бизнес-модель продажи программного обеспечения, при которой поставщик разрабатывает вебприложение и самостоятельно управляет им, предоставляя заказчикам доступ к

62

программному обеспечению через Интернет. Основное преимущество модели SaaS для потребителя состоит в отсутствии затрат, связанных с установкой, обновлением и поддержкой работоспособности оборудования и работающего на нём программного обеспечения. Программное обеспечение как сервис является моделью распространения программного обеспечения, в которой приложения размещены у вендора SaaS или поставщика услуг и доступны для клиентов по сети, как правило, Интернет. Модель SaaS доставки приложений становится все более и более распространенной технологией, которая поддерживает веб-службы и сервис-ориентированную архитектуру (SOA). SaaS также часто ассоциирована с моделью лицензирования, когда оплата происходит по мере получения услуг. Тем временем, услуги широкополосных сетей стали все более и более доступными, для поддержки доступа пользователей из большего количества мест по всему миру.

Огромные успехи, достигнутые поставщиками услуг интернет (ISP), чтобы увеличить полосу пропускания и сохранить возможность использования более мощных микропроцессоров вместе с недорогими устройствами хранения данных. Это обеспечивает огромную платформу для того, чтобы проектировать, разворачивать и использовать программное обеспечение через все области бизнес- и частных вычислений. Приложения SaaS также должны быть в состоянии взаимодейстововать с другими данными и другими приложениями среди большого разнообразия окружающих сред и платформ. Компания IDC описывает две немного отличающихся модели поставки SaaS.

SaaS чаще всего предназначен для обеспечения бизнес функциональности программного обеспечения для корпоративных клиентов по низкой цене, что позволяет избавиться от установки, управления, поддержки, лицензирования и высоких затрат в компании. Большинству клиентов неинтересно знать, как или почему программное обеспечение реализовано, развернуто и т.д., но все они, в тоже время, имеют потребность в использовании программное обеспечение в их работе. Многие типы программного обеспечения хорошо удовлетворяют модели SaaS (например, бухгалтерский учет, работа с клиентами, электронная почта, учет трудовых ресурсов, ИТ безопасность, управление ИТ, видеоконференцсвязь, веб-аналитика, управление веб-контентом). Различие между SaaS и более ранними способами доставки приложений через Интернет в том, что решения SaaS были разработаны специально, чтобы работать с веб браузерами. Архитектура приложений на основе SaaS специально предназначена для поддержки обработки запросов от большого количества пользователей. В этом и заключается большая разница между традиционным клиент-серверным приложением решением, расположенным у поставщиков услуг. С другой стороны, поставщики услуг SaaS увеличивают экономию масштабирования при развертывании, управлении, поддержке и обслуживании их предложений.

Много типов компонентов программного обеспечения и Фреймворков могут быть использованы при разработке приложений SaaS. Используя новые технологии в этих современных компонентах и средах разработки приложений, можно значительно уменьшить время разработки и стоимости преобразования традиционного продукта в решение SaaS. Согласно Microsoft, SaaS архитектура может быть классифицирована в один из четырех уровней, с ключевыми признаками: простота конфигурации, эффективность при многопользовательском доступе и масштабируемость. Каждый уровень отличается от предыдущего добавлением одного из этих признаков. Рассмотрим уровни, описанные Microsoft:

Архитектурный Уровень 1 — Специальный/Настраиваемый.

Первый уровень является фактически самым низким. Каждый клиент имеет уникальную, настроенную версию размещаемого приложения. Приложение запускает свои собственные экземпляры на серверах. Миграция традиционных несетевых или клиент-серверных приложений на этот уровень SaaS, как правило, требует незначительных усилий при разработке и уменьшает эксплуатационные

63

расходы, благодаря объединению серверного аппаратного обеспечения и администрирования.

Архитектурный Уровень 2 Конфигурируемость.

Второе уровень SaaS обеспечивает большую гибкость программы благодаря метаданным конфигурации. На данном уровне клиенты могут использовать много отдельных экземпляров одного приложения. Это позволяет вендорам удовлетворять переменные потребностям каждого клиента при использовании детализированной конфигурации. Также облегчается обслуживание, появляется возможность обновить общую кодовую базу.

Архитектурный Уровень 3 — Эффективность Мультиарендатора.

Третий уровень отличается от второго наличием поддержки многопользовательского доступа. Единственный экземпляр программы способен обслужить всех пользователей. Данный подход позволяет более эффективно использовать ресурсы сервера незаметно для конечного пользователя, но, в конечном счете, этот уровень не позволяет выполнять масштабирование системы.

Архитектурный Уровень 4— Масштабируемость.

Вчетвертом Уровень SaaS, масштабируемость добавлена благодаря использованию многоуровневой архитектуры. Эта архитектура способна поддерживать распределение нагрузки фермы идентичных экземпляров приложений, запущенных на переменном количестве серверов, которое достигает сотен и даже тысяч. Мощность системы может быть динамически увеличена или уменьшена в соответствии с требованиями. Это осуществляется путем добавления или удаления серверов без необходимости для дальнейшего изменения прикладной архитектуры программного обеспечения.

Развертывание приложений в сервис-ориентированной архитектуре является более сложной проблемой, чем развертывание программного обеспечения в традиционных моделях. В результате стоимость использования приложения SaaS основывается на числе пользователей, которые осуществляют доступ к сервису. Довольно часто возникают дополнительные расходы, связанные с использованием услуг сервисной службы, дополнительной полосы пропускания, и дополнительного дискового пространства. Доходы поставщиков услуг SaaS обычно первоначально ниже, чем традиционный расходы за лицензии на программное обеспечение. Однако компромисс для более низких затрат лицензии ежемесячно возвращающий доход, который рассматривается финансовым директором компании, как более предсказуемый критерий существования бизнеса. К ключевым особенностям программного обеспечения SaaS относятся:

Управление по сети и сетевой доступ к коммерческому программному обеспечению в централизованных центрах обработки данных, а не на сайтах клиентов, предоставление возможности клиентам получить доступ к приложениям удаленно через Интернет.

Доставка приложений по модели «один ко многим», в противоположность традиционной модели «один к одному».

Централизованная модернизация и обновления, что позволяет избежать необходимости в загрузке и установке приложений пользователем. SaaS часто используется в крупных сетях коммуникаций и программного обеспечения для совместной работы, иногда как программное расширение к архитектуре PaaS.

Циклы разработки программ в компаниях могут занимать достаточно долгое время, потребляя большие ресурсы и приводя к неудовлетворительным результатам. Хотя решение уступить контроль является трудным, это может привести к улучшению эффективности, снижению рисков и сокращению расходов. Постоянно увеличивается число компаний, которые хотят использовать модель SaaS для корпоративных приложений, таких как работа с клиентами, финансовые расходы, управление персоналом.

64

Модель SaaS гарантирует предприятиям, что все пользователи системы используют правильную версию приложения и поэтому формат зарегистрированных и переданных данных корректен, совместим и точен. Возлагая ответственность за приложения на поставщика SaaS, предприятия могут уменьшить затраты на администрирование и управление, которые необходимы для поддержки собственного корпоративного приложения. SaaS увеличивает доступность приложений в сети Интернет. SaaS гарантирует, что все транзакции приложения зарегистрированы. Преимущества SaaS для клиентов достаточно понятны:

Рациональное управление;

Автоматизированное обновление и исправление;

Целостность данных в рамках предприятия;

Совместная работа сотрудников предприятия;

Глобальная доступность.

Серверная виртуализация может использоваться в архитектуре SaaS вместо или в дополнение к поддержке многопользовательского режима. Главное преимущество платформы виртуализации – увеличение производительности системы без необходимости в дополнительном программировании. Эффект объединения совместного использования ресурсов и платформы виртуализации в решение SaaS обеспечивает большую гибкость и производительность для конечного пользователя.

Коммуникация как Сервис (CaaS)

Коммуникация как Сервис (CaaS) — построенное в облаке коммуникационное решение для предприятия. Поставщики этого тип облачного решения отвечает за управление аппаратным и программным обеспечением, требуемым для того, чтобы предоставить:

систему связи, обеспечивающая передачу речевого сигнала по сети Интернет или по любым другим IP-сетям (VoIP),

обмен мгновенными сообщениями (IM),

видеоконференц-связь.

Эта модель начала свой эволюционный процесс в индустрии телекоммуникаций, не сильно отличаясь от модели SaaS, стала результатом сектора служб доставки программного обеспечения. Вендоры CaaS ответственные за управление аппаратным и программным обеспечением их пользователей. Вендоры CaaS, как правило, предоставляют гарантируемое качество обслуживания (QoS) в соответствии с соглашением сервисного обслуживания (SLA).

Модель CaaS позволяет деловым клиентам выборочно разворачивать средства коммуникаций и услуг на оснований оплаты услуг в срок для используемых сервисов. CaaS разработан на ценовой политике общего назначения, которая предоставляет пользователям всесторонний, гибкий и легкий в понимании сервисный план. Согласно Gartner, рынок CaaS, как ожидается, будет насчитывать $2,3 миллиарда в 2011 году, с ежегодным темпом роста более 105 %.

Сервисные предложения CaaS часто связаны и включают интегрированный доступ к традиционному голосу (или VoIP) и данным, дополнительная функциональность объединенных коммуникаций, такие как видео вызовы, совместная работа, беседы, присутствие в реальном времени и передача сообщений, телефонная сеть, местная и распределенная голосовые услуги, голосовая почта. CaaS решение включает избыточное переключение, сеть, избыточность оборудования, WAN failover – что определенно подходит к потребностям клиентов. Все транспортные компоненты VoIP расположены в географически распределенных, безопасных информационных центрах для высокой доступности и жизнеспособность. CaaS предполагает гибкость и масштабируемость для

65

мелкого и среднего бизнеса, чего зачастую сами компании не могут обеспечить. Поставщики услуг CaaS подготовлены к пиковым нагрузкам, оказывают услуги по расширению емкости устройств, состояний или области покрытия по требованию заказчика. Пропускная способность сети и наборы средств могут быть изменены динамически, таким образом, функциональность идет в ногу с потребительским спросом и ресурсы, находящиеся в собственности поставщика не используются впустую. В отличие от поставщика услуг, перспектива клиента фактически не приводит к риску обслуживания устаревшего оборудования, так как обязательста поставщика услуг CaaS заключается в том, чтобы периодически модернизировать или заменять аппаратное и программное обеспечение, чтобы подерживать платформу в технологически актуальном состоянии.

CaaS не требует контроля от клиентов. Это избавляет от необходимости клиентов совершать какие-либо капиталовложения в инфраструктуру, и это устраняет накладные расходы для инфраструктуры. С решением CaaS клиенты в состоянии усиливать коммуникационные услуги класса предприятия, не имея необходимости к построению собственное решение внутри своей организации. Это позволяет клиентам перераспределять бюджет и трудозатраты персонала, использовать их в тех местах, где это наиболее необходимо.

От телефонной трубки, которую можно найти на столе каждого сотрудника до клиентского программного обеспечения на ноутбуке сотрудника, VoIP частная основа, и все необходимые действия между каждым из компонентов в решении CaaS поддерживаются в режиме 27/7 поставщиком услуг CaaS.

Решения размещения и управления

Удаленное управление услугами инфраструктуры обеспечивается третьими лицами, казалось недопустимой ситуацией для большинства компаний. Однако за прошлое десятилетие с развитием технологий, организацией сети и программным обеспечением отношение изменилось. Это частично связано со снижением издержек при использовании выбранных услуг. Однако в отличие от единичных услуг предложение поставщиков услуг CaaS предоставляет полное коммуникационное решение, которое является полностью управляемый одним вендором. Наряду с особенностями, такими как VoIP и объединенные коммуникации, интеграция офисной автоматической телефонной станции с дополнительной функциональностью управляется одним вендором, который ответственен за всю интеграцию и доставку услуг пользователям.

Удобство управления и функциональность

Когда клиенты пользуются услугами связи на стороне поставщика услуг CaaS, они платят только за необходимую функциональность. Поставщик услуг может распределять стоимость услуг. Как отмечалось ранее, это способствует более экономичному внедрению и использованию общей необходимой функциональности для клиентов. Экономия за счет роста производства позволяет поставщикам услуг производить обслуживание достаточно гибко, они не привязаны к единственному поставщику инвестиций. Поставщики услуг в состоянии усилить решения лучших среди аналогичных поставщиков, таких как Microsoft, Google, Amazon, Cisco, Nortel более экономично.

Нет затрат средств на оборудования

Все оборудование расположено у поставщиков услуг CaaS, это фактически избавляет от необходимости клиентов поддерживать собственные информационные центры и оборудование. Отсутствуют расходы средств на электропотребление, охлаждение, аренду помещений. Клиенты получают многократную выгоду, используя центры обработки данных масштаба крупных авиакомпаний с полным резервированием — и это все включено в ежемесячную оплату.

Гарантируемая непрерывность бизнеса

Позволяет ли Ваш план аварийного восстановления после катастрофических событий в центре обработки данных продолжать непрерывно работать Вашему бизнесу? Как долго Ваша компания может работать при отключении электроэнергии? Для большинства

66

компаний эти события неизбежно означают ощутимые финансовые потери, связанные с простоем бизнеса. Распределение информационной системы компании между географически распределенными центрами обработки данных становятся нормой для все большего числа компаний. Это смягчает риск финансовых потерь и позволяет компаниям расположенным в месте, где произошли какие либо катастрофические события, восстанавливать инфраструктуру так скоро, насколько это возможно. Этот процесс осуществлен поставщиками услуг CaaS. Для большого количества компаний, работающий с голосовой передачей данных, перебои в работе системы являются катастрофическими. В отличие от целостности данных, устранение единственных точек отказа для голосовой сети является обычно достаточно дорогостоящим из-за крупного масштаба и сложности управления проектом. Решения CaaS обладают многократными уровнями избыточности системы, что исключает из системы единые точки отказа.

Мониторинг как Сервис (MaaS)

Мониторинг как Сервис (Monitoring-as-a-Service, MaaS) является обслуживаемым в облаке обеспечением безопасности, прежде всего на бизнес платформах. За прошлое десятилетие MaaS стал все более и более популярным. С появлением облачных вычислений, популярность MaaS стала больше. Контроль безопасности затрагивает защиту клиентов – предприятий или правительства от кибер угроз. Служба безопасности играет важную роль в обеспечении и поддержании конфиденциальность, целостность, и доступность средств ИТ. Однако время и ограниченные ресурсы ограничивают мероприятия безопасности и их эффективность для большинство компаний. Это требует постоянной бдительности безопасности инфраструктуры и критических информационных средств. Много промышленных правил требуют, чтобы организации контролировали свою среду безопасности, журналы серверов, и другие информационные средства, чтобы гарантировать целостность этих систем. Однако обеспечение эффективного контроля состояния безопасности может быть пугающей задачей, потому что она требует передовых технологий, квалифицированных экспертов по безопасности, и масштабируемые процесс, ни один из которых не является дешевым. Сервисы контроля состояния безопасности MaaS предлагает контроль в реальном времени, в режиме 24/7 и практически немедленные реагирование по инцидентам через инфраструктуру безопасности. Эти сервисы помогают защитить критические информационные активы клиентов. До появления электронных систем обеспечения безопасности, контроль состояния безопасности и реагирование зависели в большой степени от человеческих ресурсов и человеческих способностей, которые ограничивали правильность и эффективность контролирующих усилий. За прошедшие два десятилетия, были разработаны информационные технологии в системах обеспечения безопасности, которые способны взаимодействовать с центрами операционной безопасности (SOC) через корпоративные сети, что значительно изменило картину. Данные средства включают две важных вещи:

1.Общая стоимость владения центром операционной безопасности намного выше, чем для современной технологии SOC;

2.Достижение более низких операционных затрат безопасности и более высокая эффективность средств безопасности.

SOC услуги контроля состояния безопасности могут улучшить эффективность инфраструктура безопасности клиента, активно анализируя журналы и оповещения от устройств инфраструктуры круглосуточно и в режиме реального времени. Контроль команд соотносит информацию с различных устройств безопасности, чтобы предоставить аналитикам по безопасности данные, необходимые им для устранения ложный угроз и для реагирования на истинный угрозы предприятия. Служба информационной безопасности

67

может оценить производительность системы на периодически повторяющейся основе и обеспечить рекомендации для усовершенствований если необходимо.

Сервис раннего обнаружения сообщает о новых слабых местах в безопасности вскоре после того, как они появляются. Вообще, угрозы взаимосвязаны с источниками, имеющими отношение к третьей стороне. Отчет обычно посылается по электронной почте ответственному человеку, назначенному компанией. Отчеты об уязвимости безопасности, кроме содержания подробного описания уязвимости, также включает информацию о влиянии данной уязвимости на систему или приложение. Наиболее часто отчет также указывает на определенные действия, которые нужно выполнить, чтобы минимизировать эффект уязвимости.

Платформа, управление и мониторинг сервиса часто предоставляются как приборная панель, что позволяет в любое время узнать рабочее состояние системы. Доступ можно получить через веб-интерфейсы, что позволяет работать удаленно. Каждый рабочий элемент, который проверяется обычно содержит рабочий индикатор статуса, всегда принимая во внимание критическое воздействие каждого элемента. Данные сервиса позволяют определить, какие элементы находятся в рабочем состоянии, каким не хватает мощности, а какие находятся за пределами установленных параметров. Обнаруживая и идентифицируя такие проблемы, можно принимать профилактические меры, для предотвращения потери работоспособности сервиса.

Ключевые термины:

Инфраструктура как Сервис, IaaS — предоставление компьютерной инфраструктуры (как правило, это платформы виртуализации) как сервиса.

Платформа как сервис, PaaS – предоставление интегрированной платформы для разработки, тестирования, развертывания и поддержки веб-приложений как услуги, организованная на основе концепции облачных вычислений

Программное обеспечение как сервис, SaaS бизнес-модель продажи программного обеспечения, при которой поставщик разрабатывает веб-приложение и самостоятельно управляет им, предоставляя заказчикам доступ к программному обеспечению через Интернет.

Коммуникация как Сервис, CaaS — построенное в облаке коммуникационное решение для предприятия MaaS.

Литература:

1. John W. Rittinghouse, James F. Ransome – «Cloud Computing: Implementation, Management, and Security»

68

Лекция 5. Windows Azure SDK.

Windows Azure SDK предоставляет разработчикам интерфейс программирования приложений, необходимый для разработки, развертывания и управления масштабируемых сервисов в Windows Azure.

Azure Cloud Fabric и службы Azure Storage не поддерживают разработку или отладочные операции в облаке, поэтому Azure SDK позволяет делать это локально в виде приложений Development Fabric (DF) и Development Storage (DS), которые устанавливает

Windows Azure SDK. Вместе с SDK также устанавливаются коллекция приложений примеров и библиотеки упакованных классов для облегчения программирования приложений.

Должны быть установлены .NET Framework 3.5 SP1 и SQL Express 2005 or 2008, также необходимо включить ASP.NET и WCF HTTP Activation для IIS 7.0 для Windows Server 2008, Windows Vista SP2,or Windows 7 RC или позже для установки и запуска SDK.

Заметки к выпуску включают инструкции для настройки этих опций. Использование SDK не является обязательным, потому что есть возможность пользоваться любыми операционными системами и языками программирования, которые поддерживают HTTP запросы и ответы. Однако, вы увидите что использование SDK интерфейсов прикладного программирования .NET и библиотек для приложений и хранилищ позволяет наиболее просто работать с HTTP напрямую.

После того, как вы установили Azure SDK, Вы должны скачать и установить инструменты Windows Azure для Visual Studio для добавления шаблонов проектов Web Cloud Sevice, Worker Cloud Service, Web and Worker Cloud Service Workflow Service. Вы можете скачать текущую версию Windows Azure SDK и Windows Azure Tools для Visual Studio с главной страницы Windows Azure по ссылке www.microsoft.com/azure/windowsazure.mspx.

После установки Windows Azure Tools в Visual Studio появляются шаблоны Cloud Service в диалоге создания нового проекта. При выборе узла Cloud Service открываются

New Cloud Service, который позволяет добавить ASP.NET Web Roles, Worker Roles or CGI Web Roles для нового проекта. Windows Azure SDK позволяет добавить более чем одну роль для каждого типа Cloud Service. Каждая роль использует отдельный экземпляр Windows Azure CPU, так минимальная стоимость запуска проекта в облаке будет примерно 4 * $0.12 = $0.48 в час.

Рисунок 5.1 Создание нового проекта Cloud Service в Visual Studio

69

Добавив указанные роли и нажав ОК, откроется новое решение с проектами WebRole и Worker-Role в Solution Explorer как показано на рисунке 6.2.

Узел Roles содержит элементы WebRole, которые указывают на каждую WebRole, которая обеспечивает пользовательский интерфейс ASP.NET для приложения и каждый WorkerRole для вычислительный операций, которые не требуют пользовательского интерфейса или используют страниц ASP.NET WebRole вместо этого.

Рисунок 5.2 Solution Explorer Cloud Service

В зависимости от типа Cloud Service проекты включают пространство имен

Microsoft.ServiceHosting.ServiceRuntime, которое содержит классы, указанные в таблице ниже.

Класс

Описание

RoleEntryPoint

Обеспечивает методы для управления инициализацией,

запуском и остановкой методов сервиса, так же используется

для мониторинга состояния сервиса.

70

A few days ago I wrote a post about newly released Windows Azure SDK 2.0 for .Net. You can read that post here: https://gauravmantri.com/2013/04/30/introducing-windows-azure-sdk-2-0-for-net/. In that post I briefly talked about the improvements in the latest SDK with regards to Windows Azure Diagnostics (WAD). In this post, we’ll talk about WAD in more details. We’ll talk about improvements in SDK as well as changes in the Service Management API to facilitate these changes.

So let’s start.

Changes to Windows Azure Diagnostics

First let’s talk about changes done to Windows Azure Diagnostics.

Windows Azure Diagnostics is now an Extension

Windows Azure Diagnostics (WAD) module is now an extension to your cloud service. I wrote a blog post on extensions which you can read here: https://gauravmantri.com/2013/05/06/windows-azure-cloud-services-extensions-and-service-management-api-fun-with-remote-desktop/. What that means is that you can enable / disable diagnostics functionality on the fly. If you’ve been working with cloud services, I think you’ll greatly appreciate this enhancement. In the cloud services which used previous version (say 1.8) of the SDK, enabling diagnostics was a pain. One would need to remember a lot of things to get the diagnostics working and if one forgets to do those things, the only option to make diagnostics working was to go back to your code and make the changes and redeploy your application. NOT ANYMORE! Even if you forget to enable diagnostics when you first deploy your cloud service, you can enable the diagnostics on the fly using the extensions mechanism. Furthermore, you don’t really need to write any code in your role’s OnStart() method to enable the diagnostics.

We’ll see an example of how you can do this later in this post.

Configuring Windows Azure Diagnostics has never been easier

With the latest SDK, it’s extremely easy to configure Windows Azure Diagnostics (WAD). Visual Studio provides you with an easy to use user interface to configure the diagnostics. To configure WAD, open up your cloud service configuration by double clicking on the role’s name and go to “Configuration” tab. Under the “Diagnostics” section, you’ll see various configuration options as shown in the screenshot below:

clip_image002

If you’ve been using previous versions of SDK, you’re used to seeing this kind of screen:

clip_image004

As you can see from the screenshots, not only you get to choose whether the diagnostics should be enabled or disabled you also get a simple to use user interface to configure the diagnostics. Let’s talk about these options.

Errors only

When you choose “Errors Only” option, WAD extension transfers only the log entries with log level type “error” and “critical” to storage. A few things to keep in mind:

  • This option will only enable following log types – trace and event logs.
  • This option will not do anything with the performance counters. So no performance counters data will be transferred to storage.
  • As said earlier, only “error” and “critical” log entries will be transferred to storage.
  • By default the logs will be transferred to storage every minute or in other words the scheduled transfer period is one minute.

Following code segment shows what kind of trace log entries will be transferred if this option is chosen:

            Trace.WriteLine("This is verbose trace entry", "Verbose");//Will NOT be transferred.
            Trace.WriteLine("This is information trace entry", "Information");//Will NOT be transferred.
            Trace.WriteLine("This is warning trace entry", "Warning");//Will NOT be transferred.
            Trace.WriteLine("This is error trace entry", "Error");//Will BE transferred.
            Trace.WriteLine("This is critical trace entry", "Critical");//Will BE transferred.

All information

When you choose “All information” option, WAD extension transfers all log entries to storage. A few things to keep in mind:

  • This option will only enable following log types – trace and event logs.
  • This option will not do anything with the performance counters. So no performance counters data will be transferred to storage.
  • As said earlier, all log entries will be transferred to storage. This would include the following log level types: Verbose, Information, Warning, Error and Critical.
  • By default the logs will be transferred to storage every minute or in other words the scheduled transfer period is one minute.

Following code segment shows what kind of trace log entries will be transferred if this option is chosen:

            Trace.WriteLine("This is verbose trace entry", "Verbose");// Will BE transferred.
            Trace.WriteLine("This is information trace entry", "Information");// Will BE transferred.
            Trace.WriteLine("This is warning trace entry", "Warning");// Will BE transferred.
            Trace.WriteLine("This is error trace entry", "Error");//Will BE transferred.
            Trace.WriteLine("This is critical trace entry", "Critical");//Will BE transferred.

Custom plan

Custom plan is where things get interesting. Here you get full flexibility for configuring WAD. This is where you’re in complete control of what is captured and what gets transferred to storage. Here’re a few screenshots of the window where you can customize the diagnostics:

Trace Logs
clip_image002[5]

Event Logs
clip_image004[5]

Performance Counters
clip_image006

My guess is that most of the time developers would use these screens to configure diagnostics.

Diagnostics.wadcfg file

If you look closely in your solution explorer, you’ll notice a diagnostics.wadcfg file beneath your role name. You can read more about this file here: http://msdn.microsoft.com/en-us/library/windowsazure/hh411551.aspx.

clip_image002[7]

Essentially when you configure diagnostics using one of the options above, Visual Studio automatically updates this file. This is not a new concept and has been around for quite some time. What’s new is that now Visual Studio creates this file for you. So if you want to tweak some settings after Visual Studio has updated the file, just modify the XML file manually and you should be good to go.

Good Bye Old Storage Client Library

SDK 1.8 came with a new version of storage client library (2.0.0.0) however Windows Azure Diagnostics (WAD) was not updated to make use of this library. It was still using older version of storage client library. Needless to say, it was a big mess. Not only you would need to remember to add reference to both versions of the library but also take into consideration the different namespaces of older and newer versions of storage client library. With the release of SDK 2.0, WAD library is updated to make use of the latest version of storage client library which is 2.0.5.1 at the time SDK 2.0 was made live.

Diagnostics Extension

In this section we’ll talk about diagnostics extension and how it can be used to enable/disable or change diagnostics on the fly. I would recommend going through my blog post on extensions first because we’ll make use of code from that post. You can read that post here: https://gauravmantri.com/2013/05/06/windows-azure-cloud-services-extensions-and-service-management-api-fun-with-remote-desktop/.

For fun sake, we’ll create a cloud service (a simple worker role will do) and choose not to enable diagnostics. When we do that, out diagnostics.wadcfg file looks something like this:

<?xml version="1.0" encoding="utf-8"?>
<DiagnosticMonitorConfiguration configurationChangePollInterval="PT1M" 
                                overallQuotaInMB="4096" 
                                xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">
  <DiagnosticInfrastructureLogs />
  <Directories>
    <IISLogs container="wad-iis-logfiles" />
    <CrashDumps container="wad-crash-dumps" />
  </Directories>
  <Logs bufferQuotaInMB="1024" scheduledTransferPeriod="PT0M" scheduledTransferLogLevelFilter="Error" />
  <WindowsEventLog bufferQuotaInMB="1024" scheduledTransferPeriod="PT0M" scheduledTransferLogLevelFilter="Error">
    <DataSource name="Application!*" />
  </WindowsEventLog>
</DiagnosticMonitorConfiguration>

This is how my worker role’s code looks like:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.Storage;

namespace WorkerRole1
{
    public class WorkerRole : RoleEntryPoint
    {
        public override void Run()
        {
            // This is a sample worker implementation. Replace with your logic.
            Trace.TraceInformation("WorkerRole1 entry point called", "Information");

            while (true)
            {
                Thread.Sleep(10000);
                Trace.WriteLine("This is verbose trace entry", "Verbose");//Will NOT be transferred.
                Trace.WriteLine("This is information trace entry", "Information");//Will NOT be transferred.
                Trace.WriteLine("This is warning trace entry", "Warning");//Will BE transferred.
                Trace.WriteLine("This is error trace entry", "Error");//Will BE transferred.
                Trace.WriteLine("This is critical trace entry", "Critical");//Will BE transferred.
            }
        }

        public override bool OnStart()
        {
            // Set the maximum number of concurrent connections 
            ServicePointManager.DefaultConnectionLimit = 12;

            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

            return base.OnStart();
        }
    }
}

Nothing special really. One thing you’ll notice in the OnStart() method is that I’ve not included initialization code for diagnostics. In prior versions of the SDK, I would need to add the following 2 lines of code for diagnostics to work:

            DiagnosticMonitorConfiguration config = DiagnosticMonitor.GetDefaultInitialConfiguration();
            DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", config); 

And this is how my configuration file looks like. If you notice, there’s no diagnostics connection string there.

<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="WindowsAzure6" 
                      xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" 
                      osFamily="3" osVersion="*" schemaVersion="2013-03.2.0">
  <Role name="WorkerRole1">
    <Instances count="1" />
    <ConfigurationSettings>
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

Let’s publish this cloud service. To ensure Visual Studio is not doing anything “funky”, we’ll just package the file and upload it using Azure Management Studio. If you want, you can upload it through the portal as well.

Now it’s time to get a bit dramatic Smile. For the sake of adding drama to the whole equation, let’s assume that you’re working with a remote team with significant time difference so that you don’t really talk with your remote team in real time but using emails and stuff. The remote team is responsible for the code and deployment and in all their wisdom, they just deployed the service with code as above i.e. with no diagnostics enabled but you don’t know that. Suddenly you start getting calls from your users that the application is running slow and they are not able to do anything there. On top of that, your boss is breathing down your neck to find the problem. Your first reaction is to fire your favorite tools to see diagnostics data to figure out what’s going on but then you realize that your “smart ass remote team Smile” forgot to enable diagnostics. Following sections will help you get out of the murky water and make you an office superhero!!! Let’s begin.

Step 1: Get the details of diagnostics extension

Using the code from my previous post, you get the details of diagnostics extension so that you can fetch public and private configuration schema for diagnostics:

            var allExtensions = ListAvailableExtensions(subscriptionId, cert);
            var diagnostics = allExtensions.FirstOrDefault(e => e.Type == "Diagnostics");

Public Configuration Schema:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="DiagnosticsConfigSchema"    targetNamespace="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration"    elementFormDefault="qualified"    xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration"    xmlns:mstns="http://tempuri.org/XMLSchema.xsd"    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="PositiveDuration">
    <xs:restriction base="xs:duration">
      <xs:minInclusive value="PT0S" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="LogLevel">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Undefined" />
      <xs:enumeration value="Verbose" />
      <xs:enumeration value="Information" />
      <xs:enumeration value="Warning" />
      <xs:enumeration value="Error" />
      <xs:enumeration value="Critical" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="ContainerName">
    <xs:restriction base="xs:string">
      <xs:pattern value="[a-z0-9][a-z0-9-]{1,61}[a-z0-9]" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="AbsolutePathWithEnvironmentExpansion">
    <xs:restriction base="xs:string">
      <xs:pattern value="([a-zA-Z]:\)?([^&lt;&gt;:&quot;/|?*]+)*(\)?" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="RelativePathWithEnvironmentExpansion">
    <xs:restriction base="xs:string">
      <xs:pattern value="([^&lt;&gt;:&quot;/\|?*]+)(\([^&lt;&gt;:&quot;/\|?*]+))*(\)?" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="PerformanceCounterPath">
    <xs:restriction base="xs:string">
      <xs:pattern value="\[^\()/#*]+((([^\()#*]+|[^\()#*]+/[^\()#*]+|[^\()#*]+#[^\()#*]+|[^\()#*]+/[^\()#*]+#[^\()#*]+|*)))?\[^\()*]+" />
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="NamedElementNameString">
    <xs:restriction base="xs:string">
      <xs:pattern value="^[a-zA-Z_][^\/:*?&quot;&lt;&gt;|]*(?&lt;![.s])$" />
    </xs:restriction>
  </xs:simpleType>
  <xs:attributeGroup name="BasicConfiguration">
    <xs:attribute name="bufferQuotaInMB" type="xs:unsignedInt" use="optional" default="0">
      <xs:annotation>
        <xs:documentation>          The maximum amount of file system storage allocated for the specified data.        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="scheduledTransferPeriod" type="PositiveDuration" use="optional" default="PT0S">
      <xs:annotation>
        <xs:documentation>          The interval between scheduled transfers for this data, rounded up to the nearest minute.        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
  </xs:attributeGroup>
  <xs:attributeGroup name="LogLevel">
    <xs:attribute name="scheduledTransferLogLevelFilter" type="LogLevel" use="optional" default="Undefined">
      <xs:annotation>
        <xs:documentation>          The minimum log severity to transfer.        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
  </xs:attributeGroup>
  <xs:attributeGroup name="DirectoryAttributes">
    <xs:attribute name="container" type="ContainerName" use="required">
      <xs:annotation>
        <xs:documentation>          The name of the container where the content of the directory is to be transferred.        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="directoryQuotaInMB" type="xs:unsignedInt" use="optional" default="0">
      <xs:annotation>
        <xs:documentation>          The maximum size of the directory in megabytes.        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
  </xs:attributeGroup>
  <xs:complexType name="LogsBase">
    <xs:attributeGroup ref="BasicConfiguration" />
  </xs:complexType>
  <xs:complexType name="DiagnosticInfrastructureLogs">
    <xs:complexContent>
      <xs:extension base="LogsBase">
        <xs:attributeGroup ref="LogLevel" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="DirectoryBase" />
  <xs:complexType name="DirectoryAbsolute">
    <xs:complexContent>
      <xs:extension base="DirectoryBase">
        <xs:attribute name="path" type="AbsolutePathWithEnvironmentExpansion" use="required">
          <xs:annotation>
            <xs:documentation>              The absolute path to the directory to monitor.            </xs:documentation>
          </xs:annotation>
        </xs:attribute>
        <xs:attribute name="expandEnvironment" type="xs:boolean" use="required">
          <xs:annotation>
            <xs:documentation>              If true, then environment variables in the path will be expanded.            </xs:documentation>
          </xs:annotation>
        </xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="DirectoryLocalResource">
    <xs:complexContent>
      <xs:extension base="DirectoryBase">
        <xs:attribute name="relativePath" type="RelativePathWithEnvironmentExpansion" use="required">
          <xs:annotation>
            <xs:documentation>              The path relative to the local resource to monitor.            </xs:documentation>
          </xs:annotation>
        </xs:attribute>
        <xs:attribute name="name" type="NamedElementNameString" use="required">
          <xs:annotation>
            <xs:documentation>              The local resource that contains the directory to monitor.            </xs:documentation>
          </xs:annotation>
        </xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="DirectoryConfiguration">
    <xs:choice>
      <xs:element name="Absolute" type="DirectoryAbsolute">
        <xs:annotation>
          <xs:documentation>            The absolute path to the directory to monitor.          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="LocalResource" type="DirectoryLocalResource">
        <xs:annotation>
          <xs:documentation>            The path relative to a local resource to monitor.          </xs:documentation>
        </xs:annotation>
      </xs:element>
    </xs:choice>
    <xs:attributeGroup ref="DirectoryAttributes" />
  </xs:complexType>
  <xs:complexType name="SpecialLogDirectory">
    <xs:attributeGroup ref="DirectoryAttributes" />
  </xs:complexType>
  <xs:complexType name="DataSources">
    <xs:sequence maxOccurs="unbounded">
      <xs:element name="DirectoryConfiguration" type="DirectoryConfiguration" maxOccurs="unbounded">
        <xs:annotation>
          <xs:documentation>            The directory of log files to monitor.          </xs:documentation>
        </xs:annotation>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="Directories">
    <xs:complexContent>
      <xs:extension base="LogsBase">
        <xs:all>
          <xs:element name="IISLogs" type="SpecialLogDirectory" minOccurs="0">
            <xs:annotation>
              <xs:documentation>                The IIS log directory.              </xs:documentation>
            </xs:annotation>
          </xs:element>
          <xs:element name="FailedRequestLogs" type="SpecialLogDirectory" minOccurs="0">
            <xs:annotation>
              <xs:documentation>                The failed request log directory.              </xs:documentation>
            </xs:annotation>
          </xs:element>
          <xs:element name="CrashDumps" type="SpecialLogDirectory" minOccurs="0">
            <xs:annotation>
              <xs:documentation>                The crash dump directory.              </xs:documentation>
            </xs:annotation>
          </xs:element>
          <xs:element name="DataSources" type="DataSources" minOccurs="0">
            <xs:annotation>
              <xs:documentation>                Additional log directories.              </xs:documentation>
            </xs:annotation>
          </xs:element>
        </xs:all>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="Logs">
    <xs:complexContent>
      <xs:extension base="LogsBase">
        <xs:attributeGroup ref="LogLevel" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="PerformanceCounterConfiguration">
    <xs:attribute name="counterSpecifier" type="PerformanceCounterPath" use="required">
      <xs:annotation>
        <xs:documentation>          The path to the performance counter to collect.        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="sampleRate" type="PositiveDuration" use="required">
      <xs:annotation>
        <xs:documentation>          The rate at which the performance counter should be sampled.        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
  </xs:complexType>
  <xs:complexType name="PerformanceCounters">
    <xs:complexContent>
      <xs:extension base="LogsBase">
        <xs:sequence maxOccurs="unbounded">
          <xs:element name="PerformanceCounterConfiguration" type="PerformanceCounterConfiguration">
            <xs:annotation>
              <xs:documentation>                The performance counter to collect.              </xs:documentation>
            </xs:annotation>
          </xs:element>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="DataSource">
    <xs:attribute name="name" type="xs:string" use="required">
      <xs:annotation>
        <xs:documentation>          An XPath expression specifying the logs to collect.        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
  </xs:complexType>
  <xs:complexType name="WindowsEventLog">
    <xs:complexContent>
      <xs:extension base="LogsBase">
        <xs:sequence maxOccurs="unbounded">
          <xs:element name="DataSource" type="DataSource">
            <xs:annotation>
              <xs:documentation>                The event log to monitor.              </xs:documentation>
            </xs:annotation>
          </xs:element>
        </xs:sequence>
        <xs:attributeGroup ref="LogLevel" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="DiagnosticMonitorConfiguration">
    <xs:all>
      <xs:element name="DiagnosticInfrastructureLogs" type="DiagnosticInfrastructureLogs" minOccurs="0">
        <xs:annotation>
          <xs:documentation>            Configures the logs generated by the underlying diagnostics infrastructure. The diagnostic infrastructure logs are useful for troubleshooting the diagnostics system itself.          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="Directories" type="Directories" minOccurs="0">
        <xs:annotation>
          <xs:documentation>            Describes the configuration of a directory to which file-based logs are written.          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="Logs" type="Logs" minOccurs="0">
        <xs:annotation>
          <xs:documentation>            Configures basic Windows Azure logs.          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="PerformanceCounters" type="PerformanceCounters" minOccurs="0">
        <xs:annotation>
          <xs:documentation>            Configures performance counter collection.          </xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element name="WindowsEventLog" type="WindowsEventLog" minOccurs="0">
        <xs:annotation>
          <xs:documentation>            Configures Windows event log collection.          </xs:documentation>
        </xs:annotation>
      </xs:element>
    </xs:all>
    <xs:attribute name="configurationChangePollInterval" type="PositiveDuration" use="optional" default="PT1M">
      <xs:annotation>
        <xs:documentation>          The interval at which the diagnostic monitor polls for configuration changes.        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
    <xs:attribute name="overallQuotaInMB" type="xs:unsignedInt" use="optional" default="4000">
      <xs:annotation>
        <xs:documentation>          The total amount of file system storage allocated for all logging buffers.        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
  </xs:complexType>
  <xs:complexType name="StorageAccount">
    <xs:all>
      <xs:element name="Name" type="xs:string" minOccurs="0" maxOccurs="1" />
      <xs:element name="DefaultEndpointsProtocol" type="xs:string" minOccurs="0" maxOccurs="1" default="https" />
      <xs:element name="ConnectionQualifiers" type="xs:string" minOccurs="0" maxOccurs="1" />
    </xs:all>
  </xs:complexType>
  <xs:element name="PublicConfig">
    <xs:complexType>
      <xs:all>
        <xs:element name="WadCfg">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="DiagnosticMonitorConfiguration" type="DiagnosticMonitorConfiguration" minOccurs="0" maxOccurs="1"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="StorageAccount" type="StorageAccount" minOccurs="1" />
      </xs:all>
    </xs:complexType>
  </xs:element>
</xs:schema>

Private Configuration Schema:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="PrivateConfig">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="StorageKey" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Based on these, you can generate XML template for public and private configurations.

Public Configuration XML Template:

<?xml version="1.0" encoding="utf-8"?>
<PublicConfig xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">
  <StorageAccount>
    <ConnectionQualifiers>ConnectionQualifiers1</ConnectionQualifiers>
    <DefaultEndpointsProtocol>https</DefaultEndpointsProtocol>
    <Name>Name1</Name>
  </StorageAccount>
  <WadCfg>
    <DiagnosticMonitorConfiguration configurationChangePollInterval="PT1M" overallQuotaInMB="4000">
      <WindowsEventLog scheduledTransferLogLevelFilter="Undefined" bufferQuotaInMB="0" scheduledTransferPeriod="PT0S">
        <DataSource name="name1" />
        <DataSource name="name2" />
        <DataSource name="name3" />
      </WindowsEventLog>
      <PerformanceCounters bufferQuotaInMB="0" scheduledTransferPeriod="PT0S">
        <PerformanceCounterConfiguration counterSpecifier="counterSpecifier1" sampleRate="PT0S" />
        <PerformanceCounterConfiguration counterSpecifier="counterSpecifier2" sampleRate="P10675199DT2H48M5.477S" />
        <PerformanceCounterConfiguration counterSpecifier="counterSpecifier3" sampleRate="P365D" />
      </PerformanceCounters>
      <Logs scheduledTransferLogLevelFilter="Undefined" bufferQuotaInMB="0" scheduledTransferPeriod="PT0S" />
      <Directories bufferQuotaInMB="0" scheduledTransferPeriod="PT0S">
        <DataSources>
          <DirectoryConfiguration container="container1" directoryQuotaInMB="0">
            <Absolute path="path1" expandEnvironment="true" />
          </DirectoryConfiguration>
          <DirectoryConfiguration container="container2" directoryQuotaInMB="0">
            <Absolute path="path2" expandEnvironment="false" />
          </DirectoryConfiguration>
          <DirectoryConfiguration container="container3" directoryQuotaInMB="4294967295">
            <Absolute path="path3" expandEnvironment="true" />
          </DirectoryConfiguration>
          <DirectoryConfiguration container="container4" directoryQuotaInMB="1">
            <Absolute path="path4" expandEnvironment="false" />
          </DirectoryConfiguration>
          <DirectoryConfiguration container="container5" directoryQuotaInMB="4294967294">
            <Absolute path="path5" expandEnvironment="true" />
          </DirectoryConfiguration>
          <DirectoryConfiguration container="container6" directoryQuotaInMB="2">
            <Absolute path="path6" expandEnvironment="false" />
          </DirectoryConfiguration>
          <DirectoryConfiguration container="container7" directoryQuotaInMB="4294967293">
            <Absolute path="path7" expandEnvironment="true" />
          </DirectoryConfiguration>
          <DirectoryConfiguration container="container8" directoryQuotaInMB="3">
            <Absolute path="path8" expandEnvironment="false" />
          </DirectoryConfiguration>
          <DirectoryConfiguration container="container9" directoryQuotaInMB="4294967292">
            <Absolute path="path9" expandEnvironment="true" />
          </DirectoryConfiguration>
        </DataSources>
        <CrashDumps container="container1" directoryQuotaInMB="0" />
        <FailedRequestLogs container="container1" directoryQuotaInMB="0" />
        <IISLogs container="container1" directoryQuotaInMB="0" />
      </Directories>
      <DiagnosticInfrastructureLogs scheduledTransferLogLevelFilter="Undefined" bufferQuotaInMB="0" scheduledTransferPeriod="PT0S" />
    </DiagnosticMonitorConfiguration>
  </WadCfg>
</PublicConfig>

Private Configuration XML Template:

<?xml version="1.0" encoding="utf-8"?>
<PrivateConfig>
  <StorageKey>StorageKey1</StorageKey>
</PrivateConfig>

Step 2: Create XML files

Using the templates from the previous steps, we create public and private configuration XML files. Let’s assume that we’re only interested in capturing all trace log entries, “Application” event logs and 2 performance counters – “Processor(_Total)% Processor Time” and “MemoryAvailable Mbytes”. Based on this, this is how our XML files look like:

Public Configuration XML:

<?xml version="1.0" encoding="utf-8"?>
<PublicConfig xmlns="http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration">
  <StorageAccount>
    <ConnectionQualifiers/>
    <DefaultEndpointsProtocol>https</DefaultEndpointsProtocol>
    <Name>[your storage account name]</Name>
  </StorageAccount>
  <WadCfg>
    <DiagnosticMonitorConfiguration configurationChangePollInterval="PT1M" overallQuotaInMB="4096">
      <DiagnosticInfrastructureLogs />
      <Directories>
        <IISLogs container="wad-iis-logfiles" />
        <CrashDumps container="wad-crash-dumps" />
      </Directories>
      <Logs bufferQuotaInMB="1024" scheduledTransferPeriod="PT1M" scheduledTransferLogLevelFilter="Verbose" />
      <PerformanceCounters bufferQuotaInMB="1024" scheduledTransferPeriod="PT1M">
        <PerformanceCounterConfiguration counterSpecifier="Processor(_Total)% Processor Time" sampleRate="PT1S" />
        <PerformanceCounterConfiguration counterSpecifier="MemoryAvailable MBytes" sampleRate="PT1S" />
      </PerformanceCounters>
      <WindowsEventLog bufferQuotaInMB="1024" scheduledTransferPeriod="PT1M" scheduledTransferLogLevelFilter="Error">
        <DataSource name="Application!*" />
      </WindowsEventLog>
    </DiagnosticMonitorConfiguration>
  </WadCfg>
</PublicConfig>

Private Configuration XML:

<?xml version="1.0" encoding="utf-8"?>
<PrivateConfig>
  <StorageKey>[your storage account key]</StorageKey>
</PrivateConfig>

Step 3: Add WAD Extension

To add WAD extension, we’ll use public and private key configuration for the extension and add that extension to the cloud service.

            string publicConfiguration = @"<?xml version=""1.0"" encoding=""utf-8""?>
                <PublicConfig xmlns=""http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration"">
                  <StorageAccount>
                    <ConnectionQualifiers/>
                    <DefaultEndpointsProtocol>https</DefaultEndpointsProtocol>
                    <Name>[your storage account name]</Name>
                  </StorageAccount>
                  <WadCfg>
                    <DiagnosticMonitorConfiguration configurationChangePollInterval=""PT1M"" overallQuotaInMB=""4096"">
                      <DiagnosticInfrastructureLogs />
                      <Directories>
                        <IISLogs container=""wad-iis-logfiles"" />
                        <CrashDumps container=""wad-crash-dumps"" />
                      </Directories>
                      <Logs bufferQuotaInMB=""1024"" scheduledTransferPeriod=""PT1M"" scheduledTransferLogLevelFilter=""Verbose"" />
                      <PerformanceCounters bufferQuotaInMB=""1024"" scheduledTransferPeriod=""PT1M"">
                        <PerformanceCounterConfiguration counterSpecifier=""Processor(_Total)% Processor Time"" sampleRate=""PT1S"" />
                        <PerformanceCounterConfiguration counterSpecifier=""MemoryAvailable MBytes"" sampleRate=""PT1S"" />
                      </PerformanceCounters>
                      <WindowsEventLog bufferQuotaInMB=""1024"" scheduledTransferPeriod=""PT1M"" scheduledTransferLogLevelFilter=""Error"">
                        <DataSource name=""Application!*"" />
                      </WindowsEventLog>
                    </DiagnosticMonitorConfiguration>
                  </WadCfg>
                </PublicConfig>";

            string privateConfiguration = @"<?xml version=""1.0"" encoding=""utf-8""?>
                <PrivateConfig>
                  <StorageKey>[your storage account key]</StorageKey>
                </PrivateConfig>";

            AzureExtension wadExtension = new AzureExtension()
            {
                ProviderNamespace = "Microsoft.Windows.Azure.Extensions",
                Type = "Diagnostics",
                Id = "DiagnosticsExtensionWhichWillSaveMyButt",
                PublicConfiguration = publicConfiguration,
                PrivateConfiguration = privateConfiguration,
            };

            AddExtension(subscriptionId, cert, cloudServiceName, wadExtension);

Step 4: Update Configuration

Once the extension is added, next step would be to update the cloud service configuration by performing “Change Deployment Configuration” operation. For this, first we may need to fetch the current configuration. To do so, we’ll perform “Get Hosted Service Properties” operation and try to get both production and staging configuration settings. Here’s the sample code to get the configuration settings:

        private static string[] GetCloudServiceDeploymentConfigurations(string subscriptionId, X509Certificate2 cert, string cloudServiceName)
        {
            string[] deploymentConfigurations = new string[2];//We'll try to get both production and staging deployment configurations. The 1st element will always be production and the 2nd will be staging.
            string uri = string.Format("https://management.core.windows.net/{0}/services/hostedservices/{1}?embed-detail=true", subscriptionId, cloudServiceName);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            request.Method = "GET";
            request.Headers.Add("x-ms-version", "2013-03-01");
            request.ClientCertificates.Add(cert);
            using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
            {
                using (var streamReader = new StreamReader(resp.GetResponseStream()))
                {
                    string result = streamReader.ReadToEnd();
                    XElement cloudServiceProperties = XElement.Parse(result);
                    var deployments = cloudServiceProperties.Elements(XName.Get("Deployments", "http://schemas.microsoft.com/windowsazure"));
                    foreach (var deployment in deployments.Elements())
                    {
                        var slotElement = deployment.Element(XName.Get("DeploymentSlot", "http://schemas.microsoft.com/windowsazure"));
                        var configElement = deployment.Element(XName.Get("Configuration", "http://schemas.microsoft.com/windowsazure"));
                        var deploymentSlot = slotElement.Value;
                        var configurationSettings = Encoding.UTF8.GetString(Convert.FromBase64String(configElement.Value));
                        switch (deploymentSlot.ToUpper())
                        {
                            case "PRODUCTION":
                                deploymentConfigurations[0] = configurationSettings;
                                break;
                            case "STAGING":
                                deploymentConfigurations[1] = configurationSettings;
                                break;
                        }
                    }
                }
            }
            return deploymentConfigurations;
        }

Now that we’ve got the configurations for both production and staging slots, let’s apply the changes. Here’s the sample code for change deployment configuration operation:

        private static void ChangeDeploymentConfiguration(string subscriptionId, X509Certificate2 cert, string cloudServiceName, string slot, string configuration)
        {
            try
            {
                string uri = string.Format("https://management.core.windows.net/{0}/services/hostedservices/{1}/deploymentslots/{2}/?comp=config", subscriptionId, cloudServiceName, slot);
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
                request.Method = "POST";
                request.ContentType = "application/xml";
                request.Headers.Add("x-ms-version", "2013-03-01");
                request.ClientCertificates.Add(cert);
                byte[] content = Encoding.UTF8.GetBytes(configuration);
                request.ContentLength = content.Length;
                using (var requestStream = request.GetRequestStream())
                {
                    requestStream.Write(content, 0, content.Length);
                }

                using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
                {
                }
            }
            catch (WebException webEx)
            {
                using (var streamReader = new StreamReader(webEx.Response.GetResponseStream()))
                {
                    string result = streamReader.ReadToEnd();
                    Console.WriteLine(result);
                }
            }

        }

And this is how you call it:

            string updateConfigurationFormat = @"<?xml version=""1.0"" encoding=""utf-8""?>
                <ChangeConfiguration xmlns=""http://schemas.microsoft.com/windowsazure"">
                  <Configuration>{0}</Configuration>
                <ExtensionConfiguration>
                    <AllRoles>
                      <Extension>
                        <Id>{1}</Id>
                      </Extension>
                    </AllRoles>
                 </ExtensionConfiguration>
                </ChangeConfiguration>";

            var productionConfig = configurations[0];
            if (!string.IsNullOrWhiteSpace(productionConfig))
            {
                var productionConfigurationSetting = string.Format(updateConfigurationFormat, Convert.ToBase64String(Encoding.UTF8.GetBytes(productionConfig)), wadExtension.Id);
                ChangeDeploymentConfiguration(subscriptionId, cert, cloudServiceName, "Production", productionConfigurationSetting);
            }

Putting it all together nicely in just one function:

        private static void AddDiagnosticsExtension(string subscriptionId, X509Certificate2 cert, string cloudServiceName)
        {
            string publicConfiguration = @"<?xml version=""1.0"" encoding=""utf-8""?>
                <PublicConfig xmlns=""http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration"">
                  <StorageAccount>
                    <ConnectionQualifiers/>
                    <DefaultEndpointsProtocol>https</DefaultEndpointsProtocol>
                    <Name>[your storage account name]</Name>
                  </StorageAccount>
                  <WadCfg>
                    <DiagnosticMonitorConfiguration configurationChangePollInterval=""PT1M"" overallQuotaInMB=""4096"">
                      <DiagnosticInfrastructureLogs />
                      <Directories>
                        <IISLogs container=""wad-iis-logfiles"" />
                        <CrashDumps container=""wad-crash-dumps"" />
                      </Directories>
                      <Logs bufferQuotaInMB=""1024"" scheduledTransferPeriod=""PT1M"" scheduledTransferLogLevelFilter=""Verbose"" />
                      <PerformanceCounters bufferQuotaInMB=""1024"" scheduledTransferPeriod=""PT1M"">
                        <PerformanceCounterConfiguration counterSpecifier=""Processor(_Total)% Processor Time"" sampleRate=""PT1S"" />
                        <PerformanceCounterConfiguration counterSpecifier=""MemoryAvailable MBytes"" sampleRate=""PT1S"" />
                      </PerformanceCounters>
                      <WindowsEventLog bufferQuotaInMB=""1024"" scheduledTransferPeriod=""PT1M"" scheduledTransferLogLevelFilter=""Error"">
                        <DataSource name=""Application!*"" />
                      </WindowsEventLog>
                    </DiagnosticMonitorConfiguration>
                  </WadCfg>
                </PublicConfig>";

            string privateConfiguration = @"<?xml version=""1.0"" encoding=""utf-8""?>
                <PrivateConfig>
                  <StorageKey>[your storage account key]</StorageKey>
                </PrivateConfig>";

            string updateConfigurationFormat = @"<?xml version=""1.0"" encoding=""utf-8""?>
                <ChangeConfiguration xmlns=""http://schemas.microsoft.com/windowsazure"">
                  <Configuration>{0}</Configuration>
                <ExtensionConfiguration>
                    <AllRoles>
                      <Extension>
                        <Id>{1}</Id>
                      </Extension>
                    </AllRoles>
                 </ExtensionConfiguration>
                </ChangeConfiguration>";

            AzureExtension wadExtension = new AzureExtension()
            {
                ProviderNamespace = "Microsoft.Windows.Azure.Extensions",
                Type = "Diagnostics",
                Id = "DiagnosticsExtensionWhichWillSaveMyButt",
                PublicConfiguration = publicConfiguration,
                PrivateConfiguration = privateConfiguration,
            };

            AddExtension(subscriptionId, cert, cloudServiceName, wadExtension);

            var configurations = GetCloudServiceDeploymentConfigurations(subscriptionId, cert, cloudServiceName);
            var productionConfig = configurations[0];
            if (!string.IsNullOrWhiteSpace(productionConfig))
            {
                var productionConfigurationSetting = string.Format(updateConfigurationFormat, Convert.ToBase64String(Encoding.UTF8.GetBytes(productionConfig)), wadExtension.Id);
                ChangeDeploymentConfiguration(subscriptionId, cert, cloudServiceName, "Production", productionConfigurationSetting);
            }
            var stagingConfig = configurations[1];
            if (!string.IsNullOrWhiteSpace(stagingConfig))
            {
                var stagingConfigurationSetting = string.Format(updateConfigurationFormat, Convert.ToBase64String(Encoding.UTF8.GetBytes(stagingConfig)), wadExtension.Id);
                ChangeDeploymentConfiguration(subscriptionId, cert, cloudServiceName, "Staging", stagingConfigurationSetting);
            }
        }

That’s pretty much it!!! Once the operation is complete, you should be able to see the diagnostics data for your cloud service in some time.

clip_image002[9]

Summary

I strongly believe that changes done to diagnostics in SDK 2.0 are pretty significant. From my personal experience working with various users of Cerebrata Azure Diagnostics Manager, I do believe that it’s a boon to developers. Now it is very easy and straight forward to configure the diagnostics and change it on the fly. That’s it for this post. As always, if you find any issues with the post please let me know and I’ll fix it ASAP.

Happy Coding!

Понравилась статья? Поделить с друзьями:
  • Зачем нужны виртуальные рабочие столы в windows 10
  • Зачем нужно несколько рабочих столов windows 10
  • Зачем нужно индексирование файлов windows 10
  • Зачем нужно залипание клавиш в windows
  • Зачем нужно делить жесткий диск на разделы в windows