{"version":3,"sources":["jsdelivr-header.js","/npm/pm2-logrotate-azure-upload@1.0.3/app.js"],"names":[],"mappings":"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","file":"/npm/pm2-logrotate-azure-upload@1.0.3/app.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/pm2-logrotate-azure-upload@1.0.3/app.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","var fs = require('graceful-fs');\nvar path = require('path');\nvar pmx = require('pmx');\nvar pm2 = require('pm2');\nvar dayjs = require('dayjs');\nvar timezone = require('dayjs/plugin/timezone')\nvar scheduler = require('node-schedule');\nvar zlib = require('zlib');\nvar deepExtend = require('deep-extend');\nvar { BlobServiceClient } = require('@azure/storage-blob');\n\nvar conf = pmx.initModule({\n  widget: {\n    type: 'generic',\n    logo: 'https://raw.githubusercontent.com/riazXrazor/pm2-logrotate-azure-upload/master/pres/logo.png',\n    theme: ['#111111', '#1B2228', '#31C2F1', '#807C7C'],\n    el: {\n      probes: false,\n      actions: false\n    },\n    block: {\n      issues: true,\n      cpu: true,\n      mem: true,\n      actions: true,\n      main_probes: ['Global logs size', 'Files count']\n    }\n  }\n});\nvar PM2_ROOT_PATH = '';\nvar Probe = pmx.probe();\nvar SERVER_PUBLIC_IP;\n\nif (process.env.PM2_HOME)\n  PM2_ROOT_PATH = process.env.PM2_HOME;\nelse if (process.env.HOME && !process.env.HOMEPATH)\n  PM2_ROOT_PATH = path.resolve(process.env.HOME, '.pm2');\nelse if (process.env.HOME || process.env.HOMEPATH)\n  PM2_ROOT_PATH = path.resolve(process.env.HOMEDRIVE, process.env.HOME || process.env.HOMEPATH, '.pm2');\n\ntry {\n  var customConfig = require(path.resolve(PM2_ROOT_PATH, 'pm2-logrotate-azure-upload-config.js'));\n  conf = deepExtend(conf, customConfig);\n} catch (error) { }\n\nif (process.env.SERVER_PUBLIC_IP && typeof process.env.SERVER_PUBLIC_IP === 'string') {\n  SERVER_PUBLIC_IP = process.env.SERVER_PUBLIC_IP;\n  console.log('ENV SERVER_PUBLIC_IP: ', SERVER_PUBLIC_IP);\n} else if (conf && conf.serverIp) {\n  SERVER_PUBLIC_IP = conf.serverIp;\n  console.log('CONF SERVER_PUBLIC_IP: ', SERVER_PUBLIC_IP);\n}\n\nvar WORKER_INTERVAL = isNaN(parseInt(conf.workerInterval)) ? 30 * 1000 : parseInt(conf.workerInterval) * 1000; // default: 30 secs\nvar SIZE_LIMIT = get_limit_size(); // default : 10MB\nvar ROTATE_CRON = conf.rotateInterval || \"0 0 * * *\"; // default : every day at midnight\nvar RETAIN = isNaN(parseInt(conf.retain)) ? undefined : parseInt(conf.retain); // All\nvar COMPRESSION = JSON.parse(conf.compress) || false; // Do not compress by default\nvar DATE_FORMAT = conf.dateFormat || 'YYYY-MM-DD_HH-mm-ss';\nvar TZ = conf.TZ;\nvar ROTATE_MODULE = JSON.parse(conf.rotateModule) || true;\nvar WATCHED_FILES = [];\n\nfunction get_limit_size() {\n  if (conf.max_size === '')\n    return (1024 * 1024 * 10);\n  if (typeof (conf.max_size) !== 'string')\n    conf.max_size = conf.max_size + \"\";\n  if (conf.max_size.slice(-1) === 'G')\n    return (parseInt(conf.max_size) * 1024 * 1024 * 1024);\n  if (conf.max_size.slice(-1) === 'M')\n    return (parseInt(conf.max_size) * 1024 * 1024);\n  if (conf.max_size.slice(-1) === 'K')\n    return (parseInt(conf.max_size) * 1024);\n  return parseInt(conf.max_size);\n}\n\nfunction delete_old(file) {\n  if (file === \"/dev/null\") return;\n  var fileBaseName = file.substring(0, file.length - 4).split(path.sep).pop() + \"__\";\n  var dirName = path.dirname(file);\n\n  fs.readdir(dirName, function (err, files) {\n    var i, len;\n    if (err) return pmx.notify(err);\n\n    var rotated_files = [];\n    for (i = 0, len = files.length; i < len; i++) {\n      if (files[i].indexOf(fileBaseName) >= 0)\n        rotated_files.push(files[i]);\n    }\n    rotated_files.sort().reverse();\n    for (i = rotated_files.length - 1; i >= RETAIN; i--) {\n      (function (i) {\n\n        if (\n          conf.azureStorageContainer\n          && conf.azureStorageConnectionString\n        ) {\n          var currentTime = new Date();\n          var key = `${(conf.azureFilePathFormat || '__filename__')\n            .replace(/__ip__/, SERVER_PUBLIC_IP || '')\n            .replace(/__year__/, currentTime.getFullYear())\n            .replace(/__month__/, currentTime.getMonth() + 1)\n            .replace(/__day__/, currentTime.getDate())\n            .replace(/__filename__/, rotated_files[i])\n            .replace(/__epoch__/, currentTime.getTime())\n            }`;\n          console.log('KEY: ', key);\n\n          const blobServiceClient = BlobServiceClient.fromConnectionString(\n            conf.azureStorageConnectionString\n          );\n\n          const containerClient = blobServiceClient.getContainerClient(conf.azureStorageContainer);\n\n          const blockBlobClient = containerClient.getBlockBlobClient(key);\n\n          const data = fs.readFileSync(path.resolve(dirName, rotated_files[i]))\n\n          blockBlobClient.upload(data, data.length)\n            .then(() => {\n\n              console.log(`${rotated_files[i]} has been uploaded to ${key}`);\n              return fs.unlink(path.resolve(dirName, rotated_files[i]), function (err) {\n                if (err) return console.error(err);\n                console.log('\"' + rotated_files[i] + '\" has been deleted');\n              });\n\n            })\n            .catch(error => {\n              console.error(JSON.stringify(error));\n            });\n        }\n      })(i);\n    }\n  });\n}\n\n\n/**\n * Apply the rotation process of the log file.\n *\n * @param {string} file\n */\nfunction proceed(file) {\n  // set default final time\n  var final_time = dayjs().format(DATE_FORMAT);\n  // check for a timezone\n  if (TZ) {\n    try {\n      dayjs.extend(timezone);\n      final_time = dayjs().tz(TZ).format(DATE_FORMAT);\n    } catch (err) {\n      // use default\n    }\n  }\n  var final_name = file.substring(0, file.length - 4) + '__' + final_time + '.log';\n  // if compression is enabled, add gz extention and create a gzip instance\n  if (COMPRESSION) {\n    var GZIP = zlib.createGzip({ level: zlib.constants.Z_BEST_COMPRESSION, memLevel: zlib.constants.Z_BEST_COMPRESSION });\n    final_name += \".gz\";\n  }\n\n  // create our read/write streams\n  var readStream = fs.createReadStream(file);\n  var writeStream = fs.createWriteStream(final_name, { 'flags': 'w+' });\n\n  // pipe all stream\n  if (COMPRESSION)\n    readStream.pipe(GZIP).pipe(writeStream);\n  else\n    readStream.pipe(writeStream);\n\n\n  // listen for error\n  readStream.on('error', pmx.notify.bind(pmx));\n  writeStream.on('error', pmx.notify.bind(pmx));\n  if (COMPRESSION) {\n    GZIP.on('error', pmx.notify.bind(pmx));\n  }\n\n  // when the read is done, empty the file and check for retain option\n  writeStream.on('finish', function () {\n    if (GZIP) {\n      GZIP.close();\n    }\n    readStream.close();\n    writeStream.close();\n    fs.truncate(file, function (err) {\n      if (err) return pmx.notify(err);\n      console.log('\"' + final_name + '\" has been created');\n\n      if (typeof (RETAIN) === 'number')\n        delete_old(file);\n    });\n  });\n}\n\n\n/**\n * Apply the rotation process if the `file` size exceeds the `SIZE_LIMIT`.\n *\n * @param {string} file\n * @param {boolean} force - Do not check the SIZE_LIMIT and rotate everytime.\n */\nfunction proceed_file(file, force) {\n  if (!fs.existsSync(file)) return;\n\n  if (!WATCHED_FILES.includes(file)) {\n    WATCHED_FILES.push(file);\n  }\n\n  fs.stat(file, function (err, data) {\n    if (err) return console.error(err);\n\n    if (data.size > 0 && (data.size >= SIZE_LIMIT || force))\n      proceed(file);\n  });\n}\n\n\n/**\n * Apply the rotation process of all log files of `app` where the file size exceeds the`SIZE_LIMIT`.\n *\n * @param {Object} app\n * @param {boolean} force - Do not check the SIZE_LIMIT and rotate everytime.\n */\nfunction proceed_app(app, force) {\n  // Check all log path\n  // Note: If same file is defined for multiple purposes, it will be processed once only.\n  if (app.pm2_env.pm_out_log_path) {\n    proceed_file(app.pm2_env.pm_out_log_path, force);\n  }\n  if (app.pm2_env.pm_err_log_path && app.pm2_env.pm_err_log_path !== app.pm2_env.pm_out_log_path) {\n    proceed_file(app.pm2_env.pm_err_log_path, force);\n  }\n  if (app.pm2_env.pm_log_path && app.pm2_env.pm_log_path !== app.pm2_env.pm_out_log_path && app.pm2_env.pm_log_path !== app.pm2_env.pm_err_log_path) {\n    proceed_file(app.pm2_env.pm_log_path, force);\n  }\n}\n\n// Connect to local PM2\npm2.connect(function (err) {\n  if (err) return console.error(err.stack || err);\n\n  // start background task\n  setInterval(function () {\n    // get list of process managed by pm2\n    pm2.list(function (err, apps) {\n      if (err) return console.error(err.stack || err);\n\n      // rotate log that are bigger than the limit\n      apps.forEach(function (app) {\n        // if its a module and the rotate of module is disabled, ignore\n        if (typeof (app.pm2_env.axm_options.isModule) !== 'undefined' && !ROTATE_MODULE) return;\n        proceed_app(app, false);\n      });\n    });\n\n    // rotate pm2 log\n    proceed_file(PM2_ROOT_PATH + '/pm2.log', false);\n    proceed_file(PM2_ROOT_PATH + '/agent.log', false);\n  }, WORKER_INTERVAL);\n\n  // register the cron to force rotate file\n  scheduler.scheduleJob(ROTATE_CRON, function () {\n    // get list of process managed by pm2\n    pm2.list(function (err, apps) {\n      if (err) return console.error(err.stack || err);\n\n      // force rotate for each app\n      apps.forEach(function (app) {\n        // if its a module and the rotate of module is disabled, ignore\n        if (typeof (app.pm2_env.axm_options.isModule) !== 'undefined' && !ROTATE_MODULE) return;\n\n        proceed_app(app, true);\n      });\n    });\n  });\n});\n\n/**  ACTION PMX **/\npmx.action('list watched logs', function (reply) {\n  var returned = {};\n  WATCHED_FILES.forEach(function (file) {\n    returned[file] = (fs.statSync(file).size);\n  });\n  return reply(returned);\n});\n\npmx.action('list all logs', function (reply) {\n  var returned = {};\n  var folder = PM2_ROOT_PATH + \"/logs\";\n  fs.readdir(folder, function (err, files) {\n    if (err) {\n      console.error(err.stack || err);\n      return reply(0)\n    }\n\n    files.forEach(function (file) {\n      returned[file] = (fs.statSync(folder + \"/\" + file).size);\n    });\n    return reply(returned);\n  });\n});\n\n/** PROB PMX **/\nvar metrics = {};\nmetrics.totalsize = Probe.metric({\n  name: 'Global logs size',\n  value: 'N/A'\n});\n\nmetrics.totalcount = Probe.metric({\n  name: 'Files count',\n  value: 'N/A'\n});\n\n// update folder size of logs every 10secs\nfunction updateFolderSizeProbe() {\n  var returned = 0;\n  var folder = PM2_ROOT_PATH + \"/logs\";\n  fs.readdir(folder, function (err, files) {\n    if (err) {\n      console.error(err.stack || err);\n      return metrics.totalsize.set(\"N/A\");\n    }\n\n    files.forEach(function (file, idx, arr) {\n      returned += fs.statSync(folder + \"/\" + file).size;\n    });\n\n    metrics.totalsize.set(handleUnit(returned, 2));\n  });\n}\nupdateFolderSizeProbe();\nsetInterval(updateFolderSizeProbe, 30000);\n\n// update file count every 10secs\nfunction updateFileCountProbe() {\n  fs.readdir(PM2_ROOT_PATH + \"/logs\", function (err, files) {\n    if (err) {\n      console.error(err.stack || err);\n      return metrics.totalcount.set(0);\n    }\n\n    return metrics.totalcount.set(files.length);\n  });\n}\nupdateFileCountProbe();\nsetInterval(updateFileCountProbe, 30000);\n\nfunction handleUnit(bytes, precision) {\n  var kilobyte = 1024;\n  var megabyte = kilobyte * 1024;\n  var gigabyte = megabyte * 1024;\n  var terabyte = gigabyte * 1024;\n\n  if ((bytes >= 0) && (bytes < kilobyte)) {\n    return bytes + ' B';\n  } else if ((bytes >= kilobyte) && (bytes < megabyte)) {\n    return (bytes / kilobyte).toFixed(precision) + ' KB';\n  } else if ((bytes >= megabyte) && (bytes < gigabyte)) {\n    return (bytes / megabyte).toFixed(precision) + ' MB';\n  } else if ((bytes >= gigabyte) && (bytes < terabyte)) {\n    return (bytes / gigabyte).toFixed(precision) + ' GB';\n  } else if (bytes >= terabyte) {\n    return (bytes / terabyte).toFixed(precision) + ' TB';\n  } else {\n    return bytes + ' B';\n  }\n}\n"]}