"log4javascript" logger to store in local file

2.5k Views Asked by At

We are currently using log4javascript-popUpAppender console for development and would like to store the details to local file.

Though we can use the AjaxAppender to send log messages to the server and log those messages to log4j set up with a rolling file appender, we are looking for a way to use something similar to FileAppender in Log4js.

Any idea/suggestion?


This is similar to http://www.techques.com/question/1-3626960/JavaScript-logger-into-a-rolling-file
Since we have already implemented log4javascript, we would like to stick with the same framework.

2

There are 2 best solutions below

1
On

Adding FileAppender solution for IE and Firefox.

function FileAppender() {}

FileAppender.prototype = new log4javascript.Appender();

FileAppender.prototype.layout = new log4javascript.SimpleLayout();

FileAppender.prototype.append = function(loggingEvent) {

  var appender = this;

     var getFormattedMessage = function() {
    var layout = appender.getLayout();
     var formattedMessage = layout.format(loggingEvent);
      if (layout.ignoresThrowable()) {
          formattedMessage += loggingEvent.getThrowableStrRep();
      }
      return formattedMessage;
    };
    writefile = function(destinationFile, message) {
     if (isEmpty(destinationFile)) {
         log.error("Source location unknown");
         return;
    }
    if ($.browser.msie) {
        try {
        var fso = new ActiveXObject("Scripting.FileSystemObject");
        var file = fso.OpenTextFile(destinationFile, 8, true);
        file.WriteLine(message);
        file.close();
        } catch (e) {
        log.error("Please validate if file exist");
        }
    } else {
        netscape.security.PrivilegeManager
            .enablePrivilege("UniversalXPConnect");
        this.fso.initWithPath(destinationFile);
        if (!this.fso.exists()) {
        // create file if needed
        this.fso.create(0x00, 0600);
        }

        var file = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
        file.init(this.fso, 0x04 | 0x08 | 0x10, 064, 0);
        var line = message;
        file.write(line, line.length); // write data
        file.close();
    }
    };
    getFile = function() {
    return "c://temp//log//Javascriptlog.log";
    };
    writefile(getFile(), getFormattedMessage());
};

FileAppender.prototype.toString = function() {
    return "FileAppender";
};

log4javascript.FileAppender = FileAppender;
0
On

This is still not really viable in browsers, in my view. I've had another look at it; these are my observations:

  • In Firefox, I don't think it is currently possible to write to the local file system at all, even if the user approves. From Firefox 17 (I think), privileged code can no longer run in a web page, which rules out the old method floating around on the web (e.g. here)

  • IE still has its ActiveX method of doing this, but it's more locked-down than ever and requires various actions by the user to enable it.

  • HTML5 has a file system API which is currently only implemented by new versions of Chrome and Opera. It writes files to a carefully sandboxed location and offers no control over actual file name or path.

  • Safari currently has no way to do this, as far as I can tell.

In general, browsers sensibly offer little or no access to files on the local file system, so it's an unreliable way to log. However, I've written a rough BrowserFileAppender that implements the HTML5 and ActiveX methods which you're welcome to use if you find it helpful:

https://gist.github.com/timdown/6572000