Freigeben über


Cloud-Diagnose

Protokollierung und Ablaufverfolgung in Windows Azure

Mike Kelly

Beispielcode herunterladen.

Wie viele andere Programmierer auch, habe ich in meiner Anfängerzeit Ausgabeanweisungen zum Debuggen verwendet. Denn ich wusste nicht, wie man einen Debugger benutzt, und die Ausgabeanweisungen waren ein primitives, aber wirkungsvolles Mittel, um zu sehen, was mein Programm so alles machte. Später lernte ich, mit richtigen Debuggern umzugehen, und gab Ausgabeanweisungen als Tool zum Debuggen auf.

Einige Zeit danach begann ich, Code zu schreiben, der auf Servern ausgeführt wurde. Schnell fand ich heraus, dass die guten alten Ausgabeanweisungen nun unter der etwas eindrucksvolleren Bezeichnung „Protokollierung und Ablaufverfolgung“ als unverzichtbare Techniken für jeden Programmierer von Serveranwendungen galten.

Selbst wenn man einen Debugger an eine Produktionsserveranwendung anhängen könnte (was aufgrund von Sicherheitseinschränkungen auf den Computern, die als Hosts der Anwendung fungieren, oft gar nicht möglich ist), so ließen sich viele der Probleme, die bei Serveranwendungen auftreten, mit herkömmlichen Debuggern nicht unbedingt feststellen. Viele Serveranwendungen sind verteilt und werden auf mehreren Computern ausgeführt. Zwar kann man durch Debuggen ermitteln, was auf einem Computer abläuft, aber das genügt oft nicht, um die in der Praxis auftretenden Probleme zu diagnostizieren.

Darüber hinaus werden Serveranwendungen oft von IT-Personal betreut, das mit einem herkömmlichen Debugger nicht umgehen kann, und bei jedem Problem einen Entwickler zu Hilfe zu rufen, das ist weder wünschenswert noch praktikabel.

In diesem Artikel möchte ich einige grundlegende Techniken für Protokollierung, Ablaufverfolgung und Debuggen bei Serveranwendungen erläutern. Dann stelle ich dar, wie man diese Techniken bei Windows Azure-Projekten einsetzen kann. Außerdem lernen Sie in diesem Artikel, wie man Protokollierung und Ablaufverfolgung bei echten Anwendungen in der Praxis einsetzt und wie man in Windows PowerShell die Diagnoseverwaltung für Dienste durchführt, die gerade ausgeführt werden.

Protokollierungsstrategie

Im Idealfall integriert man eine Protokollierungs- und Ablaufverfolgungsstrategie von Anfang an ins Design von Serveranwendungen – und im Prinzip auch von Webanwendungen einschließlich der unter Windows Azure ausgeführten. Die protokollierten Informationen sollten aussagefähig genug sein, um praktisch alles zu beschreiben, was innerhalb der einzelnen Komponenten abläuft. Aber genau wie die Ausgabeanweisungen meiner ersten Programme kann auch die Protokollierung sehr lange Ausgaben generieren. Ein gutes Design für Protokollierung und Ablaufverfolgung beinhaltet daher Möglichkeiten, Art und Menge der zu den einzelnen Komponenten protokollierten Daten festzulegen. So können IT-Personal und Entwickler ihre Aufmerksamkeit auf eine bestimmte problematische Komponente konzentrieren, vielleicht sogar auf einem bestimmten Computer, und eine Fülle an Informationen darüber erfassen, was genau in dieser Komponente vor sich geht – ohne dabei ein Protokoll voll zahlreicher unnötiger Informationen zu generieren, die sowieso nur ablenken und die Anwendung womöglich auch noch signifikant verlangsamen würden.

Darüber hinaus sind Serveranwendungen in der Regel verteilte Anwendungen, sodass Informationen von mehreren Computern (womöglich auch noch in unterschiedlichen Anwendungsrollen) erfasst und aggregiert werden müssen, bis sich ein vollständiges Bild der Vorgänge beim Auftreten eines bestimmten Problems ergibt. Daher muss eine Möglichkeit geschaffen werden, einen Transaktionsthread über alle Computer hinweg zu identifizieren, damit im Nachhinein eine Aggregation erfolgen kann.

Die Protokollierung in Windows Azure wurde im Zuge der Community Technology Preview-Versionen (CTP) immer weiter entwickelt. Am Anfang leistete die Protokollierung nicht wesentlich mehr als eine Ausgabeanweisung und wurde als Text im Windows Azure-Tabellenspeicher erfasst. Ab Version PDC09 begann Windows Azure, weitaus mehr Protokollierungsfunktionen und eine verbesserte Infrastruktur für die Ablaufverfolgung zu bieten, basierend auf dem ETW-Framework (Event Tracing for Windows, Ereignisablaufverfolgung für Windows).

Das ETW-Framework wird in ASP.NET durch Klassen im System.Diagnostics-Namespace unterstützt. Der Microsoft.WindowsAzure.Diagnostics-Namespace, der von standardmäßigen System.Diagnostics-Klassen erbt und diese erweitert, ermöglicht die Nutzung von System.Diagnostics als Protokollierungsframework in der Windows Azure-Umgebung. Abbildung 1 zeigt, wie ETW von Windows Azure Diagnostics implementiert wird.

Figure 1 High-Level Overview of Windows Azure Diagnostics
Abbildung 1 Überblick über Windows Azure Diagnostics

ETW stellt ein Modell zur Protokollierung von Code in einem oder mehreren TraceSources bereit. Die für die einzelnen Quellen zulässigen Protokollierungsstufen werden über einen SourceSwitch gesteuert. Die Quellen wiederum sind mit einem oder mehreren Consumern verbunden, die die protokollierten Informationen in unterschiedlicher Weise speichern.

Windows Azure stellt einen Standardconsumer oder -listener zum Speichern der im Tabellenspeicher oder Blob-Speicher von Windows Azure generierten Protokollierungsinformationen bereit. Sie können auch einen eigenen Consumer schreiben, wenn Sie mit den Ereignisdaten etwas anderes vorhaben. Oder Sie verwenden einen handelsüblichen Consumer, obwohl dieser unter Umständen erst für die Nutzung in der Windows Azure-Umgebung angepasst werden muss.

Das ETW-Framework ordnet jedem Ereignis einen TraceEventType zu, wie in Abbildung 2 zu sehen. Die Schweregrade in den ersten fünf Zeilen werden am häufigsten verwendet und spiegeln die relative Wichtigkeit der Ablaufverfolgungsausgabe wider. Beachten Sie, dass die Typen „Suspend“, „Resume“ und „Transfer“ von der Windows Communication Foundation (WCF) verwendet werden.

