blog.pagesd.info

Aller au contenu | Aller au menu | Aller à la recherche

vendredi 23 décembre 2011

Configurer ELMAH pour utiliser SQL Server

Pour avancer un peu plus dans mon utilisation d'ELMAH, j'ai cherché à enregistrer les informations qu'il collecte dans une base de données.

Pour cela, j'ai réalisé quelques essais pour voir comment faire et pour comprendre comment cela fonctionnait :

  • Configuration automatique de SQL Server Compact
  • Configuration semi-automatique SQL Server
  • Configuration manuelle de SQL Server Compact

La suite de ce billet récapitule le fonctionnement propre à chacune de ces méthodes.

ELMAH + Sql Server Compact en automatique

Sous NuGet, je recherche "elmah" puis choisis le package "ELMAH on MS SQL Server Compact". Sa description indique qu'il s'agit d'une configuration pour démarrer rapidement avec une base de données Microsoft SQL Server Compact.

Ca semble être un meilleur choix que "ELMAH on MS SQL Server (requires manual config)" puisque à priori, l'absence de "requires manual config" devant logiquement signifier que je n'aurai rien à faire.

Je clique sur le bouton [Install] et l'installation débute, mais impose l'installation de Sql Server Compact 4.0.8+. Je tique un peu parce qu'il me semblait que j'étais à jour ? Mais bon, [I accept] et le projet référence maintenant 2 packages supplémentaires :

  • ELMAH on MS SQL Server Compact
  • SqlServerCompact

Il suffit alors de relancer l'application et de se rendre sur l'URL elmah.axd pour confirmer que tout a été configuré sans que effectivement j'ai eu quoi que ce soit à faire : "This log is provided by the SQL Server Compact Error Log". Génial !

Si je regarde dans le dossier "App_Data", je constate qu'il contient désormais une base de données "Elmah.sdf". Un double-clic pour l'ouvrir et je peux voir que celle-ci est constitué d'une seule table "ELMAH_Error", avec les colonnes nécessaire pour enregistrer tout le détail des erreurs :

  • ErrorId
  • Application
  • Host
  • Type
  • Source
  • Message
  • User
  • StatusCode
  • TimeUtc
  • Sequence
  • AllXml

Et si maintenant j'étudie ce qui a changé dans l'application, je m'aperçois qu'en fait c'est trois fois rien dans le web.config :

Un :

<connectionStrings>
  ...
  <add name="elmah-sqlservercompact"
       connectionString="Data Source=|DataDirectory|\Elmah.sdf" />
</connectionStrings>

Deux :

<system.data>
  <DbProviderFactories>
    <remove invariant="System.Data.SqlServerCe.4.0" />
    <add name="Microsoft SQL Server Compact Data Provider 4.0"
         invariant="System.Data.SqlServerCe.4.0"
         description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
  </DbProviderFactories>
</system.data>

Et trois :

<elmah>
  <errorLog type="Elmah.SqlServerCompactErrorLog, Elmah"
            connectionStringName="elmah-sqlservercompact" />
</elmah>

Rollback

Je désinstalle le package "ELMAH on MS SQL Server Compact" (mais pas les packages dont il dépend) puis le package "SqlServerCompact".

Puis je retourne sur elmah.axd où je peux constater que je suis bien revenu à mon point de départ : "This log is provided by the In-Memory Error Log.". Parfait !

ELMAH + Sql Server en semi-automatique

Ce coup-ci je fais un essai avec l'installation du package NuGet "ELMAH on MS SQL Server (requires manual config)".

Une fois terminé, un nouveau dossier "App_Readme" est apparu dans le projet, avec deux fichiers : - Elmah.SqlServer.sql - Elmah.SqlServer.txt

Et le fichier Elmah.SqlServer.txt contient le texte suivant :

Please note that in order to complete the installation of ELMAH.SqlServer you will have to do the following:

1) Run the Elmah.SqlServer.sql script against your database
2) Edit your web.config with the correct settings in the elmah <connectionString> to connect to your database

Malgré tout, le fichier web.config a déjà été pas mal préparé pour simplifier la configuration :

Un :

<connectionStrings>
  ...
  <add name="elmah-sqlserver" 
       connectionString="Data Source=****;User ID=****;Password=****;Initial Catalog=****;"
       providerName="System.Data.SqlClient" />
</connectionStrings>

Et deux :

<elmah>
  <errorLog type="Elmah.SqlErrorLog, Elmah" 
            connectionStringName="elmah-sqlserver" />
</elmah>

