Ajout d’un suivi aux modules managés IIS 7.0

par Saad Ladki

Introduction

IIS 7.0 et versions ultérieures offre la possibilité de plug-in et d’utiliser des modules managés développés personnalisés pour accomplir de nombreuses tâches différentes et utiliser ces modules pour toutes les sortes de contenu. Toutefois, la question se pose : que se passe-t-il si le module a des problèmes ou des difficultés ? Auparavant, vous avez utilisé System.Diagnostics pour suivre l’événement lorsque des problèmes se sont produits. Malheureusement, ces traces sont complètement distinctes des traces IIS.

Ce n’est pas le cas avec IIS 7.0 et versions ultérieures. Vous pouvez maintenant ajouter des traces au code du module à l’aide de System.Diagnostics.TraceSource (nouveauté de .Net 2.0). Vous avez la possibilité d’acheminer ces traces dans l’infrastructure de suivi IIS afin qu’elles soient disponibles pour les modules qui consomment des traces, par exemple, suivi des requêtes ayant échoué.

L’équipe IIS encourage l’instrumentation du code à l’aide de modèles de base tels que :

  • Événements START & STOP autour des activités clés dans votre code
  • Événements AVERTISSEMENT & ERREUR pour les occurrences inattendues susceptibles d’entraîner l’échec de la requête (par exemple, l’authentification ayant échoué)
  • Événements INFORMATIONAL & VERBOSE pour obtenir de l’aide sur les diagnostics, tels que la configuration du module utilisée

Cette procédure pas à pas décrit notamment les tâches suivantes :

  • Ajout du suivi au module à l’aide de System.Diagnostics.TraceSource
  • Configuration du suivi des requêtes ayant échoué pour capturer ces traces
  • Générer la condition d’échec et affichage de la trace résultante

Prérequis

Suivez les étapes ci-dessous avant d’effectuer les tâches de cet article.

Étape 1 : installer IIS

Tout d’abord, IIS doit être installé. Vérifiez si IIS est installé en accédant à http://localhost/. Si IIS est installé, la page « en construction » s’affiche. Si IIS n’est pas installé, reportez-vous à Installer IIS pour obtenir des instructions. Veillez à installer les composants IIS suivants :

  • ASP (dans Services World Wide Web => Fonctionnalités de développement d’applications => ASP)
  • ASP.Net (sous Services World Wide Web => Fonctionnalités de développement d’applications => ASP.Net)
  • Suivi (dans Services World Wide Web => Intégrité et diagnostics => suivi)

Étape 2 : connectez-vous en tant qu’administrateur

Se connecter en tant que compte Administrateur ou au groupe Administrateurs.

Remarque

Le fait d’être dans le groupe Administrateurs ne vous accorde pas les droits d’administrateur complets par défaut. Vous devez exécuter de nombreuses applications en tant qu’administrateur. Cliquez avec le bouton droit sur l’icône d’application et choisissez « Exécuter en tant qu’administrateur ».

Étape 3 : effectuez une Sauvegarde Microsoft Azure

Effectuer une sauvegarde de la configuration avant d’exécuter les tâches décrites dans cet article. Exécutez la commande suivante :

  1. Cliquez sur le bouton Démarrer -> Tous les programmes -> Accessoires -> (clic droit) Invite de commandes -> Exécuter en tant qu’administrateur
    Screenshot of the Windows Start menu with a focus on the Run as administrator option in the right-click drop-down menu.

  2. Exécutez la commande suivante dans cette invite de commandes :

    %windir%\system32\inetsrv\appcmd add backup
    

Étape 4 : création d’exemples de contenu

  1. Supprimez tout dans le dossier c:\inetpub\wwwroot.
  2. À partir de l’invite de commandes Administrateur démarrée ci-dessus, collez le code attaché dans un fichier inetpub\wwwroot appelé test.htm :
<h2>HOWTO: Adding tracing to modules </h2>
This is a sample page served by the static file handler (native code).

Création et suivi d’un module simple

Dans cette section, vous allez créer un exemple de module à instrumenter.

Étape 1 : créer un module simple

À l’aide de l’invite de commandes Administrateur, copiez et collez le code suivant dans un fichier appelé IIS_MOD_REQDATA.cs :

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;

namespace IIS_MOD_REQDATA
{
    public class IIS_MOD_REQDATA : IHttpModule
    {
        public void Init(HttpApplication application)
        {
            application.EndRequest += (new EventHandler(this.Application_EndRequest));
        }

        private void Application_EndRequest(Object source, EventArgs e)
        {
            HttpApplication application = (HttpApplication)source;
            HttpContext context = application.Context;

            // start writing out the request data

            context.Response.Write("<hr>");
            context.Response.Write("<b><font size=2 color=green>REQUEST HEADERS</font></b><br>");
            context.Response.Write("<font size=2>");
            context.Response.Write("METHOD : " + context.Request.HttpMethod + "<br>");
            context.Response.Write("URL : " + context.Request.Url + "<br>");
            context.Response.Write("QUERYSTRING : " + context.Request.QueryString + "<br>");
            context.Response.Write("</font><br>");

            // now response data

            context.Response.Write("<b><font size=2 color=blue>RESPONSE HEADERS</font></b><br>");
            context.Response.Write("<font size=2>");
            context.Response.Write("STATUS CODE : " + context.Response.StatusCode.ToString() + "." + context.Response.SubStatusCode.ToString() + "<br>");
            context.Response.Write("CONTENT TYPE : " + context.Response.ContentType.ToString() + "<br>");
            context.Response.Write("EXPIRES : " + context.Response.Expires.ToString() + "<br>");
            context.Response.Write("</font><br>");

            // set cache policy on response so it's not cached.

            context.Response.DisableKernelCache();
        }

        public void Dispose()
        {
        }
    }
}

Étape 2 : ajout du suivi au module managé

Pour ajouter le suivi à votre module et router ses événements de trace dans IIS, utilisez la source System.Diagnostics.Trace. Ajoutez la ligne suivante sous les instructions d’utilisation :

using System.Diagnostics;

Vous devez créer une TraceSource dans le code : notez la définition de traceSource dans la déclaration du module IIS_MOD_REQDATA :

public class IIS_MOD_REQDATA : IHttpModule
{
    TraceSource tsStatus;

Le membre tsStatus est initialisé pendant la méthode Init() de IHttpModule :

public void Init(HttpApplication application)    
{    
    application.EndRequest += (new EventHandler(this.Application_EndRequest));
    // setup traceSource
    tsStatus = new TraceSource("tsStatus");    
}

Le nom de TraceSource («  tsStatus ») est important, car ce nom est ultérieurement référencé dans le fichier web.config ultérieurement. Le module est maintenant configuré pour émettre des événements si nécessaire.

Pour ajouter un nouvel événement de trace, utilisez tsStatus.TraceEvent(<type>, 0, <somestring>) pour écrire des événements. Ajoutez les événements Commencer et Terminer recommandés à la méthode Application_EndRequest() :

private void Application_EndRequest(Object source, EventArgs e)        
{    
    tsStatus.TraceEvent(TraceEventType.Start, 0, "[REQDATA MODULE] START EndRequest");

    // other code

    tsStatus.TraceEvent(TraceEventType.Stop, 0, "[REQDATA MODULE] END EndRequest");    
}

Notez que les différents <types> sont pris en charge, entre autres :

  • TraceEventType.Start
  • TraceEventType.Stop
  • TraceEventType.Error
  • TraceEventType.Warning
  • TraceEventType.Information
  • TraceEventType.Verbose

Pour l’exhaustivité, la source entière du module (y compris les événements de trace) peut être copiée ici :

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Diagnostics;

namespace IIS_MOD_REQDATA
{
    public class IIS_MOD_REQDATA : IHttpModule
    {

        TraceSource tsStatus;

        public void Init(HttpApplication application)
        {
            application.EndRequest += (new EventHandler(this.Application_EndRequest));

            // TRACING

            tsStatus = new TraceSource("tsStatus");
        }