Abbildung 2 Typen von Ablaufverfolgungsereignissen

TraceEventType Wert Bedeutung
Critical 0x0001 Schwerwiegender Fehler oder Anwendungsabsturz
Error 0x0002 Behebbarer Fehler
Warning 0x0004 Nicht kritisches Problem – kann auf kommende, schwerwiegendere Probleme hinweisen
Information 0x0008 Informationsmeldung
Verbose 0x0010 Debugablaufverfolgung (z. B. detaillierte Informationen zum Ausführungsablauf, Parameter usw.)
Start 0x0100 Starten eines logischen Vorgangs
Stop 0x0200 Beenden eines logischen Vorgangs
Suspend 0x0400 Anhalten eines logischen Vorgangs
Resume 0x0800 Wiederaufnehmen eines logischen Vorgangs
Transfer 0x1000 Übergang zu einer neuen Aktivität

Wenn Sie ausschließlich auf der Suche nach schwerwiegenden Problemen sind, sollten Sie nur Ereignisse des Typs „Critical“ und eventuell „Error“ erfassen. Wenn Sie möglichst viele Informationen über sämtliche Vorgänge wünschen, erfassen Sie alle Ereignistypen oberhalb von „Verbose“.

Ihre Protokollierungsstrategie sollte sich durch eine konsistente Verwendung der Ereignistypen sowie umfangreiche Protokolleinträge für die Werte weiter unten in der Hierarchie auszeichnen. Es sollte möglich sein, den Ausführungsablauf der Anwendung praktisch vollständig nachzuverfolgen, wenn die Protokollierung aller angegebenen Werte in der Anwendung aktiviert ist. Dies kann bei der Behebung von Fehlern oder Problemen in der Produktion äußerst hilfreich sein.

Man kann Listener, Quellen und Schalter anbinden, um programmtechnisch unterschiedliche Ausgabestufen zu ermöglichen, aber normalerweise realisiert man dies über Konfigurationsdateien. Sie können die Ausgabe in app.config (für Windows Azure Worker-Rollen) oder web.config (für Windows Azure Web-Rollen) konfigurieren. Aber – wie ich weiter unten in diesem Artikel noch erläutern werde – können Sie die Protokollierungs- und Ablaufverfolgungsoptionen auch während der Ausführung des Windows Azure-Dienstes anpassen, was Sie über ServiceConfiguration.cscfg realisieren können. Sie brauchen dann weder Updates für den ausgeführten Code bereitzustellen noch etwa gar den Dienst zu stoppen. Darüber hinaus macht Windows Azure eine RESTful-Schnittstelle verfügbar, was eine Remotesteuerung für einige der Protokollierungsoptionen ermöglicht. Windows PowerShell kann die RESTful-Schnittstelle nutzen.

Protokollierung, Ablaufverfolgung und Debugausgaben

In manchen Zusammenhängen sind die Begriffe „Protokollierung“, „Ablaufverfolgung“ und „Debugausgabe“ austauschbar. In diesem Artikel möchte ich aber zwischen vier verschiedenen Typen so genannter Diagnoseausgaben im Code unterscheiden. Dies sind – in der Reihenfolge von der ausführlichsten zur am wenigsten ausführlichen – Folgende.

  • Debugausgabe: Diese Informationen sind nur in den Debugbuilds der Anwendung enthalten und werden bei der Kompilierung aus den Releasebuilds ausgeschlossen (je nachdem, ob das DEBUG-Präprozessorsymbol bei der Kompilierung definiert wird, das Visual Studio standardmäßig ausschließlich in Debugbuilds definiert). In der Regel enthalten Debugausgaben Elemente wie Asserts, anhand derer man Fälle finden kann, in denen der Code nicht mit den erwarteten Vorbedingungen übereinstimmt, was zu Fehlern führen oder sogar Speicherabbilder von Datenstrukturen generieren kann. Diese Elemente sind beim Debuggen und Testen insbesondere für das Debuggen von Algorithmen nützlich.
  • Ablaufverfolgung: Die entsprechenden Anweisungen sollen die Nachverfolgung der Ablaufsteuerung und des Programmstatus während der Ausführung ermöglichen. Wenn Sie einen Debugger ausführen, können Sie den Code Schritt für Schritt nachverfolgen und die Werte von Schlüsselvariablen im Überwachungsfenster überprüfen. Ablaufverfolgungsanweisungen dienen dazu, diesen Effekt in Fällen zu replizieren, in denen kein Debugger angehängt werden kann. Im Idealfall sollten Sie ausreichend Kontext bereitstellen, sodass man erkennen kann, welchen Weg das Programm an den einzelnen Kontrollpunkten der Anwendung einschlägt, und den Code nachverfolgen kann, indem man die Ablaufverfolgungsanweisungen liest. Eine Ablaufverfolgung ist möglich, wenn das TRACE-Präprozessorsymbol bei der Kompilierung definiert wird, und zwar sowohl im Release- wie auch im Debugbuild. Standardmäßig definiert Visual Studio TRACE im Debug- und im Releasebuild, aber das können Sie selbstverständlich ändern.
  • Ereignisprotokollierung: Mit diesen Anweisungen sollen wichtige Ereignisse im Ablauf der Anwendung erfasst werden – beispielsweise der Start einer Transaktion oder die Hinzufügung eines Elements in eine Datenbank. Die Ereignisprotokollierung unterscheidet sich insofern von der Ablaufverfolgung, als sie anstelle detaillierter Ablaufsteuerungs- wichtige Statusereignisse erfasst.
  • Fehlerprotokollierung: Dies ist ein Sonderfall der Ereignisprotokollierung: Ausnahme- bzw. potenziell gefährliche Situationen werden erfasst. Als Beispiele kommen erfasste Ausnahmen aller Art infrage – kein Zugriff auf eine Ressource auf einem anderen Computer, obwohl dieser Zugriff eigentlich möglich sein sollte (was die Anwendung zwar mühelos bewältigt, aber trotzdem vermerken sollte), oder Fehler, die von APIs zurückgegeben werden, von denen eigentlich keine Fehler zu erwarten wären.

Die Fehlerprotokollierung ist auch für IT-Mitarbeiter hilfreich, wenn zwar noch keine Fehler auftreten, aber Anzeichen vorliegen, dass bald welche auftreten werden – beispielsweise bei Quoten, die sich dem Höchstwert nähern, oder Transaktionen, die zwar erfolgreich ausgeführt werden, aber mehr Zeit brauchen als üblich. Diese Art der Ereignisprotokollierung kann die IT-Mitarbeiter also bei der proaktiven Problembehandlung noch im Vorfeld der eigentlichen Probleme unterstützen, sodass Ausfallzeiten bei der Anwendung vermieden werden können.

