cklanac
8/15/2017 - 8:53 PM

Morgan, Winston and Loggly

Morgan, Winston and Loggly

'use strict';
const { LOGGLY_TOKEN } = require('../config');

/**
 * [Winston](https://github.com/winstonjs/winston)
 * A multi-tranport async logging library
 * 
 * Use winston to implement our logger, but the rest of the app uses
 * the generic logger interface that we export. This decouples logging 
 * logic in our code from implementation with Winston.
 * 
 * [Winston Loggly Bulk](https://github.com/loggly/winston-loggly-bulk)
 * A version of `winston-loggly` which is maintained by Loggly. Use this 
 * instead of the original because it ties into Loggly documentation
 */

var winston = require('winston');
require('winston-loggly-bulk');

var logger = new winston.Logger({
  transports: [
    new winston.transports.File({
      level:            'info',
      filename:         './server.log',
      handleExceptions: true,
      json:             true,
      maxsize:          5242880, //5MB
      maxFiles:         5,
      colorize:         true
    }),  
    new winston.transports.Console({ 
      level:            'debug', 
      handleExceptions: true, 
      json:             false, 
      colorize:         true 
    }),
    new winston.transports.Loggly({
      token: LOGGLY_TOKEN,
      subdomain: 'bellyful',
      tags: ['Winston-NodeJS', (process.env.NODE_ENV || 'DEV')],
      json: true
    })
  ], 
  exitOnError: false 
});

logger.stream = { 
  write: function(message, encoding){ 
    // use message.trim() to remove empty line between logged lines
    // https://stackoverflow.com/a/28824464/3109731
    logger.info(message.trim()); 
  } 
}; 

module.exports = {logger};
'use strict';

const express = require('express');

const morgan = require('morgan');

const { logger } = require('./utilities/logger');


const app = express();

/**
 * [Morgan](https://github.com/expressjs/morgan)
 * Use logger before routes so it logs all requests
 * 
 * By default, morgan sends the output to stdout which is the console
 *  `app.use(morgan('common'));`
 * 
 * Custom log output example:
 *  `app.use(morgan(':date[iso] :method :url :response-time'));`
 * 
 * Configure morgan to send the output to our logger's stream instead
 */
app.use(morgan('common', { stream: logger.stream }));
      res.status(500).json({ message: 'Internal server error' });
    });
});

/**
 * REMOVED FOR BREVITY
 */

// catch-all endpoint if client makes request to non-existent endpoint
app.use('*', function (req, res) {
  res.status(404).json({ message: 'Not Found' });
});

// Only run this section if file is loaded directly (eg `node server.js`)
// Fixes error: "Trying to open unclosed connection."
if (require.main === module) {

  // TODO: Abstract to runServer(PORT); 
  const server = app
    .listen(PORT, () => {
      console.info(`App listening on port ${server.address().port}`);
    })
    .on('error', err => {
      console.error(err);
    });
}

module.exports = { app }; // for testing