        private void Application_EndRequest(Object source, EventArgs e)
        {
            HttpApplication application = (HttpApplication)source;
            HttpContext context = application.Context;

            tsStatus.TraceEvent(TraceEventType.Start, 0, "[REQDATA MODULE] START EndRequest");

            // start writing out the request data

            context.Response.Write("<hr>");
            context.Response.Write("<b><font size=2 color=green>REQUEST HEADERS</font></b><br>");
            context.Response.Write("<font size=2>");
            context.Response.Write("METHOD : " + context.Request.HttpMethod + "<br>");
            context.Response.Write("URL : " + context.Request.Url + "<br>");
            context.Response.Write("QUERYSTRING : " + context.Request.QueryString + "<br>");
            context.Response.Write("</font><br>");

            tsStatus.TraceEvent(TraceEventType.Verbose, 0, "[REQDATA MODULE] done with Req Data, moving onto Response");

            // now response data

            context.Response.Write("<b><font size=2 color=blue>RESPONSE HEADERS</font></b><br>");
            context.Response.Write("<font size=2>");
            context.Response.Write("STATUS CODE : " + context.Response.StatusCode.ToString() + "." + context.Response.SubStatusCode.ToString() + "<br>");
            context.Response.Write("CONTENT TYPE : " + context.Response.ContentType.ToString() + "<br>");
            context.Response.Write("EXPIRES : " + context.Response.Expires.ToString() + "<br>");
            context.Response.Write("</font><br>");

            if (context.Response.StatusCode > 399)
            {
                tsStatus.TraceEvent(TraceEventType.Warning, 0, "[REQDATA MODULE] error status code detected");
            }

            tsStatus.TraceEvent(TraceEventType.Verbose, 0, "[REQDATA MODULE] done with Response Data");

            // set cache policy on response so it's not cached.

            context.Response.DisableKernelCache();
            tsStatus.TraceEvent(TraceEventType.Verbose, 0, "[REQDATA MODULE] cache setting is (" + context.Response.Cache.ToString() + ")");

            tsStatus.TraceEvent(TraceEventType.Stop, 0, "[REQDATA MODULE] STOP - EndRequest");
        }

        public void Dispose()
        {
        }
    }
}

Étape 3 : compilation de notre module suivi

Maintenant, pour compiler le module et le déployer. Dans l’invite de commandes administrateur, exécutez la commande suivante :

%systemroot%\Microsoft.NET\Framework\v2.0.50727\csc.exe /target:library /out:IIS_MOD_REQDATA.dll /debug /d:TRACE /R:System.Web.dll IIS_MOD_REQDATA.cs

Screenshot of the exclamation code dash consoleMain command in Notepad.

Remarque

Si vous exécutez cette opération sur un système 64 bits, compilez à l’aide du compilateur c# 64 bits dans %windir%\microsoft.net\framework64\v2.0.50727\csc.exe

Notez l’utilisation des commutateurs /debug et /d:TRACE. Vous devez utiliser ces commutateurs pour compiler les événements de trace dans le fichier binaire. L’échec de la compilation avec ces commutateurs signifie que le module n’aura pas d’événements de trace dans celui-ci.

Après avoir compilé le module, déployez le module et exécutez un test initial pour voir si le module fonctionne avant de capturer ses traces.

Ajout de modules à la configuration du site

Cette section inclut l’ajout et le test du module.

Étape 1 : ajout du module à la configuration du site