Die meisten guten Entwickler haben es sich längst zur Gewohnheit gemacht, Debugausgaben in ihre Anwendungen mit aufzunehmen, um Probleme während der Entwicklung zu diagnostizieren, und viele haben auch schon irgendeine Lösung für die Fehlerprotokollierung konzipiert.

Auf jeden Fall sollten Sie sich aber nicht nur um die Debugausgaben- und Fehlerprotokollierungsoptionen kümmern, sondern auch eine robuste Strategie für die Ablaufverfolgung und Ereignisprotokollierung ausarbeiten, denn dies kann bei der Diagnose von Problemen helfen, die ausschließlich bei sehr hoher Auslastung in Produktionsumgebungen auftreten.

Ebenso sollten Sie überlegen, ob Sie nicht vieles der Ablaufverfolgung statt der Debugausgabe zuordnen sollten, da erstere nicht nur im Debug-, sondern auch im Releasebuild verfügbar ist. Denn eine Anwendung, die in der Produktion fehlerhaft ausgeführt wird, liegt normalerweise im Releasebuild vor. Sind die Ablaufverfolgungsanweisungen vorhanden, aber deaktiviert (Erläuterungen dazu folgen später), können Sie diese selektiv aktivieren und auf diese Weise im Releasebuild sehr umfangreiche, mit Debugausgaben vergleichbare Ausgaben generieren, was bei der Diagnose von Problemen hilfreich ist.

Ablaufverfolgung und Protokollierung in Windows Azure

Die Windows Azure-Protokollierung ist einsatzfertig – sie ist ein Teil des Windows Azure-SDK. Die Verwendung eines Protokollierungsframeworks wie Logger.NET, Enterprise Library, log4net oder Ukadc.Diagnostics hat einige Vorteile. Die Protokollierungsmeldungen erhalten mehr Struktur und darüber hinaus stellt das Framework einige Konfigurationsmöglichkeiten bereit, wie schon erwähnt. Die meisten Frameworks sind jedoch nicht für eine Windows Azure-Umgebung optimiert und einige sind weit mehr als nur ein Protokollierungsframework.

Für den Beispielcode in diesem Artikel habe ich nur die standardmäßigen Protokollierungs- und Ablaufverfolgungs-APIs von Windows Azure verwendet, lediglich ergänzt durch einen dünne Schicht, die die dynamische Konfiguration bereitstellt. Wahrscheinlich wäre es nützlich, diese Struktur durch einige Hilfsklassen und ein Framework für Ihre Protokollierungs- und Ablaufverfolgungsstrategie zu ergänzen. Oder achten Sie auf weitere Frameworks mit Versionen für Windows Azure.

Wenn Sie in Windows Azure mit Visual Studio einen neuen Dienst erstellen, ist dieser bereits auf eine grundlegende Protokollierung ausgelegt. Im von den Windows Azure-Vorlagen generierten Standardcode für Worker- und Web-Rollen ist der Diagnoselistener schon konfiguriert und aktiviert.

