UNPKG

simple-node-logger

Version:

A node console and file logger suitable for small, medium and large production projects.

162 lines (134 loc) 4.37 kB
/** * @class RollingFileAppender * * roll on size and/or date/time; * * @author: darryl.west@raincitysoftware.com * @created: 7/27/14 9:52 AM */ const Logger = require('./Logger'); const AbstractAppender = require('./AbstractAppender'); const dash = require('lodash'); const moment = require('moment'); const path = require('path'); const RollingFileAppender = function(options) { 'use strict'; const appender = this; const fs = options.fs || require('fs'); const newline = /^win/.test(process.platform) ? '\r\n' : '\n'; let typeName = options.typeName; let autoOpen = dash.isBoolean(options.autoOpen) ? options.autoOpen : true; let logDirectory = options.logDirectory; let fileNamePattern = options.fileNamePattern; let dateFormat = options.dateFormat || 'YYYY.MM.DD'; let level = options.level || Logger.DEFAULT_LEVEL; let levels = options.levels || Logger.STANDARD_LEVELS; let currentLevel = levels.indexOf(level); let currentFile = options.currentFile; let rollTimer; let createInterval = options.createInterval || setInterval; let writers = []; if (!typeName) { typeName = options.typeName = 'RollingFileAppender'; } AbstractAppender.extend(this, options); const getWriter = function() { return writers[0]; }; const openWriter = function(fname) { const filename = fname || appender.createFileName(); const file = path.join(logDirectory, filename); const opts = { flags: 'a', encoding: 'utf8' }; let writer = fs.createWriteStream(file, opts); // make this the current writer... writers.unshift(writer); currentFile = file; // now close the current logger and remove from the writers list while (writers.length > 1) { // close the old writer writer = writers.pop(); writer.removeAllListeners(); writer.end('\n'); } }; // check once per minute to see if we need to roll const startRollTimer = function() { rollTimer = createInterval(function() { if (appender.checkForRoll()) { openWriter(); } }, 60 * 1000); }; /** * default formatter for this appender; * @param entry */ this.formatter = function(entry) { const fields = appender.formatEntry(entry); fields.push(newline); return fields.join(appender.separator); }; /** * call formatter then write the entry to the console output * @param entry - the log entry */ this.write = function(entry) { if (levels.indexOf(entry.level) >= currentLevel) { const writer = getWriter(); if (writer) { writer.write(appender.formatter(entry)); } else { /*eslint no-console: "off"*/ console.log('no writer...'); } } }; this.checkForRoll = function(now) { // check to see if the const fn = appender.createFileName(now); const current = path.basename(currentFile); return fn !== current; }; this.createFileName = function(now) { let dt; if (now || now instanceof moment) { dt = now.format(dateFormat); } else { dt = moment().format(dateFormat); } return fileNamePattern.replace(/<DATE>/i, dt); }; this.setLevel = function(level) { const idx = levels.indexOf(level); if (idx >= 0) { currentLevel = idx; } }; this.__protected = function() { return { openWriter: openWriter, currentFile: currentFile, rollTimer: rollTimer, writers: writers }; }; // constructor tests (function() { if (!logDirectory) { throw new Error('appender must be constructed with a log directory'); } if (!fileNamePattern) { throw new Error('appender must be constructed with a file name pattern'); } }()); // now validate the date pattern and file format // date may only contain YMDHAa-. if (autoOpen) { openWriter(); startRollTimer(); } }; module.exports = RollingFileAppender;