  1. À l’aide de la même invite de commandes Administrateur, créez un répertoire appelé \inetpub\wwwroot\bin, puis copiez IIS_MOD_REQDATA.dll sur ce répertoire.
  2. Activez le module. À partir de l’invite de commandes administrateur, tapez démarrer inetmgr pour afficher l’interface utilisateur d’administration IIS.
  3. Sous le volet Connections, développez le nom de l’ordinateur local, puis Sites, puis cliquez sur Site web par défaut.
  4. Sous IIS dans le volet central, double-cliquez sur Modules :
    Screenshot of the Default Web Site Home screen with the Modules option being highlighted.
  5. Vous voyez une grande liste de modules configurés pour une utilisation par ce site. Sur le côté droit de l’interface utilisateur sous Actions, cliquez sur Ajouter un module managé :
    Screenshot of the Actions pane with a focus on the Add Managed Module option.
  6. Dans la fenêtre qui s’affiche, nommez le module managé IIS_MOD_REQDATA et le type du module est IIS_MOD_REQDATA.IIS_MOD_REQDATA (sélectionnez-la dans la zone de liste déroulante) :
    Screenshot of the Add Managed Module dialog box, showing the Name and Type fields.
  7. Cliquez sur OK. Le module nouvellement suivi est maintenant configuré pour l’utilisation du site web.
    Screenshot of the Modules screen, showing the newly traced module.

Étape 2 : test de notre module

Testez le module en ouvrant Internet Explorer et en accédant à http://localhost/test.htm. La fenêtre suivante apparaît :

Screenshot of a webpage reading here is a sample page that is served by static file handler.

Le contenu « EN-TÊTES DE DEMANDE » et « EN-TÊTES DE RÉPONSE » provient de notre module, indiquant qu’il fonctionne.

Routage d’événements vers IIS

Cette tâche connecte TraceSource du module jusqu’au suivi IIS afin que ses événements soient émis via IIS, puis configurent le suivi des demandes d’échec pour capturer ces événements de trace.

Étape 1 : activation du module TraceSource et routage de ses événements dans IIS

Le module est mis à jour pour inclure des événements de trace. Configurez System.Diagnostics et IIS pour capturer ces événements de trace et les router dans le module Suivi des demandes ayant échoué IIS. Pour ce faire, configurez la section <system.diagnostics> dans le fichier web.config pour configurer TraceSource et router ses événements en conséquence.

  1. À l’aide de votre invite de commandes Administrateur, accédez à c:\inetpub\wwwroot et utilisez le bloc-notes pour modifier votre fichier web.config.

  2. Il existe 3 parties de la configuration qui doivent être effectuées pour obtenir les événements émis par le module à router vers l’infrastructure de suivi d'IIS :

    • Définition de l’événement IIS traceListener en tant qu’écouteur partagé
    • Définition d’un commutateur pour activer tous les événements
    • Définition de la source de trace, attachement du commutateur que nous avons défini, ainsi que définition de l’écouteur de trace pour notre source.
  3. IIS fournit un nouveau System.Diagnostics.TraceListener utilisé pour acheminer les événements TraceSource dans l’infrastructure trace d'IIS. Ce fournisseur doit également être défini dans votre fichier web.config.

  4. Définissez traceSource par son nom (tsStatus) et connectez-le à DefaultSwitch et IisTraceListener.

  5. Copiez et collez cette section <system.Diagnostics> dans votre fichier web.config (après votre section <system.webServer>).

    <system.diagnostics>
        <sharedListeners>
          <add name="IisTraceListener" type="System.Web.IisTraceListener, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        </sharedListeners>
    
        <switches>
          <add name="DefaultSwitch" value="All" />
        </switches>
    
        <sources>
          <source name="tsStatus" switchName="DefaultSwitch">
            <listeners>
              <add name="IisTraceListener" type="System.Web.IisTraceListener, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
            </listeners>
          </source>
        </sources>
    </system.diagnostics>
    

La traceSource tsStatus est câblée à IIS7TraceListener, qui émettra des événements dans l’infrastructure de suivi d'IIS. Passez à l’étape suivante pour lier ces événements au fournisseur de suivi des demandes ayant échoué.

Étape 2 : activation du suivi des demandes ayant échoué pour capturer les événements de trace de module

Lorsque ces événements de diagnostic sont émis dans l’infrastructure de suivi d'IIS, ils sont mappés au fournisseur ASP.net et à l’indicateur module sur ce fournisseur. Leur détail dépend du TraceEventType utilisé. Pour configurer le suivi des demandes ayant échoué pour les récupérer :

  1. À partir de votre invite de commandes Administrateur, tapez start inetmgr. Dans le panneau Connexions, développez le nom de l’ordinateur, puis le dossier Sites ; ensuite, cliquez sur le site Web par défaut. À droite sous le volet Actions, cliquez sur le lien Suivi des demandes ayant échoué... sous Configurer :
    Screenshot of the Manage Web Site section of the Actions pane, with the Failed Request Tracing option being highlighted.