Um eine einfache Protokollierung in einem Windows Azure-Dienst zu aktivieren, starten Sie ein neues Projekt in Visual Studio. Verwenden Sie dazu die Cloud-Dienstvorlage (Visual C#) von Windows Azure. Benennen Sie das Projekt. In meinem Beispiel lautet der Name „MSDNSampleLoggingService“. Klicken Sie auf OK.

Der Assistent für das neue Cloud-Dienst-Projekt wird ausgeführt. Fügen Sie im Assistenten eine Worker- und eine Web-Rolle zum Projekt hinzu. Benennen Sie die Worker-Rolle in „LoggingWorkerRole“ und die Web-Rolle in „LoggingWebRole“ um und klicken Sie auf OK. Daraufhin erstellt Visual Studio das Projekt.

Jetzt können Sie den generierten Code untersuchen. Sehen Sie sich die Datei „app.config“ im Projekt LoggingWorkerRole an. Beachten Sie dabei den folgenden Code:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace autoflush="false" indentsize="4">
      <listeners>
        <add name="AzureDiagnostics" type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Mi-crosoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>

Dieser verknüpft den standardmäßigen Windows Azure-Diagnoselistener mit Ihrem Code. Das heißt, die gesamte Protokollierung und Ablaufverfolgung, die Sie für die Worker-Rolle ausführen, wird zum Windows Azure-Listener (DiagnosticMonitorTraceListener) umgeleitet, solange Sie dies nicht ändern. In der Datei „web.config“ für die Web-Rolle, die Sie für diesen Dienst erstellt haben, finden Sie einen ähnlichen Eintrag.

Wenn Sie sich die Datei „WorkerRole.cs“ im Worker-Rollenprojekt ansehen, sehen Sie folgende Zeile in der OnStart-Methode:

DiagnosticMonitor.Start("DiagnosticsConnectionString");

Und in der Run-Methode sehen Sie einen Aufruf für die Ablaufverfolgung:

// This is a sample worker implementation. Replace with your logic.
Trace.WriteLine("LoggingWorkerRole entry point called", "Information");

Darüber hinaus finden Sie in der Datei „ServiceConfiguration.cscfg“ im Stammverzeichnis des Dienstes folgende Zeile für die Worker- und die Web-Rolle:

<Setting name="DiagnosticsConnectionString" 
         value="UseDevelopmentStorage=true" />

Diese teilt dem Windows Azure-Listener mit, welches Speicherkonto er für die Speicherung der Protokollierungs- und Ablaufverfolgungsinformationen verwenden soll. In diesem Fall werden die Protokollierungsinformationen im Entwicklungsspeicher auf dem lokalen Computer gespeichert. Wechselt man stattdessen zu einem Windows Azure-Cloud-Speicherkonto, können die Protokolle in den Cloud-Speicher geschrieben werden. Im Folgenden finden Sie ein Beispiel für das Format dafür aus dem Beispielcode in diesem Artikel:

<Setting name="DiagnosticsConnectionString" 
  value="DefaultEndpointsProtocol=https;AccountName=Xxxxxx;AccountKey=Yyyyyy" />

Die Werte AccountName und AccountKey müssen Sie gemäß Ihrem Azure-Konto und Azure-Schlüssel anpassen. Sie erhalten diese Informationen über das Speicherkontoportal für Ihren Dienst unter windows.azure.com. AccountName ist der erste Teil der URL für die Endpunkte des Tabellen- und Blob-Speichers (der Teil vor „.table.core.windows.net“). AccountKey ist der Base64-codierte primäre Zugriffsschlüssel für Ihr Speicherkonto.

Für die Diagnose wird also ein eigenes Speicherkonto verwendet. Daraus folgt, dass Sie Ihre Diagnoseinformationen getrennt von den anderen Anwendungsdaten speichern können. Dazu brauchen Sie lediglich ein eigenes Speicherkonto einzurichten, in dem Sie auf der Portalseite auf „New Service“ klicken, „Storage Account“ auswählen und dann einen Namen dafür eingeben (beispielsweise MyAppLogs). Sie können auch eine Zugehörigkeitsgruppe einrichten, sodass sich der Speicher für Ihre Protokolle in der gleichen Region wie der Dienst befindet.

Nach diesem kurzen Blick auf den Ablaufverfolgungscode in Windows Azure-Diensten können Sie jetzt das einfache Web-Rollenprojekt ausführen, das Sie erstellt haben. Beachten Sie, dass der Standardlistener von Windows Azure die Ausgabe auch ins Ausgabefenster von Visual Studio für Debugbuilds umleitet. Das heißt, die OnStart-Meldung wird im Debugfenster angezeigt:

Information: LoggingWorkerRole entry point called

Und wenn Sie sich die Protokolle ansehen wollen, nachdem der Dienst ausgeführt wurde? Standardmäßig speichert Windows Azure die Protokolle nicht. Sie können die Protokolle aber speichern lassen, indem Sie ein paar Codezeilen in die OnStart-Methode der Rolle einfügen:

TimeSpan tsOneMinute = TimeSpan.FromMinutes(1);
DiagnosticMonitorConfiguration dmc =
DiagnosticMonitor.GetDefaultInitialConfiguration();

// Transfer logs to storage every minute
dmc.Logs.ScheduledTransferPeriod = tsOneMinute;
// Transfer verbose, critical, etc. logs
dmc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;    
// Start up the diagnostic manager with the given configuration
DiagnosticMonitor.Start("DiagnosticsConnectionString", dmc);

Wenn Sie diesen Code zu WorkerRole.cs hinzufügen und diese neue Version ausführen, überträgt Windows Azure die Protokolle einmal pro Minute in den Entwicklungsspeicher. Die Protokolle können auch bedarfsgesteuert (der Code in admin.aspx.cs in meiner Beispielanwendung zeigt das Vorgehen dazu) oder mithilfe von Windows PowerShell-Befehlen übertragen werden, die weiter unten in diesem Artikel noch erläutert werden. Denken Sie daran: Wenn Sie Protokolle in den Speicher übertragen, wird Ihnen der Speicherplatz in Rechnung gestellt, und es ist Ihre Aufgabe, die Informationen zu löschen, wenn sie nicht mehr gebraucht werden.

Wenn die Protokolle erst im Windows Azure-Speicher bereitstehen, benötigen Sie ein Tool zum Anzeigen der Speichertabellen, damit Sie die Protokolle auch lesen können. Ich habe dazu Cloud Storage Studio von Cerebrata (cerebrata.com) verwendet. Zum Anzeigen von Cloud-Speichern und Diagnosen hat Cerebrata mittlerweile ein Tool namens Azure Diagnostics Manager herausgebracht, und darüber hinaus stehen auf CodePlex (codeplex.com) kostenlose Tools zur Verfügung. Die Protokolle werden in eine Tabelle mit der Bezeichnung WADLogsTable gestellt, die Sie in Abbildung 3 sehen.

Figure 3 Logs Persisted in Development Storage
Abbildung 3 Im Entwicklungsspeicher gespeicherte Protokolle

Bei einem Blick auf die Protokolle im Speicher werden Ihnen einige Dinge auffallen. Erstens verknüpft Windows Azure automatisch einige Informationen mit jedem protokollierten Ereignis: einen Timestamp, einen Zähler für die Anzahl der Ticks (der mit seiner Granularität im 100-Nanosekundenbereich eine besonders detaillierte Zeitzählung ermöglicht) sowie Informationen über Bereitstellung, Rolle und Rolleninstanz. So können Sie Protokolle bei Bedarf auf bestimmte Instanzen eingrenzen.

Zweitens wird jedes Ereignis mit einer Stufe (Level) und einer Ereignis-ID (EventId) verknüpft. Die Stufe entspricht den Werten in Abbildung 2. Ablaufverfolgungsereignisse, die unter „Information“ protokolliert wurden, haben demnach die Stufe 4. Ereignisse, die unter „Error“ protokolliert wurden, haben die Stufe 2. Generische Ereignisse, die über Trace.WriteLine gesendet wurden (wie der Standardcode aus der Vorlage) haben Stufe 5 (Verbose).

Die EventId ist ein von Ihnen angegebener Wert. Der zuvor gezeigte Trace.WriteLine-Aufruf lässt diese Angabe jedoch nicht zu. Zur Übergabe der EventId sind also andere Ablaufverfolgungsmethoden erforderlich.

Selektive Aktivierung von Ablaufverfolgung und Protokollierung

Eine typische Anwendung besteht aus mehreren logischen Komponenten. Denken Sie zum Beispiel an eine Datenbankkomponente für das Datenmodell im Windows Azure-Speicher. Oder denken Sie an eine Web-Rolle, die aus einer administrativen und einer Benutzerkomponente besteht, die ihrerseits aus logischen Komponenten bestehen kann, je nach den Anforderungen der Anwendung.

Sie können die Protokollierungs- und Ablaufverfolgungsoptionen – also welche Art der Protokollierung auf welcher Detailstufe aktiviert wird – mit diesen Komponenten verknüpfen. Auf diese Weise können Sie eine selektive Ablaufverfolgung für genau die Komponenten realisieren, für die eine Ablaufverfolgung nötig ist. So vermeiden Sie, dass viele unnütze Daten generiert werden.

Der Schlüssel für diese Strategie liegt darin, die Ablaufverfolgung nicht direkt aufzurufen, sondern dafür mehrere TraceSource-Instanzen zu verwenden, in der Regel eine pro Namespace. Zu einer TraceSource gehört ein SourceSwitch, der steuert, ob die TraceSource aktiviert ist und welche Detailstufe bei der Ausgabe gewünscht ist. Dabei müssen Sie bedenken, dass die SourceSwitch-Werte nicht bei der Kompilierung, sondern zur Laufzeit festgelegt werden. Infolgedessen können Sie Diagnoseausgaben aus verschiedenen Teilen Ihrer Anwendung aktivieren oder deaktivieren, ohne sie neu kompilieren oder gar in einer anderen Version erneut bereitstellen zu müssen.

WorkerDiagnostics.cs und WebDiagnostics.cs enthalten die Konfiguration der TraceSources und SourceSwitches im Beispielcode. Hier ein Auszug:

// Trace sources
public TraceSource ConfigTrace;
public TraceSource WorkerTrace;
// Add additional sources here

// Corresponding trace switches to control 
// level of output for each source
public SourceSwitch ConfigTraceSwitch { get; set; }
public SourceSwitch WorkerTraceSwitch { get; set; }
// Add additional switches 1:1 with trace sources here

In der Konfigurationsdatei zu Ihrer Rolle verknüpfen Sie diese mit Listenern, wie in Abbildung 4 zu sehen. Dabei wird zunächst der standardmäßige Windows Azure-Diagnoselistener als freigegebener Listener eingerichtet, sodass in den <sources>-Elementen darauf verwiesen werden kann. Dann werden zwei Quellen konfiguriert: eine WorkerTrace-Quelle und eine ConfigTrace-Quelle. Darüber hinaus werden die entsprechenden Schalter eingerichtet, sodass man die Detailstufe der Ausgabe festlegen kann. ConfigTrace erzeugt die ausführlichste Ausgabe, WorkerTrace berücksichtigt nur Fehler.

Abbildung 4 Konfigurieren von TraceSources und Listenern

<configuration>
  <system.diagnostics>
    <sharedListeners>
      <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
        name="AzureDiagnostics">
        <filter type="" />
      </add>
    </sharedListeners>
    <sources>
      <source name="ConfigTrace">
        <listeners>
          <add name="AzureDiagnostics" />
        </listeners>
      </source>
      <source name="WorkerTrace">
        <listeners>
          <add name="AzureDiagnostics" />
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="ConfigTrace" value="Verbose"/>
      <add name="WorkerTrace" value="Error"/>
    </switches>
    <trace>
      <listeners>
        <add name="AzureDiagnostics" />
      </listeners>
    </trace>
  </system.diagnostics>
</configuration>

Sie müssen den Schaltern nicht den gleichen Namen geben wie den Quellen, aber es dürfte Ihnen die Arbeit erleichtern. Sind die Namen nicht gleich, fügen Sie ein switchName-Attribut zum Quellelement hinzu, das den Namen des Schalters angibt, der die Ausgabe für die betreffende Quelle steuert. So können Sie einen einzigen Schalter für mehrere TraceSources nutzen. Beachten Sie dabei, dass bei den Namen von TraceSources und Schaltern zwischen Groß- und Kleinschreibung unterschieden wird und Sie bei der Übergabe an den Konstruktor in Ihrem Code genau dieselbe Groß- und Kleinschreibung verwenden müssen.

Sie können den Schalter auch ganz umgehen, indem Sie einfach ein switchValue-Attribut zum Quellelement hinzufügen, das den gewünschten Wert für den Schalter zu dieser Quelle angibt. Die verwendeten Schalterwerte aus der Konfigurationsdatei werden als einer der in Abbildung 5 definierten SourceLevels analysiert. Die Abbildung zeigt darüber hinaus, wie der an TraceSource-Aufrufe übergebene TraceEventType mit dem SourceLevel interagiert, das für die Quelle festgelegt wurde und bestimmt, welche Ereignistypen weitergeleitet werden sollen.

Abbildung 5 Ablaufverfolgung mit SourceLevels und TraceEventType

Figure 5 Tracing Source Levels and TraceEventType

Beachten Sie bitte, dass es sich beim SourceLevel lediglich um eine Bitmaske handelt, die zur Laufzeit über den Operator AND mit dem TraceEventType verknüpft wird, um festzulegen, ob ein Ereignis protokolliert werden soll oder nicht. Um Kombinationen wie eine Ablaufverfolgung für Warnungen und Aktivitäten zu erzielen, geben Sie den numerischen Wert für das Bitfeld als Schalterwert an, statt die abgebildeten symbolischen Werte zu verwenden.

Außer Schaltern kann ein Listener auch einen TraceFilter haben, mit dem sich eine komplexere Laufzeitlogik realisieren lässt als lediglich die Entscheidung, ob eine bestimmte Meldung protokolliert werden soll oder nicht. Eine Erläuterung, wie man einen angepassten TraceFilter schreibt, würde den Rahmen dieses Artikels sprengen, aber in der Dokumentation zum Ukadc.Diagnostics-Projekt auf CodePlex (ukadcdiagnostics.codeplex.com/wikipage?title=LoggingPrimer) finden Sie ein nützliches Beispiel.

Ändern der zu protokollierenden Ereignisse zur Laufzeit

Bisher ging es in diesem Artikel um die Standardfunktionsweise der ASP.NET-Ablaufverfolgung, die sich bestens für unter Windows Azure bereitgestellte Dienste eignet. Zu Problemen kommt es, wenn Sie die Schalterwerte zur Laufzeit ändern möchten, denn Windows Azure lässt einen Austausch der Datei web.config oder app.config ohne erneute Bereitstellung des Dienstes nicht zu. Die generische ASP.NET-Lösung für dieses Problem besteht darin, die Konfigurationswerte über den WebConfiguationManager zu ändern, was Windows Azure für in der Cloud bereitgestellte Dienste zurzeit aber ebenfalls nicht zulässt.

Die Lösung besteht in der Spiegelung der Werte für diese Schalter in der Datei ServiceConfiguration.cscfg, denn Sie haben in Windows Azure die Möglichkeit, diese Datei über das Entwicklungsportal zu bearbeiten (oder eine neue hochzuladen), während der Dienst ausgeführt wird. Dazu müssen Sie allerdings etwas zusätzlichen Code schreiben.

Der System.Diagnostics-Standardcode kennt Einstellungen ausschließlich in app.config oder web.config, aber die Rollen werden während der Laufzeit mittels der Ereignisse RoleEnvironmentChanging und RoleEnvironmentChanged über Änderungen in ServiceConfiguration.cscfg benachrichtigt. Sie können dann entscheiden, ob Sie die Rolle neu starten oder einfach einen Konfigurationswert aktualisieren. Das zweite Verfahren eignet sich für Ablaufverfolgungsschalter. Durch einen Neustart der Rolle können intermittierende Probleme unter Umständen behoben werden. Der Beispielcode für diesen Artikel zeigt, wie sich das durch Hinzufügen von einigen Werten in die Datei ServiceConfiguration.cscfg (wobei auch die Datei ServiceDefinition.csdef bearbeitet werden muss, die das Schema bereitstellt) sowie durch Einfügen von etwas Code in die Rollen realisieren lässt.

Testen in Development Fabric

Wie testet man in Development Fabric, wo das Windows Azure-Portal nicht wie bei in der Cloud bereitgestellten Diensten zum Bearbeiten der Konfiguration zur Verfügung steht? Ermitteln Sie zunächst die Bereitstellungs-ID, die Windows Azure dem ausgeführten Development Fabric-Dienst zugewiesen hat. Diese ID können Sie anzeigen lassen, indem Sie die Benutzeroberfläche von Development Fabric über die Taskleiste aufrufen, während der Dienst ausgeführt wird. Die ID ist eine Nummer wie zum Beispiel 177.

  1. Wechseln Sie in das Verzeichnis, in das Sie die Binärdateien Ihres Dienstes zum Kompilieren hineingestellt haben (in der Regel das Unterverzeichnis \bin\debug oder \bin\release unter dem Verzeichnis mit dem Dienstcode). Dort finden Sie eine Kopie der Datei ServiceConfiguration.cscfg, die beim Kompilieren der Anwendung erstellt wurde.
  2. Bearbeiten Sie diese Datei dann mit einem Texteditor so, dass der gewünschte Ablaufverfolgungsschalter verwendet wird. Ändern Sie im Beispielscode zum Beispiel „Off“ für „WebTrace“ in „Verbose“.
  3. Führen Sie dann in einer Windows Azure SDK-Eingabeaufforderung (Start | Alle Programme | Windows Azure SDK v1.1 | Windows Azure SDK Command Prompt) folgenden Befehl aus:
csrun /update:NNN;ServiceConfiguration.cscfg

NNN ist dabei die Bereitstellungs-ID von Windows Azure, die Sie zuvor ermittelt hatten. Auf diese Weise bewirken Sie in Development Fabric das Gleiche, was Sie durch Klicken auf die Konfigurationsschaltfläche im Windows Azure-Entwicklungsportal für in der Cloud bereitgestellte Dienste erzielen – die Konfigurationseinstellungen werden aktualisiert und die Ereignisse ausgelöst.

Weitere Diagnoseinformationen

In diesem Artikel ging es bisher in erster Linie um Tabellendaten, die die Anwendung mittels System.Diagnostics protokollieren kann. Windows Azure kann unter anderem aber auch IIS-Protokolle und Ablaufverfolgungsprotokolle für Anforderungsfehler (Failed Request Tracing, früher „Failed Request Buffering“ oder „FREB“ genannt) erfassen. Einige davon werden in den Windows Azure-Blob-Speicher gestellt, einige in den Windows Azure-Tabellenspeicher. Abbildung 6 enthält eine Liste der verfügbaren Protokolle und ihrer Speicherorte. Beachten Sie, dass Sie für Protokolle, die nicht standardmäßig aktiviert sind, in der Regel die Datei web.config oder app.config für Windows Azure ändern müssen, damit die entsprechenden Protokolle generiert werden. Am Beispiel eines Protokolls, das nicht standardmäßig generiert wird, soll die Vorgehensweise verdeutlicht werden.  

Abbildung 6 Standardmäßige Windows Azure-Protokollierungsoptionen

Protokolltyp Windows Azure-Speicherformat Standardmäßig erfasst? Hinweise
Über Code generierte Windows Azure-Protokolle Tabelle 4 Ablaufverfolgungslistener müssen, wie im Beispielcode gezeigt, in die Datei web.config oder app.config eingefügt werden. Die Speicherung erfolgt in WADLogsTable.
IIS 7.0-Protokolle Blob 4 Nur Web-Rollen. Die Speicherung erfolgt in einem Blob-Container im Pfad wad-iis-logfiles\<Bereitstellungs-ID>\<Web-Rollenname>\<Rolleninstanz>\W3SVC1.
Protokolle zur Windows-Diagnoseinfrastruktur Tabelle 4 Informationen über den Diagnosedienst selbst. Die Speicherung erfolgt in WADDiagnosticInfrastructureLogsTable.
Protokolle für Anforderungsfehler Blob   Nur Web-Rollen. Aktivierbar durch Einstellen der Ablaufverfolgungsoptionen unter den system.WebServer-Einstellungen in web.config. Die Speicherung erfolgt in einem Blob-Container im Pfad wad-iis-failedreqlogfiles\<Bereitstellungs-ID>\<Web-Rollenname>\<Rolleninstanz>\W3SVC1.
Windows-Ereignisprotokolle Tabelle   Aktivierbar durch Ändern von DiagnosticMonitor Configuration.WindowsEventLog im Rahmen der Erstkonfiguration. Die Speicherung erfolgt in WADWindowsEventLogsTable. Im Blog von Steve Marx (blog.smarx.com/posts/capturing-filtered-windows-events-with-windows-azure-diagnostics) wird die Vorgehensweise erläutert.
Leistungsindikatoren Tabelle   Aktivierbar durch Ändern von DiagnosticMonitor Configuration.PerformanceCounters. Die Speicherung erfolgt in WADPerformanceCountersTable. In der Worker-Rolle im Beispielcode wird ein Leistungsindikator eingerichtet.
Absturzabbilder Blob   Aktivierbar durch Aufrufen von CrashDumps.EnableCollection. Die Speicherung erfolgt in einem Blob-Container im Pfad wad-crash-dumps. Da ASP.NET die meisten Ausnahmen behandelt, ist dieses Protokoll in der Regel nur für eine Worker-Rolle sinnvoll.
Benutzerdefinierte Fehlerprotokolle Blob   Würden den Rahmen dieses Artikels sprengen, aber ein nützliches Beispiel zur Vorgehensweise finden Sie im Blog von Neil Mackenzie (nmackenzie.spaces.live.com/blog/cns!B863FF075995D18A!537.entry).

Betrachten wir als Beispiel die Aktivierung der FREB-Protokollierung aus IIS heraus für die Web-Rolle. Um das Beispiel in Aktion zu sehen, laden Sie den mit diesem Artikel bereitgestellten Beispielcode für MSDNSampleLoggingService herunter. Öffnen Sie web.config für LoggingWebRole und suchen Sie den Abschnitt <system.webServer>. Beachten Sie, dass die in Abbildung 7 enthaltenen Zeilen zur Standardversion der Datei web.config in Windows Azure hinzugefügt wurden. Diese bewirken eine Fehlerprotokollierung bei allen Anforderungen, die länger als 15 Sekunden dauern oder einen Statuscode zwischen 400 und 599 (Element failureDefinitions) aufweisen.

Abbildung 7 Protokollierung von Anforderungsfehlern für LoggingWebRole

<tracing>
  <traceFailedRequests>
    <add path="*">
      <traceAreas>
        <add provider="ASP" verbosity="Verbose" />
        <add provider="ASPNET" 
             areas="Infrastructure,Module,Page,AppServices"
             verbosity="Verbose" />
        <add provider="ISAPI Extension" verbosity="Verbose" />
        <add provider="WWW Server"
             areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module" 
             verbosity="Verbose" />
      </traceAreas>
      <failureDefinitions timeTaken="00:00:15" statusCodes="400-599" />
    </add>
  </traceFailedRequests>
</tracing>

Wenn Sie die Datei about.aspx.cs im LoggingWebRole-Projekt öffnen, sehen Sie, dass ich in die PageLoad-Methode eine willkürliche Verzögerung von 18 Sekunden eingefügt habe, und zwar mit folgender Codezeile:

System.Threading.Thread.Sleep(18000);

Aufgrund der zuvor festgelegten Definition wird das Laden dieser Seite also immer als fehlgeschlagene Anforderung interpretiert.

Um das FREB-Protokoll anzuzeigen, kompilieren Sie die Anwendung neu und stellen Sie sie in Development Fabric bereit. Suchen Sie dann den Development Fabric-Controller im Infobereich der Taskleiste. Dazu müssen Sie eventuell auf die Schaltfläche „Ausgeblendete Symbole einblenden“ in der Taskleiste klicken, da er oft inaktiv und daher ausgeblendet ist. Klicken Sie mit der rechten Maustaste darauf und wählen Sie „Show Development Fabric UI“. Während die Anwendung ausgeführt wird, werden nun Informationen zur Anwendung angezeigt.

Erweitern Sie die Web-Rolle und klicken Sie mit der rechten Maustaste auf die Rolleninstanz (0). Öffnen Sie mit „Open local store“ den Ordner auf dem lokalen Computer, in dem die Protokolle gespeichert werden (siehe Abbildung 8). Innerhalb dieses Ordners befinden sich die Protokolle im Ordner \directory\DiagnosticStore, weil die Web-Rolle im Beispielcode so konfiguriert ist, dass Diagnoseinformationen im Entwicklungsspeicher gespeichert werden. Wenn Sie stattdessen für DiagnosticsConnectionString ein Cloud-Speicherkonto festlegen, werden die persistenten Protokolle in den Blob-Speicher zu diesem Speicherkonto gestellt. Mit Cloud Storage Studio können Sie die Blob-Container anzeigen lassen, um die Protokolle darin zu sehen.

Figure 8 Opening Logs Saved to Local Development Fabric Storage
Abbildung 8 Öffnen von Protokollen im lokalen Development Fabric-Speicher

Diagnoseverwaltung für einen ausgeführten Dienst

Zwar kann man seinen Code mit umfangreichen Protokollierungsfunktionen versehen, aber in der Regel sollen diese Protokollierungsinformationen nicht dauerhaft im Speicher verbleiben, während der Dienst in der Produktion ausgeführt wird. So ist es eventuell sinnvoll, nur Fehler- und kritische Informationen („Error“ and „Critical“) in die persistenten Protokolle aufzunehmen und detailliertere Informationen (protokolliert unter „Verbose“ oder „Information“) zu unterdrücken.

Aber was, wenn ein Problem auftritt? Es ist nicht unbedingt sinnvoll, erneut eine Neuversion des Dienstes bereitzustellen, da das Problem dann möglicherweise verschwindet – Sie wissen zweifellos, dass sich schwer fassbare Probleme durch einen Neustart sehr wirkungsvoll zum Verschwinden bringen lassen.

Viel effektiver ist es, stattdessen mehr Informationen in die Protokolltabellen oder den Blob-Speicher aufzunehmen und die Ausführung des fehlerhaften Codes fortzusetzen. Auf diese Weise haben Sie bessere Chancen, die Ursache eines Problems in Ihrer Anwendung zu ermitteln, während sie in ihrer aktuellen Form ausgeführt wird.

Zuvor habe ich bereits beschrieben, wie man die Feinabstimmung der Protokolleinträge vornimmt, die für eine bestimmte TraceSource an Windows Azure Diagnostics weitergeleitet werden sollen. Dabei handelt es sich um eine Art vorgeschaltete Festlegung, welche Informationen protokolliert werden sollen. In diesem Abschnitt dagegen geht es um die allgemeinen Windows Azure-Diagnoseeinstellungen, die festlegen, wie die Informationen, die eine TraceSource passieren, in den persistenten Speicher gelangen.

Mit den Windows PowerShell-CmdLets lassen sich viele Aspekte der ausgeführten Windows Azure-Dienste einschließlich der Diagnose verwalten. Sie werden vom lokalen Computer aus ausgeführt, stellen über das Internet eine Verbindung zu den Windows Azure-Cloud-Servern her, auf denen der Dienst ausgeführt wird, stellen Informationen bereit und legen Parameter fest. Windows PowerShell ist bei Windows 7 bereits installiert und kann für Windows Vista über microsoft.com/powershell heruntergeladen werden. Laden Sie die CmdLets für die Windows Azure-Dienstverwaltung von code.msdn.microsoft.com/azurecmdlets herunter und installieren Sie sie laut den Anweisungen. Die Diagnosebefehle von Windows Azure sind in Abbildung 9 aufgelistet.

Abbildung 9 Diagnose-CmdLets für die Verwaltung von Windows Azure

Name Beschreibung
Get-ActiveTransfers Gibt das Set aktiver Diagnoseübertragungen mit den zugehörigen Übertragungsinformationen zurück.
Get-CommonConfigurationLogs Ruft die gemeinsamen Konfigurationswerte aller Protokollpuffer ab. Dies umfasst auch das Zeitintervall, in dem Konfigurationsänderungen abgerufen werden, sowie die Puffergröße, die den Protokollen im Speicher zugewiesen wurde.
Get-DiagnosticAwareRoleInstances Gibt eine Liste der IDs aktiver Rolleninstanzen zurück, für die ein Diagnosemonitor ausgeführt wird.
Get-DiagnosticAwareRoles Listet ein Set von Rollen auf, die mindestens einen Diagnosemonitor erfolgreich gestartet haben.
Get-DiagnosticConfiguration Ruft die Pufferkonfiguration zum angegebenen Puffernamen (Logs, Directories, PerformanceCounters, WindowsEventLogs oder DiagnosticInfrastructureLogs) ab.
Set-CommonConfigurationLogs Legt die gemeinsamen Konfigurationswerte aller Protokollpuffer fest.
Set-FileBasedLog Legt die Pufferkonfiguration für dateibasierte Protokolle fest.
Set-InfrastructureLog Legt die Pufferkonfiguration für die von der zugrunde liegenden Windows Azure-Diagnoseinfrastruktur generierten Protokolle fest. Die Protokolle der Diagnoseinfrastruktur sind nützlich für die Fehlerbehebung im Diagnosesystem selbst.
Set-PerformanceCounter Legt die Pufferkonfiguration für Leistungsindikatordaten fest, die vom Dienst erfasst werden.
Set-WindowsAzureLog Legt die Pufferkonfiguration für die vom Dienst generierten grundlegenden Windows Azure-Protokolle fest.
Set-WindowsEventLog Legt die Pufferkonfiguration für die vom Dienst generierten grundlegenden Windows-Ereignisprotokolle fest.
Start-OnDemandTransfer Startet eine bedarfsgesteuerte Übertragung der angegebenen Datenpuffer. Dabei werden die Daten in den Windows Azure-Speicher (Tabellen- oder Blob-Speicher) verschoben.
Stop-ActiveTransfer Stoppt die aktive bedarfsgesteuerte Übertragung. Eine Übertragungs-ID muss angegeben werden.

Um beispielsweise die aktuellen Übertragungsparameter für eine bestimmte Rolleninstanz zu suchen, übergeben Sie die Bereitstellungs-ID (aus dem Windows Azure-Entwicklerportal, wo Sie den Dienst bereitstellen) und den Speicherkontonamen sowie den Schlüssel, den Sie als DiagnosticsConnectionString in der app.config oder web.config für die Dienstrolle verwendet haben (siehe Abbildung 10). Beachten Sie, dass Windows PowerShell Sie zur Eingabe einiger fehlender, aber erforderlicher Parameter auffordert – nämlich Rolleninstanz und Namen des gewünschten Puffers. Die Protokolle sind die standardmäßigen Windows Azure-Protokolle. Das Ergebnis zeigt, dass als Filterstufe „Verbose“ eingestellt ist und planmäßig einmal pro Minute eine Übertragung stattfindet.

Figure 10 Diagnostics Configuration for a Running Service Using Windows PowerShell
Abbildung 10 Diagnosekonfiguration für einen ausgeführten Dienst mit Windows PowerShell

Zum Ändern der Konfiguration für diese Rolle geben Sie das CmdLet Set-DiagnosticConfiguration ein, wie in Abbildung 11 zu sehen. Beachten Sie, dass ich das Übertragungsintervall von einer in zwei Minuten geändert und den Filter von „Verbose“ auf „Error“ gesetzt habe. Das heißt, nur Ereignisse des Typs „Error“ und „Critical“ werden in den persistenten Speicher übertragen.

Figure 11 Changing Diagnostics Configuration from Windows PowerShell
Abbildung 11 Ändern der Diagnosekonfiguration über Windows PowerShell

Die vielleicht nützlichste Funktion, die sich remote über Windows PowerShell ausführen lässt, ist das sofortige Erzwingen einer Protokollübertragung. Abbildung 12 zeigt die Vorgehensweise.

Figure 12 Using Windows PowerShell to Initiate a Transfer of IIS Logs
Abbildung 12 Initiieren der Übertragung von IIS-Protokollen über Windows PowerShell

Zuerst frage ich ab, ob eine bedarfsgesteuerte Protokollübertragung vorliegt. Denn eine Einschränkung in der aktuellen Windows Azure-Diagnoseimplementierung besagt, dass immer nur eine bedarfsgesteuerte Übertragung eines bestimmten Typs gleichzeitig stattfinden darf. Ich sehe, dass keine solche Übertragung in Bearbeitung ist, und kann also eine anfordern. Dazu gebe ich die Bereitstellungs-ID des Dienstes, die Rolle und die Instanz, den zu übertragenden Protokolltyp und das Zeitintervall für die Datenübertragung an. Beim Protokolltyp weist „Directories“ auf dateibasierte Protokolle einschließlich der IIS-Protokolle hin. „Logs“ dagegen weist auf Windows Azure-tabellenbasierte Protokolle hin, die über TraceSource übertragen werden.

Darüber hinaus gebe ich den Namen der Benachrichtigungswarteschlange an, also der Warteschlange, in die Windows Azure Diagnostics die Benachrichtigung schickt, dass die Übertragung abgeschlossen ist. Durch Experimentieren habe ich herausgefunden, dass anscheinend keine Übertragung stattfindet, wenn man keine Benachrichtigungswarteschlange angibt. Daraufhin wird eine GUID zurückgegeben, die die Übertragungsanforderung identifiziert. Nun frage ich den Status der Anforderung ab und sehe, dass sie veröffentlicht, also in Bearbeitung ist.

Die aktuelle Version der CmdLets für die Windows Azure-Dienstverwaltung zeigt offenbar nicht an, wann die Anforderung abgeschlossen ist. Wenn man aber den Blob-Speicher des Diagnosespeichers abfragt, sieht man, wie die Protokolle nach kurzer Zeit in der Containerhierarchie (oder im Windows Azure-Tabellenspeicher, wenn man die Übertragung von Informationen aus dem Tabellenspeicher angefordert hat) angezeigt werden.

Zusammenfassung

Die Diagnoseausgabe von Windows Azure-Diensten lässt sich mit einer Kombination von Maßnahmen sehr genau steuern: Zum einen kann man die Konfigurationsparameter für die im Code definierten TraceSources einstellen, zum anderen kann man Informationen mithilfe der CmdLets für die Windows Azure-Dienstverwaltung in den persistenten Speicher verschieben.

Die wichtigste Maßnahme für die Fehlerbehebung im Produktionscode ist jedoch die Entwicklung einer robusten Strategie für die Diagnoseausgaben bereits früh im Lauf der Entwicklungsarbeit und die Einhaltung dieser Strategie während der gesamten Codierung. Mithilfe der TraceSources und der von Windows Azure bereitgestellten Tools zur Konfiguration des Ausführlichkeitsgrades von Diagnoseausgaben, die von der Anwendung in den Speicher übertragen werden, können Sie erreichen, dass im Fall eines Problems genau das richtige Maß an Informationen erfasst wird.

Es gibt nichts Schlimmeres als das Gefühl, dass es sich bei einem Code, der auf einem Server fehlerhaft ausgeführt ist, um eine undurchschaubare Black Box handelt. Mit einem soliden Diagnosecode und den in diesem Artikel beschriebenen Tools können Sie die Black Box öffnen und hineinschauen.  

Mike Kelly ist Berater. Seine Hauptarbeitsgebiete sind Softwareentwicklung und Unterstützung bei der Integration von Akquisitionen in großen Unternehmen. Vorher war er 15 Jahre lang bei Microsoft in verschiedenen Aufgabengebieten der Produktentwicklung und als Leiter für Emerging Practices im Engineering Excellence-Team tätig. Sie erreichen ihn unter himself@mikekellyconsulting.com.

Unser Dank gilt den folgenden technischen Experten für die Durchsicht dieses Artikels: Sumit Mehrotra, Michael Levin und Matthew Kerner von Microsoft sowie Neil Mackenzie und Steven Nagy