Click here to Skip to main content
Click here to Skip to main content
Go to top

JavaScript Logging

, 13 Mar 2014
Rate this:
Please Sign up or sign in to vote.
A simple JavaScript logger, supporting multiple appenders (console & service)

When "Capturing client-side JavaScript errors" showed up in the "adopt" section in the ThoughtWorks Technology Radar, I was reminded that I couldn't find a JavaScript logger which met my requirements, when I wrote my first JavaScript heavy web application (in 2011). Since the ones I looked at back then are still the top hits on Google (log4js & log4javascript), I guess there might still be a need for custom solutions. However, if one of them fits your needs, you should probably not roll your own...

I had basically two requirements:

  • Multiple appenders (console & web service)
  • Fine granular configuration

I implemented a logger "module" (no fancy and module, just the plain revealing module pattern), a console appender module and a service appender module.

The logger offers the usual log methods, checks if the corresponding level is enabled and then forwards the calls to the registered appenders:

isLogLevelEnabled = function (logLevel) { 
    return app.config.logger['is' + logLevel + 'Enabled'] === true;     
},
debug = function (message, category) {
    log(category, "Debug", message);
},
// ...
error = function (message, category) {
    log(category, "Error", message);
},
log = function (category, logLevel, message) {
    if (isLogLevelEnabled(logLevel)) {
        for (var i = 0; i < appenders.length; i++) {
                appenders[i].log(category, logLevel, message);
        }
    }
},

The service appender checks again if the log level is enabled (specifically for the service appender, so you can log different level with different appenders). It also allows you to enable logging for specific users by setting a cookie. This could be handy when you need to debug an issue of a specific user.

var log = function (category, logLevel, message) {
    if (isLogLevelEnabled(logLevel) || isUserEnabled()) {
        var logData = { 'category': category, 'logLevel': logLevel, 'message': message };
        $.post(app.config.serviceAppender.logServiceUrl, logData);
    }
},
    isLogLevelEnabled = function (logLevel) {
        return app.config.serviceAppender['is' + logLevel + 'Enabled'] === true;
    },
    isUserEnabled = function () {
        return typeof (app.config.serviceAppender.allowServiceLoggingByCookie) !== 'undefined' &&
            app.config.serviceAppender.allowServiceLoggingByCookie === true &&
                $.cookie("enableServiceLogging") === "true";
    };

The config is set by defining the app.config object, which you probably want to load from a database or some other storage you can edit without deploying your site.

window.app.config = {};
window.app.config.logger = { isDebugEnabled: false, isInfoEnabled: true, 
    isWarnEnabled: true, isErrorEnabled: true };
window.app.config.serviceAppender = {
    allowServiceLoggingByCookie: true, logServiceUrl: '@Url.Content("~/api/log")',
    isDebugEnabled: false, isInfoEnabled: false, 
    isWarnEnabled: true, isErrorEnabled: true
};
window.app.config.consoleAppender = {
    isDebugEnabled: false, isInfoEnabled: true,
    isWarnEnabled: true, isErrorEnabled: true
};

You can check out the sample project. It is a F5-ready ASP.NET MVC application, although nothing about the logger is .NET specific.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Markus Greuel

Germany Germany
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 13 Mar 2014
Article Copyright 2014 by Markus Greuel
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid