ElmahR, a description

Tagged: c# elmah signalr elmahr

After releasing Elmahr v0.2, I think it's time to describe with more details what it is, how it's done and what are my plans for the next releases. ElmahR is a web dashboard where you can aggregate several monitored applications; adding them to ElmahR configuration will enable them to post error events, which will show them on all the connected client dashboards in real-time.

ElmahR is about error logging in real-time, and to do that it's based on ELMAH for the 'error logging' part and on SignalR for the 'real-time notification' piece. The integration with ELMAH is not based on binary dependencies, but on data exchange. ELMAH already defines a set of fields and collections which describe an error, and ElmahR borrows this data structure and builds its logics on top of it. This approach makes ElmahR virtually independent from ELMAH, whoever is able to craft an error description matching the data format from ELMAH can send error events to ElmahR and have them published. It has not to be an ASP.NET application, it could be a desktop client, a mobile app, it could even be developed on a non-.NET platform, as long as it can post data over HTTP. Nevertheless the most convenient way to use ElmahR is to enable ELMAH on the ASP.NET web application you have to monitor, and configure it to post errors to ElmahR, this way you'll leverage all the great logging features that ELMAH already has. To do that you will need the new ErrorPostModule, which I wrote myself and is not part of official ELMAH. You can find its source code on the ELMAH Sandbox, and it's distributed in binary form with ElmahR. When you have ELMAH correctly configured for your application, all you have to do to have it post to ElmahR is to configure ErrorPostModule appropriately:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <sectionGroup name="elmah">
      ...
      <section name="errorPost" 
               requirePermission="false" 
               type="Elmah.ErrorLogSectionHandler, Elmah"/>
      ...
    </sectionGroup>
    <section name="elmahr" type="ElmahR.ElmahRSectionHandler,ElmahR"/>
  </configSections>
  <elmah>
    ...
    <errorPost targetUrl="http://elmahr_dashboard_base_address/posterror.ashx"
               infoUrl="http://your_application_base_address/elmah.axd"/>   
    ...
  </elmah>
  <elmahr>
    <application name="ElmahR sample erratic application"   
                 sourceId="http://localhost:37345/elmah.axd"/>
  </elmahr>
  ...
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true">
      ...
      <add name="ErrorPost" 
           type="Elmah.Sandbox.ErrorPostModule, Elmah.Sandbox"/>
    </modules>
    ...
  </system.webServer>
  ...
</configuration>

There are 2 relevant parts:

  • where the errorPost section is configured with the targetUrl and the infoUrl:
    • targetUrl: address where posterror.ashx can be found; posterror.ashx is the endpoint you have to target in order to post errors, it understands the ELMAH data format and it's able to receive errors and treat them properly
    • infoUrl: address that ElmahR users will be able to hit to have info about the monitored application
  • where ElmahR itself is configured (elmahr section), adding as many application tags as the applications you want to aggregate in the dashboard; for each of them you will define a name and an id, which should be an url uniquely identifying the application

You will find a more complete sample in the web.config from the Bitbucket repository.

When an error arrives to ElmahR after being posted as described earlier, the server side uses SignalR to redistribute it to all the connected clients. This is a place where improvements will be needed, the code I wrote is still very basic and does not really take advantage of all SignalR features. Things like 'server-side filtering', or smart history persistence for new or reconnecting clients, should be added soon.

Then SignalR does its magic, and errors arrive to the clients as JSON structures which still resemble the ELMAH data format. ElmahR is heavily based on Javascript, but to be honest I'm not the greatest Javascript expert around, so the code you will see there is still quite ugly and I'll be working on it to improve it. What I want to reach is a good level of separation of concerns, which would more easily enable contributors to clean up things ( :) ) and add new pieces. RequireJS is the next tool I'll add to the project to help me in that direction. The client-side dashboard delivers real-time experience, in form of error 'boxes' smoothly appearing as errors occur, and with (basic) statistics about how many errors have been observed. Error descriptions are clickable, causing an error details window to popup. You can also do some basic 'client-side filtering' blocking error types you are not interested into, just click the 'eye' icon corresponding to the error type you are bored about and you will not see it popup anymore.

The code so far is still quite simple, so if you are interested just go and look at the source. In the next weeks I will be adding features and doing cleanup, the areas where I'll be working the most will be:

  • Javascript cleanup: client-side code is getting complex, it leverages several amazing libraries but it really needs to be well structured, I'll work on that on the next iteration
  • New features: things like authentication management, dynamic application enlisting, server-side filtering, and more (any suggestion?)
  • Cross browser support: so far ElmahR has been tested on Chrome and Firefox only, on IE there are several issues, and almost no tests at all have been done on Safari or Opera; I'll be working on those aspects soon, it's already planned to move from an hand-made layout to a 'Twitter bootstrap' one, which should help solving the aforementioned issues

There are more details which might be interesting to describe, but I'll keep them for future posts. At some point I will collect relevant infos and put them in the project's wiki. And you can find a live demo here.

1 Comment

Add a Comment