  2. Dans la boîte de dialogue suivante, configurez les éléments suivants :
    Screenshot of the Edit Web Site Failed Request Tracing Settings dialog box.

  3. Cochez la case Activer. Conservez les valeurs par défaut pour les autres paramètres. Pour continuer, cliquez sur OK .

  4. Maintenant que nous avons vérifié que la journalisation du suivi des demandes ayant échoué est activée, nous devons configurer les définitions d’échec. De retour dans le Gestionnaire d'IIS, sous IIS, double-cliquez sur Règles de suivi des demandes ayant échoué
    Screenshot of the Default Web Site Home screen with the Failed Request Tracing Rules option being highlighted.

  5. Dans le volet Actions, cliquez sur Ajouter…. Cela lance l’Assistant Ajouter une règle de suivi des demandes ayant échoué.

  6. Dans la page Spécifier le contenu à suivre, sélectionnez l’option Tout le contenu (*) pour savoir comment effectuer le suivi. Sélectionnez Suivant.
    Screenshot of the Add Failed Request Tracing Rule page with a focus on the Next option.

  7. Dans l’écran Définir les conditions de trace, cochez la case Codes d’état et entrez « 200 » comme code d’état à suivre.
    Screenshot of the Define Trace Conditions screen with the Status codes field being checked.

  8. Sélectionnez Suivant. La page Sélectionner les fournisseurs de traces’affiche. Sélectionnez la zone de la case à cocher ASPNET et les zones des cases à cocher Module et page sous « Zones ». Sous Verbosité, sélectionnez Détaillée.
    Screenshot of the Select Trace Providers screen with the ASPNET Provider option being highlighted.

    Remarque

    En raison d’un bogue dans les builds Server Beta 3, les traces de module ne peuvent être capturées que si les zones Module et Page sont sélectionnées. Post Server Beta 3, seul le module est nécessaire pour collecter ces événements.

  9. Cliquez sur Terminer. Vous voyez la définition suivante pour le site web par défaut :
    Screenshot of the Failed Request Tracing Rules screen.

Test et affichage des résultats

Dans cette tâche, nous générons la demande ayant échoué et afficher le journal de trace résultant. N’oubliez pas que nous avons configuré IIS pour capturer les journaux de trace pour http://localhost/* demandes qui échouent avec une version 200. Pour vérifier que cela a fonctionné :

  1. Ouvrez une nouvelle fenêtre Internet Explorer. Tapez l’adresse http://localhost/test.htm. De nouveau, vous voyez ce qui suit :
    Screenshot of the sample webpage in an Internet Explorer window.
  2. Pour vérifier que notre module a généré des traces capturées, utilisez une fenêtre Internet Explorer avec élévation de privilèges Administrateur et appuyez sur Ctrl-O, puis accédez à c:\inetpub\logs\FailedReqLogFiles\W3SVC1. Dans la zone de liste déroulante qui lit les fichiers HTML, sélectionnez Tous les fichiers.
  3. Sélectionnez le fichier fr######.xml le plus récent (date du jour) et cliquez sur Ouvrir. Vous voyez les événements :
    Screenshot of the Request Diagnostics screen, showing the Custom Module Traces tab.

Résumé

Vous avez terminé d’ajouter un nouvel événement de trace à un module managé, compilé et déployé ce module, configuré System.Diagnostics pour router ses événements vers l’infrastructure de suivi d'IIS, et enfin, configurer la fonctionnalité de suivi des demandes ayant échoué d'IIS pour capturer ses événements. Vous pouvez désormais facilement ajouter de nouveaux événements au module, puis recompiler le module et le déployer dans le répertoire \bin. À l’aide du suivi des demandes ayant échoué, vous voyez les résultats des événements.

N’oubliez pas que l’utilisation de System.Diagnostics.TraceSource vous permet toujours d’utiliser votre module et ses événements de trace de bas niveau, à condition que vous le connectiez à un autre écouteur de trace.