Logging framework for node application with LOG4JS

5)  Going the extra mile with node.js.




1) Logging framework for node application with LOG4JS



LOG4J is a proven logging framework used in Java. The logging style is exactly the same using LOG4JS for node.

1) Get started by creating an express project. Open cmd prompt and under your workspace hit - "express logging_project". If you run into issues and need help with the set up of a express project, please read my previous post here.

2) Now enter into the project created : "cd logging_project" and hit "node app.js".

3) The default express project is created and will run on port 3000. Test the same by launching the URL on browser - "http://localhost:3000"

4) You should see the express text from the index.jade rendered.

5) In the command prompt under the project folder install log4js, "npm install log4js"

6) In the project folder, under routes, let us create a file called logger.js, our custom implementation of the logger.

7) Add the following code to the logger.js

var log4js = require('log4js');
log4js.configure({
appenders: [
   { type: 'console' },
   { type: 'file', filename: "c://test.log", category: 'my_project' }
  ]
});
var logger  = log4js.getLogger('my_project');
            logger.setLevel('DEBUG');
            Object.defineProperty(exports, "LOG", {
                        value:logger,
            });


We have defined two types of loggers here, console and file types. We are employing the logging level to "DEBUG". Expose the logger object as a static variable outside this file using the Object.defineProperty.

To understand the logging hierarchy and for more details, please read here.

8) Let us add the logs say in the index.js. Add the following code under the default method created. index.js code looks as follows:

var logger= require('./logger.js');
var log=logger.LOG;
exports.index = function(req, res){
log.debug("testing the debug log here....................");
log.error("testing the error log here....................");
log.info("testing the info log here....................");
log.warn("testing the warn log here....................");
log.trace("testing the trace log here....................");
  res.render('index', { title: 'Express' });
};

9) Now to the interesting code in the app.js. We add the log4js connectlogger to allow the logging of the express servers as follows.

app.use(log4js.connectLogger(log, { level: log4js.levels.DEBUG }));

To read more on conncetLogger please go here

10) Run the application on the cmd prompt, you should see the following outputs:

a) On the console you will see the logs you have added with respective color codes.

b) Go To C:\test.logs, this path was configured in the logger.js. Opening this you will see the logs added in the application.

The logs can be further customised to track the class name, method name, request URI's to link this to Splunk.

LOG4JS can also be used to log the client side user activities. You can read more about this here.

Happy Logging with LOG4JS ............    :)



5.2) Debugging Node.js Applications


Employing node-inspector to debug a node.js application.


1) Install node-inspector using NPM, "npm install node-inspector"

2) Run the application by pausing on the first line - "node --debug-brk app.js"

3) Start the node inspector - "node-inspector &"

4) Open the debugging console - "http://127.0.0.1:8080/debug?port=5858"

5) Run the application - "http://localhost:3000/"

6) Add appropriate debug points to the scripts and do live debugging.




5.3) Running Node Application as a Windows Service




  1. Download NSSM from http://nssm.cc/download/?page=download
  2. Extract the contents from the download
  3. Open the command prompt and traverse to the folder extracted above.
  4.  Hit “nssm install”
  5.   In the popup that opens: enter the

    •   Application : Path to the node.exe
    •  Options : Path to you node application starting point ie app.js
    • Service Name: TestService ie the service name you wish to have.

  6. Service would be created. You can cross check the same by opening the services.msc  and starting the same.
  7. You can verify the working of the application by opening on the browser.
  8. Uninstalling the service if required :  "nssm remove <service name>"
   A very simple tutorial, however a very powerful feature to have for hosting your node app.


5.4) Getting the system information from node.js application


It has been a very common requirement that we look to display the details of the host system on which the node.js application runs. In this post we will see how to obtain and display the system details and as well as how to read from a package.json from the deployment structure and provide details of the dependent modules.


1) Create an Express - Jade Project

a) Create an express project say File_Upload. If this is your first time to creation of express project, please refer my previous post here.

b) On the command prompt traverse to the project created and hit "node app.js", test this on your favorite browser on the respective port, by default "http://localhost:3000". You should see the Express text gracefully displayed.

2) App.js Code Snippet





/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path')
  , mycache = require('memory-cache');

var app = express();

app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

app.get('/', routes.index);
app.get('/users', user.list);
app.get('/getInfo', routes.getInfo);

http.createServer(app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});

//store root folder dir path in cache
mycache.put("rootFolder", __dirname)
Summary of what is being done in the app.js:

a) We are adding a memory-cache module to store the path of the root directory for future reference. Please note in this context the cache is not must, however the usage of cache is a precursor to the next post.

b) the root folder path is stored to later get reference of the package.json.

c) We define the routes - routes.index to fetch the landing page, routes.getInfo to get the system requirements/details of the host.

3) Code snippet of index.js





/*
 * GET home page.
 */

exports.index = function(req, res){
  res.render('index', { title: 'Application To Obtain System Requirements' });
};


var os = require('os')
  , fs = require('fs')
  , mycache = require('memory-cache');

exports.getInfo = function (req, res) {
    var sysInfo = {
        'NodeVersion': process.version,
        'Platform': os.platform(),
        'Host': os.hostname(),
        'Path': process.execPath
    };

    var modules = {};
    var packageDotJsonObject = JSON.parse(fs.readFileSync(mycache.get("rootFolder") + "/package.json"));
    for (var xModule in packageDotJsonObject.dependencies) {
        modules[xModule] = packageDotJsonObject.dependencies[xModule];
    }

    res.render('sysinfo', {title: 'System Information', "sysInfo": sysInfo, "modules": modules });
};


Summary of what is being done in index.js:

a) We define the route handler to render the landing page ie index.jade

b) We add three dependent modules - OS, FS and MEMORY-CACHE.

c) Using the OS module we get access to the OS variables as required.

d) Process gets access to the node process running. This data is useful in handling clustering of node environment.

e) FS is used to read the package.json from the relative reference from the root dir. The path is obtained from the cache.

f) These details are packed in a JSON and sent to the UI - sysinfo.jade


4) Code snippet of sysinfo.jade



extends ./layout
block content 
            h3 System Information
            table.form_table(align='left', cellpadding='15', cellspacing='15', border='1')
                        each key,val in sysInfo
                                    tr
                                                td <b>#{val}</b>
                                                td #{key}
            table.form_table(align='left', cellpadding='15', cellspacing='15', border='1')
                        each key,val in modules
                                    tr
                                                td <b>#{val}</b>
                                                td #{key}
Summary of what is being done in sysinfo.jade:

a) Using the jade's for loop construct we are dynamically rebdering the data from both the JSONs.
b) Do note the direct access to the key, value pair using two variables simultaneously.


5) Code snippet of the index.jade



extends layout

block content
  h1= title
  p Welcome to #{title}
  a(title='System Info', href="/getInfo") Get the System Information of this Node Application
Summary of what is being done in the index.jade:
a) We add a HREF to make the call to get the system details.

6) Running the application, node app.js in the cmd prompt and opening the app on your favorite browser , you will see following screen on clicking the link:




Please feel free to write to me on your feedback of the post. 


2 comments: