UNPKG

apminsight

Version:

monitor nodejs applications

288 lines (264 loc) 7.05 kB
var fs = require("fs"); var path = require("path"); var utils = require("./utils"); var constants = require("./../constants"); var cluster = require("cluster"); var writeStream, fd, logsDir, bytesWritten, baseDir; var newLine = "\n", space = " ", emptyStr = "", underScore = "_"; var maxSize = 10 * 1024 * 1024; // 10 MB var retentionDays = 10; var levels = { DEBUG: 5, INFO: 4, WARNING: 3, CRITICAL: 2, ERROR: 1, OFF: 0 }; function init(configInstance) { const dir = configInstance && configInstance.getBaseDir(); if (utils.isEmpty(dir)) { console.error("[APM] Base directory is not set in the configuration."); writeStream = process.stdout; return; } utils.fetchAppname(configInstance); var appName = configInstance.getApplicationName(); baseDir = dir; var date = new Date(); var month = date.getMonth() + 1; var dateStr = date.getDate() + underScore + month + underScore + date.getFullYear() + underScore + date.getHours() + underScore + date.getMinutes() + underScore + date.getSeconds() + underScore + date.getMilliseconds() + underScore + process.pid + underScore + appName; try { logsDir = path.join(baseDir, "logs"); if (!fs.existsSync(logsDir)) { try { fs.mkdirSync(logsDir); } catch (dirErr) { console.error(`[APM] Failed to create logs directory: ${dirErr.message}`, dirErr); writeStream = process.stdout; return; } } cleanLogFiles(); var filePath = path.join( logsDir, "apminsight_agent_logs_" + dateStr + ".log" ); try { fd = fs.openSync(filePath, "a"); if (writeStream) { try { writeStream.end(); } catch (streamEndErr) { console.error(`[APM] Failed to close previous write stream: ${streamEndErr.message}`, streamEndErr); } } writeStream = fs.createWriteStream(null, { flags: "a", fd: fd }); writeStream.on("error", handleStreamError); bytesWritten = 0; } catch (fileErr) { console.error(`[APM] Failed to open log file: ${fileErr.message}`, fileErr); writeStream = process.stdout; } } catch (err) { console.error( `[APM] Failed to create apminsight agent logs at ${filePath || 'unknown path'}:`, err ); } //scheduleLogFileSwapping(); } /* eslint-disable no-unused-vars */ function scheduleLogFileSwapping() { var now = new Date(); var night = new Date( now.getFullYear(), now.getMonth(), now.getDate() + 1, 0, 0, 30 ); var msToMidnight = night.getTime() - now.getTime(); setTimeout(function () { if (!global.apmInsightAgentInstance) { console.error("[APM] schedule log file swap max size exceeded and no agent instance available to reinitialize."); return; } init(global.apmInsightAgentInstance.getConfig()); }, msToMidnight).unref(); } function cleanLogFiles() { if (!cluster.isMaster) { return; } fs.readdir(logsDir, function (err, files) { if (err) { return; } var now = new Date(); now.setDate(now.getDate() - retentionDays); var retentionTime = now.getTime(); files.forEach(function (file, index) { checkAndRemoveFile(path.join(logsDir, file), retentionTime); }); }); } /* eslint-enable no-unused-vars */ function checkAndRemoveFile(filePath, retentionTime) { fs.stat(filePath, function (err, stat) { if (err) { return; } if (stat.mtime.getTime() < retentionTime) { removeFile(filePath); } }); } function removeFile(filePath) { fs.unlink(filePath, function (err) { if (err) { return; } }); log(constants.info, "old log files removed properly"); } function error(message, e) { write(constants.error, message, getStackTrace, e); } function logAndThrowError(level, message, obj) { log(level, message, obj); throw new Error(message); } function debug(message, obj) { log(constants.debug, message, obj); } function info(message, obj) { log(constants.info, message, obj); } function critical(message, obj) { log(constants.critical, message, obj); } function warning(message, obj) { log(constants.warning, message, obj); } function log(level, message, obj) { write(level, message, stringify, obj); } /* eslint-disable no-unused-vars */ function handleStreamError(error) { //need to handle error } /* eslint-enable no-unused-vars */ function write(level, message, toStr, obj) { if (!writeStream) { console.error("[APM] WriteStream is not initialized."); return; } if (!isAllowed(levels[level])) { return; } if (bytesWritten > maxSize) { if (!global.apmInsightAgentInstance) { console.error("[APM] Write max size exceeded and no agent instance available to reinitialize."); return; } init(global.apmInsightAgentInstance.getConfig()); } var writeStr = getTime() + space + "[" + level + "]" + space + message + space + toStr(obj) + newLine; bytesWritten += Buffer.byteLength(writeStr); writeStream.write(writeStr); } function isAllowed(level) { if (level <= getLogConf()) { return true; } return false; } function getLogConf() { if (!global.apmInsightAgentInstance) { return levels.DEBUG; } if (levels[utils.getGenericThreshold().getLogLevel()]) { return levels[utils.getGenericThreshold().getLogLevel()]; } return levels.DEBUG; } function getTime() { var date = new Date(); var month = date.getMonth() + 1; return ( "[" + date.getDate() + "/" + month + "/" + date.getFullYear() + space + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + "]" ); } function getStackTrace(e) { try { if (utils.isEmpty(e)) { return emptyStr; } return e.stack; } catch (e) { return emptyStr; } } function stringify(obj) { try { if (utils.isEmpty(obj)) { return emptyStr; } return JSON.stringify(obj); } catch (e) { return emptyStr; } } module.exports = { init: init, debug: debug, info: info, warning: warning, critical: critical, error: error, logAndThrowError: logAndThrowError };