Je sais jamais faire, mais sinon, c'est pas compliqué :

  • démarrer SQL Server Management Studio (l'occasion de voir que j'ai des tonnes de base Xxxxx.Models.XxxxxContext crées au cours de différents essais ou tutoriels)
  • créer une nouvelle base "Elmah" (et la passer en Compatibility_Level 80)
  • lancer le script (qui génère pas mal de message d'avertissement)

Ouf ! C'est fait.

Puis enregistrer la chaine de connexion :

<add name="elmah-sqlserver"
     connectionString="Data Source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=Elmah;"
     providerName="System.Data.SqlClient" />

Je peux alors relancer l'application, provoquer une erreur et aller que la page elmah.axd et vérifier que "This log is provided by the Microsoft SQL Server Error Log.". Bravo !

ELMAH + Sql Server Compact en manuel

Après désinstallation du package "ELMAH on MS SQL Server (requires manual config)", je me retrouve à nouveau avec un ELMAH tout simple qui stocke ses erreurs en mémoire. Et au passage, le dossier App_Readme a disparu. Magnifique !

Je peux donc tenter une modification tout ce qu'il y a de plus manuelle du web.config pour utiliser une base de données Sql Server Compact (celui qui est déjà installé sur mon PC).

Un :

<connectionStrings>
  ...
  <add name="elmah-sqlservercompact"
       connectionString="Data Source=|DataDirectory|\Elmah.sdf" />
</connectionStrings>

Et deux :

<elmah>
  <errorLog type="Elmah.SqlServerCompactErrorLog, Elmah"
            connectionStringName="elmah-sqlservercompact" />
</elmah>

Je relance l'application, tente d'accéder à l'URL index.html qui n'existe pas puis direction elmah.axd et ça marche : "This log is provided by the SQL Server Compact Error Log". Magnifique !

Conclusions

Déjà, le système des packages NuGet est bien foutu (au moins en ce qui concerne ELMAH) :

  • ça installe ce qui est nécessaire et ça fait les modifications et configurations qui vont bien où ça va bien.
  • quand on désinstalle, ça sait remettre tout comme il faut, y compris les modifications apportées au web.config :)

Pour l'instant, je vais en rester à la configuration manuelle pour Sql Server Compact. C'est bien suffisant pour les essais que je fais.

Mais finalement, je pense avoir compris pourquoi le package "ELMAH on MS SQL Server Compact" en automatique installe SqlServerCompact. Au moins, lorsque on déploie sur le serveur de production, ça permet que ELMAH soit prêt à fonctionner sur une base de données SQL Server Compact, même si celui-ci n'est pas installé en production. Pas bête !

jeudi 29 septembre 2011

Configurer ELMAH pour envoyer les erreurs par email

Après avoir vu comment installer ELMAH avec NuGet, j'ai fait quelques tests avec pour voir ce que ça pouvait donner avec différents types d'erreurs.

Et quand je repense au peu d'effort que ça m'a demandé pour l'installer, le résultat est quand même assez bluffant. Au moins ça donne envie d'aller plus loin et d'étudier un peu mieux comment utiliser "réellement" ELMAH dans une application.

Un premier truc intéressant, c'est de s'occuper de paramétrer ELMAH afin de recevoir un email quand qu'il détecte un problème. De cette façon, je serai averti quasiment instantanément chaque fois que mon application provoquera une exception. Ca fait un peu peur quand même...

Concrètement, ELMAH est plutôt bien fait et il n'y a pas besoin de grand chose pour paramétrer l'envoi d'email. Mais ce qui est encore plus génial, c'est que l'essentiel du travail de paramétrage a déjà été fait lors de l'installation via NuGet. Pour mémoire, il avait ajouté les 3 lignes suivantes aux bons endroits dans le Web.config :

  • <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
  • <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
  • <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />

Pour ma part, il ne me reste plus qu'à ajouter une section <elmah> avec des informations personnelles :

<configuration>
  ...
  <elmah>
    <errorMail
       from="go@gmail.com"
       to="michel@gmail.com"
       subject="Application Exception"
       async="true"
       smtpPort="587"
       useSsl="true"
       smtpServer="smtp.gmail.com"
       userName="go@mail.com"
       password="mot_de_passe">
    </errorMail>
  </elmah>

