UNPKG

ca-apm-probe

Version:

CA APM Node.js Agent monitors real-time health and performance of Node.js applications

229 lines (202 loc) 6.82 kB
/** * Copyright (c) 2015 CA. All rights reserved. * * This software and all information contained therein is confidential and proprietary and * shall not be duplicated, used, disclosed or disseminated in any way except as authorized * by the applicable license agreement, without the express written permission of CA. All * authorized reproductions must be marked with this language. * * EXCEPT AS SET FORTH IN THE APPLICABLE LICENSE AGREEMENT, TO THE EXTENT * PERMITTED BY APPLICABLE LAW, CA PROVIDES THIS SOFTWARE WITHOUT WARRANTY * OF ANY KIND, INCLUDING WITHOUT LIMITATION, ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL CA BE * LIABLE TO THE END USER OR ANY THIRD PARTY FOR ANY LOSS OR DAMAGE, DIRECT OR * INDIRECT, FROM THE USE OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, LOST * PROFITS, BUSINESS INTERRUPTION, GOODWILL, OR LOST DATA, EVEN IF CA IS * EXPRESSLY ADVISED OF SUCH LOSS OR DAMAGE. */ var winston = require('winston'); var fs = require('fs'); var path = require('path'); var config = require('./configdata').getConfigData(); var logFile = config.logging.logFile; var enableFileMode = config.logging.fileModeLog == "enabled"; var enableConsoleMode = config.logging.consoleModeLog == "enabled"; var maxLogFileSize = (config.logging.maxLogFileSize || 2) * 1024 * 1024; // MB to byte var maxLogFileCount = config.logging.maxLogFileCount || 5; var logLevel = config.logging.logLevel || 'info'; var isDebugEnabled = false; var isVerboseEnabled = false; var logToConsole = false; var isDeepStackTraceEnabled = false; var savedDeepStackTraceLimit = -1; var probeNameResolver = require('./probename-resolver'); function logConfiguration() { config = require('./configdata').getConfigData(); if (config.logging) { var logLevelProp = config.logging.logLevel; if (logLevelProp.toLowerCase() !== logLevel.toLowerCase()) { var prevLogLevel = logLevel; logLevel = logLevelProp.toLowerCase(); if (logger) { logger.level = logLevel; logger.info('log level changed %s -> %s', prevLogLevel, logLevel); } } var isDeepStackTraceFlag = (config.logging.deepStackTraceEnabled == undefined) ? false : config.logging.deepStackTraceEnabled; if (isDeepStackTraceFlag) { if (!isDeepStackTraceEnabled) { savedDeepStackTraceLimit = Error.stackTraceLimit; Error.stackTraceLimit = Infinity; isDeepStackTraceEnabled = true; } } else { if (isDeepStackTraceEnabled && Error.stackTraceLimit == Infinity && savedDeepStackTraceLimit != -1) { Error.stackTraceLimit = savedDeepStackTraceLimit; } isDeepStackTraceEnabled = false; } enableFileMode = config.logging.fileModeLog == "enabled"; enableConsoleMode = config.logging.consoleModeLog == "enabled"; maxLogFileCount = config.logging.maxLogFileCount || 5; maxLogFileSize = (config.logging.maxLogFileSize || 2) * 1024 * 1024; // MB to byte } if (logLevel === 'debug') { isDebugEnabled = true; isVerboseEnabled = true; } if (logLevel === 'verbose') { isVerboseEnabled = true; } } function checkPermissions(){ if(!logger) { return; } try { var stats = fs.statSync(logFile); } catch(err) { // file does not exist, so no need to check for permissions return; } // logFile has write permission if (!(stats["mode"] & 200)) { logger.transports[1].silent = false; logger.transports[0].silent = true; logger.info("Log file "+logFile+" does not have write permissions. Hence logging to console"); logToConsole = true; } } function createLogsFolderIfDontExist(){ try{ fs.mkdirSync(path.dirname(logFile)); } catch(e) { if(e.code == 'EEXIST') { return; } else { // creation threw other error like access denied or something, so log to console in that case. logger.transports[1].silent = false; logger.transports[0].silent = true; logger.info("Log folder "+path.dirname(logFile)+" cannot be created. Hence logging to console"); logToConsole = true; } } } function logFromBuffer() { var buffer = probeNameResolver.getBuffer(); if(buffer) { var infoArr = buffer.info; for(var entry in infoArr) { logger.info(infoArr[entry]); } if(logger.isDebug()) { var debugArr = buffer.debug; for(var entry in debugArr) { logger.debug(debugArr[entry]); } } } } var transport = new winston.transports.File({ filename: logFile, handleExceptions: false, maxsize: maxLogFileSize, maxFiles: maxLogFileCount, colorize: false, silent: !enableFileMode }); var consoleTransport = new winston.transports.Console({ name: 'console', silent: !enableConsoleMode, format: winston.format.combine( winston.format.colorize({ all : true }) ), }); const customFormat = winston.format.printf(({ timestamp, level, message }) => { return `${timestamp} - ${level}: ${message}`; }); var logger = winston.createLogger({ format: winston.format.combine( winston.format.timestamp({ format: 'YYYY/MM/DD HH:mm:ss:SSSZ' }), winston.format.splat(), customFormat ), level: logLevel, transports: [ transport, consoleTransport ] }); createLogsFolderIfDontExist(); checkPermissions(); logConfiguration(); console.log("[CA APM PROBE] monitoring application with pid "+ process.pid); if(!logToConsole && logLevel.toLowerCase() !== 'disabled') { console.log("[CA APM PROBE] Log file location: " + path.normalize(logFile)); } logger.isDebug = function(){ return isDebugEnabled; }; logger.isVerbose = function(){ return isVerboseEnabled; }; logger.setLabel = function(str) { transport.label = str; }; logFromBuffer(); var disableLogger = { debug: function(){}, verbose: function(){}, info: function(){}, error: function(){}, fatal: function(){}, log: function(){}, warn: function(){}, isDebug: function() { return false; }, isVerbose: function() { return false; }, setLabel: function() {} }; var wrappedLogger = { debug: function(){ if (isDebugEnabled) logger.debug.apply(logger, arguments); }, verbose: function(){ if (isVerboseEnabled) logger.verbose.apply(logger, arguments); }, info: function(){ logger.info.apply(logger, arguments); }, error: function(){ logger.error.apply(logger, arguments); }, fatal: function(){ logger.fatal.apply(logger, arguments); }, log: function(){ logger.log.apply(logger, arguments); }, warn: function(){ logger.warn.apply(logger, arguments); }, isDebug: function() { return isDebugEnabled; }, isVerbose: function() { return isVerboseEnabled; }, setLabel: function(str) { logger.setLabel(str); } }; if (logLevel.toLowerCase() === 'disabled') { module.exports = disableLogger; } else { module.exports = wrappedLogger; } module.exports.logConfiguration = logConfiguration;