Note : étant donné que j'utilise GMail comme serveur SMTP, il est nécessaire d'activer SSL (d'où le useSsl="true") et de préciser qu'il faut utiliser le port 587 (quoique ?, voir mon billet System.Net.Mail et smtp.gmail.com).

Après ça, je n'ai plus qu'à relancer mon application et à provoquer quelques erreurs pour aussitôt voir ma boite mail se remplir. Heureusement que c'est pour du test...

Et pour être complet, il est sans doute préférable d'extraire le paramétrage du serveur SMTP de la configuration spécifique d'ELMAH et de le définir au niveau de la section prévue à cet effet dans le Web.config :

<configuration>
  ...
  <elmah>
    <errorMail
       from="go@gmail.com"
       to="michel@gmail.com"
       subject="Application Exception"
       async="true"
       smtpPort="0"
       useSsl="true">
    </errorMail>
  </elmah>
  ...
  <system.net>
    <mailSettings>
      <smtp deliveryMethod ="Network">
        <network host="smtp.gmail.com" 
                 port="587"
                 userName="go@gmail.com"
                 password="mot_de_passe" />
      </smtp>
    </mailSettings>
  </system.net>

Dans ce cas, il faut faire attention aux deux points suivants :

  • paramétrer le port "0" au niveau de la section <errorMail> pour que ce le port défini au niveau de la section <network> soit pris en compte,
  • l'activation du SSL se fait toujours dans la section <errorMail>.

mercredi 28 septembre 2011

Installer ELMAH avec NuGet

Jusqu'à présent, j'ai un peu tendance à utiliser NuGet uniquement pour mettre à jour Entity Framework, jQuery et consorts et dans mes très grands jours pour voir ce que donne un package de ci de là.

Après avoir terminé le chapitre de Professional ASP.NET MVC 3 consacré à NuGet, je me lance et j'en profite pour installer ELMAH. C'est l'exemple donné dans le livre et c'est un outil que j'avais déjà essayé d'utiliser du temps de mes WebForms puis de MVC 1.0 mais que j'avais chaque fois laissé tombé par manque de temps.

Je vais éviter la console pour l'instant et faire l'installation par un clic-droit sur la branche "Références" de mon projet puis en sélectionnant l'option "Manage NuGet Packages...".

elmah01.png

Note : cette option est également disponible quand on fait un clic droit sur la solution ou le nom du projet, mais dans ce cas elle plus difficile à repérer étant donné le plus grand nombre d'options proposées.

Il apparait alors la fenêtre "Manage NuGet Packages" qui liste par défaut tous les packages du monde en commençant par les plus téléchargés. Une fois là, le plus simple est d'utiliser la zone de recherche en haut à droite et d'y taper "elmah" pour n'afficher que les packages appropriés. Malgré tout, il reste encore une quinzaine de packages dans la liste !

elmah02.png

En cliquant sur un package, la colonne de droite est mise à jour et affiche tout un tas d'informations sur le package, avec entre autre sa version, sa description et ses dépendances. Comme rien n'est précisé dans le livre, j'installe le premier résultat obtenu (et donc le plus téléchargé), à savoir "ELMAH" (tout court) en cliquant sur le bouton "Install" qui apparait opportunément lorsque la souris le survole. Et c'est parti !

elmah03.png

Note : si j'avais accédé à la fenêtre "Manage NuGet Packages" par un clic-droit sur la solution, j'aurai eu droit à un préliminaire me demandant d'indiquer pour quels projet je souhaitais installer le package :

elmah04.png

Une fois que l'installation (très rapide) est terminée, la fenêtre "Manage NuGet Packages" est rafraichie et je peux constater par une coche verte que le package "ELMAH" est désormais installé, ainsi que le package "ELMAH Core Library (no config)" dont il dépend.

Je peux alors fermer NuGet en cliquant sur le bouton "Close" en bas à gauche et constater que la librairie "Elmah" est maintenant référencée dans mon projet.

elmah05.png

Et ce n'est pas tout ! Le fichier Web.config a été modifié pour incorporer tous les paramètres nécessaires au bon fonctionnement de Elmah

...
<configuration>
  <configSections>
    <sectionGroup name="elmah">
      <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
      <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
      <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
      <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
    </sectionGroup>
...
    <httpModules>
      <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
      <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
      <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
    </httpModules>
    <httpHandlers>
      <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
    </httpHandlers>
  </system.web>
...
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
      <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />
      <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />
    </modules>
    <handlers>
      <add name="Elmah" path="elmah.axd" verb="POST,GET,HEAD" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
    </handlers>
  </system.webServer>

Je peux alors lancer l'application et me rendre à l'URL /elmah.axd pour constater que tout fonctionne sans encombre :

elmah06.png

Il ne me reste plus qu'à provoquer quelques erreurs :

  • accéder à un fichier /readme.txt inexistant
  • tester une route /Foo/Bar/1 qui n'existe pas

Puis retourner à l'adresse /elmah.axd pour m'assurer que ces deux erreurs ont bien été prises en compte :

elmah07.png

C'est déjà pas mal pour un début.

Il faut juste que je revois un peu la configuration pour que tout ça soit géré de façon plus pérenne et ne plus avoir "This log is provided by the In-Memory Error Log". Et aussi voir comment faire pour recevoir automatiquement un mél d'Elmah quand un problème survient.