UNPKG

sgapps-server

Version:
467 lines (396 loc) 23.9 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>decorators/access-logger.js - SGApps Server - Framework</title> <meta name="description" content="SGApps Server for high performance results" /> <meta name="keywords" content="javascript, js, application-prototype, prototype" /> <meta name="keyword" content="javascript, js, application-prototype, prototype" /> <meta property="og:title" content="SGApps Server - Framework"/> <meta property="og:type" content="website"/> <meta property="og:image" content=""/> <meta property="og:url" content="https://labs.sgapps.io/open-source/sgapps-server"/> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc.css"> <script src="scripts/nav.js" defer></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav class="wrap"> <input type="text" id="nav-search" placeholder="Search" /> <h2><a href="index.html">Home</a></h2><h2><a href="https://labs.sgapps.io/open-source/sgapps-server" target="_blank" class="menu-item" id="website_link" >Project Page ( Git Lab )</a></h2><h2><a href="http://gordienco.net/" target="_blank" class="menu-item" id="website_link" >About Me</a></h2><h2><a href="https://labs.sgapps.io/open-source/sgapps-server" target="_blank" class="menu-item" id="github_link" >GitHub</a></h2><h3>Classes</h3><ul><li><a href="AccessLogger.html">AccessLogger</a><ul class='methods'><li data-type='method' style='display: none;'><a href="AccessLogger.html#formattedDate">formattedDate</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getProtocol">getProtocol</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getReferer">getReferer</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getRemoteIp">getRemoteIp</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getSize">getSize</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getUsername">getUsername</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#logRequest">logRequest</a></li></ul></li><li><a href="FaceboxTemplate.html">FaceboxTemplate</a><ul class='methods'><li data-type='method' style='display: none;'><a href="FaceboxTemplate.html#render">render</a></li><li data-type='method' style='display: none;'><a href="FaceboxTemplate.html#renderCode">renderCode</a></li><li data-type='method' style='display: none;'><a href="FaceboxTemplate.html#renderFile">renderFile</a></li></ul></li><li><a href="FSLibrary.html">FSLibrary</a></li><li><a href="LoggerBuilder.html">LoggerBuilder</a><ul class='methods'><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#decorateGlobalLogger">decorateGlobalLogger</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#error">error</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#info">info</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#log">log</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#prettyCli">prettyCli</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#prompt">prompt</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#warn">warn</a></li></ul></li><li><a href="SGAppsServer.html">SGAppsServer</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServer.html#all">all</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#connect">connect</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#delete">delete</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#Email">Email</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#finalHandler">finalHandler</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#get">get</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handle">handle</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handleErrorRequest">handleErrorRequest</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handlePostData">handlePostData</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handleRequest">handleRequest</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handleStaticRequest">handleStaticRequest</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#head">head</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#options">options</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#patch">patch</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#post">post</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#put">put</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#server">server</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#trace">trace</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#use">use</a></li></ul></li><li><a href="SGAppsServer.NodeJsMvc.html">NodeJsMvc</a></li><li class="level-hide"><a href="SGAppsServer.NodeJsMvc.Controller.html">Controller</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#actionExists">actionExists</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#addAction">addAction</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#addView">addView</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#getAction">getAction</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#getView">getView</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#removeAction">removeAction</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#removeView">removeView</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#render">render</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#viewExists">viewExists</a></li></ul></li><li class="level-hide"><a href="SGAppsServer.NodeJsMvc.Controller.Action.html">Action</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.Action.html#run">run</a></li></ul></li><li><a href="SGAppsServerDecoratorsLibrary.html">SGAppsServerDecoratorsLibrary</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerDecoratorsLibrary.html#.AccessLoggerDecorator">AccessLoggerDecorator</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerDecoratorsLibrary.html#.NodeJsMvcDecorator">NodeJsMvcDecorator</a></li></ul></li><li><a href="SGAppsServerDictionary.html">SGAppsServerDictionary</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerDictionary.html#generatePathKey">generatePathKey</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerDictionary.html#push">push</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerDictionary.html#run">run</a></li></ul></li><li><a href="SGAppsServerEmail.html">SGAppsServerEmail</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#.from">from</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#.isValidAddress">isValidAddress</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#.timeout">timeout</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#send">send</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#valid">valid</a></li></ul></li><li><a href="SGAppsServerRequest.html">SGAppsServerRequest</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerRequest.html#_parseDeepFieldName">_parseDeepFieldName</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerRequest.html#getMountUpdatedUrl">getMountUpdatedUrl</a></li></ul></li><li><a href="SGAppsServerRequestCookie.html">SGAppsServerRequestCookie</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerRequestCookie.html#get">get</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerRequestCookie.html#set">set</a></li></ul></li><li><a href="SGAppsServerRequestSession.html">SGAppsServerRequestSession</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerRequestSession.html#destroy">destroy</a></li></ul></li><li><a href="SGAppsServerResponse.html">SGAppsServerResponse</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#pipeFile">pipeFile</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#pipeFileStatic">pipeFileStatic</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#redirect">redirect</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#send">send</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#sendError">sendError</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#sendStatusCode">sendStatusCode</a></li></ul></li><li><a href="SGAppsServerShared.html">SGAppsServerShared</a></li><li><a href="SGAppsSessionManager.html">SGAppsSessionManager</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsSessionManager.html#handleRequest">handleRequest</a></li><li data-type='method' style='display: none;'><a href="SGAppsSessionManager.html#removeExpiredSessions">removeExpiredSessions</a></li></ul></li><li><a href="TemplateManager.html">TemplateManager</a><ul class='methods'><li data-type='method' style='display: none;'><a href="TemplateManager.html#add">add</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#addList">addList</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#get">get</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#remove">remove</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#render">render</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#templateExists">templateExists</a></li></ul></li><li><a href="TemplateManagerViewer.html">TemplateManagerViewer</a><ul class='methods'><li data-type='method' style='display: none;'><a href="TemplateManagerViewer.html#render">render</a></li><li data-type='method' style='display: none;'><a href="TemplateManagerViewer.html#renderCode">renderCode</a></li></ul></li></ul><h3>Global</h3><ul><li><a href="global.html#LoggerBuilderPrompt">LoggerBuilderPrompt</a></li><li><a href="global.html#MountUpdatedURL">MountUpdatedURL</a></li><li><a href="global.html#RequestHandler">RequestHandler</a></li><li><a href="global.html#RequestPathStructure">RequestPathStructure</a></li><li><a href="global.html#RequestPathStructureMap">RequestPathStructureMap</a></li><li><a href="global.html#RequestSessionDecorator">RequestSessionDecorator</a></li><li><a href="global.html#ResourcesExtensions">ResourcesExtensions</a></li><li><a href="global.html#routeMatch">routeMatch</a></li><li><a href="global.html#SGAppsServerDecorator">SGAppsServerDecorator</a></li><li><a href="global.html#SGAppsServerDictionaryRunCallBack">SGAppsServerDictionaryRunCallBack</a></li><li><a href="global.html#SGAppsServerErrorCallBack">SGAppsServerErrorCallBack</a></li><li><a href="global.html#SGAppsServerErrorOnlyCallback">SGAppsServerErrorOnlyCallback</a></li><li><a href="global.html#SGAppsServerHandlerPostData">SGAppsServerHandlerPostData</a></li><li><a href="global.html#SGAppsServerOptions">SGAppsServerOptions</a></li><li><a href="global.html#SGAppsServerRequestFile">SGAppsServerRequestFile</a></li><li><a href="global.html#SGAppsServerRequestPostDataItem">SGAppsServerRequestPostDataItem</a></li><li><a href="global.html#SGAppsServerRequestSessionCache">SGAppsServerRequestSessionCache</a></li><li><a href="global.html#SGAppsSessionManagerOptions">SGAppsSessionManagerOptions</a></li><li><a href="global.html#TemplateManagerRenderOptions">TemplateManagerRenderOptions</a></li><li><a href="global.html#TemplateManagerTemplate">TemplateManagerTemplate</a></li></ul> </nav> <div id="main"> <h1 class="page-title">decorators/access-logger.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>var _fs = require("fs"); var _path = require("path"); var _cluster = require("cluster"); /** * @class * @name AccessLogger * @description Access Logger for HTTP Web Servers */ function AccessLogger() { this.months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; /** * @memberof AccessLogger# * @name combined * @type {boolean} * @description log format as combined, with user agent: %h %e %^[%x] "%r" %s %b "%R" "{%u}" */ this.combined = false; /** * @memberof AccessLogger# * @name logsIncludeHostname * @type {boolean} * @description log format for vhosts %v, ex: %h %e %^[%x] "{%v}" "%r" %s %b "%R" */ this.logsIncludeHostname = false; }; /** * @memberof AccessLogger# * @description for go access: tail -c 67108864 -f '/var/logs/default/2024/2/data-master.log' | goaccess --log-format='%h %e %^[%x] "%v" "%r" %s %b "%R" "%u"' --date-format='%d/%b/%Y:%H:%M:%S %z' --time-format='%d/%b/%Y:%H:%M:%S %z' - * with combined and logger %h %e %^[%x] "%r" %s %b "%R" * @method logRequest * @param {IncomingMessage} request * @param {ServerResponse} response * @returns {string} */ AccessLogger.prototype.logRequest = function (request, response) { // %h %e %^[%x] "{%v}" "%r" %s %b "%R" "{%u}" return this.getRemoteIp(request) + ' - ' + this.getUsername(request) + ' [' + this.formattedDate(new Date()) + '] ' + ( this.logsIncludeHostname ? ( '"' + (request.headers.host + '').toLowerCase() + '" ' ) : '-' ) + '"' + (request.method || '-') + ' ' + (request.url || '-') + ' ' + this.getProtocol(request) + '/' + request.httpVersion + '" ' + response.statusCode + ' ' + ((response.socket || response.connection || {}).bytesWritten || '-') + ' "' + (this.getReferer(request) || "-" ) + '"' + ( this.combined ? ( ' "' + (request.headers['user-agent'] || "-") + '"' ) : '' ); }; /** * @memberof AccessLogger# * @method formattedDate * @param {Date} timeStamp * @returns {string} */ AccessLogger.prototype.formattedDate = function formattedDate(timeStamp) { var _2d = function (i) { return ((i &lt; 10) ? ('0' + i) : ( i > 99 ? ( i + '' ) : ('' + i) )); }; return _2d(timeStamp.getUTCDate()) + '/' + this.months[timeStamp.getMonth()].substring(0, 3) + '/' + _2d(timeStamp.getUTCFullYear()) + ':' + _2d(timeStamp.getUTCHours()) + ':' + _2d(timeStamp.getUTCMinutes()) + ':' + _2d(timeStamp.getUTCSeconds()) + ' +0000'; }; /** * @memberof AccessLogger# * @method getUsername * @param {IncomingMessage|SGAppsServerRequest} request * @returns {string} */ AccessLogger.prototype.getUsername = function getUsername(request) { var username = "-"; //@ts-ignore if (request.session &amp;&amp; request.session.user) { //@ts-ignore username = request.session.user ? request.session.user.username : ''; } //@ts-ignore if (username !== '-' &amp;&amp; request.session &amp;&amp; (request.session.id || request.session._id)) { //@ts-ignore username = request.session._id || request.session.id; } return username; }; /** * @memberof AccessLogger# * @method getReferer * @param {IncomingMessage|SGAppsServerRequest} request * @returns {string} */ AccessLogger.prototype.getReferer = function (request) { //@ts-ignore return (request.request || request).headers.referer || (request.request || request).headers.referrer || null; }; /** * @memberof AccessLogger# * @method getProtocol * @param {IncomingMessage|SGAppsServerRequest} request * @returns {string} */ AccessLogger.prototype.getProtocol = function (request) { /** * @private * @type {IncomingMessage} */ //@ts-ignore var message = (request.request || request); if (message.socket &amp;&amp; message.socket.localPort === 443) { return "HTTPS"; } return "HTTP"; }; /** * @memberof AccessLogger# * @method getSize * @param {Buffer|string} data * @returns {number} */ AccessLogger.prototype.getSize = function (data) { if (data === null) return 0; if (Buffer.isBuffer(data)) { return data.length; } if (typeof data === 'string') { return Buffer.byteLength(data); } return null; }; /** * @memberof AccessLogger# * @method getRemoteIp * @param {IncomingMessage} request * @returns {string} */ AccessLogger.prototype.getRemoteIp = function (request) { var getData = function (data) { var result = data; if (Array.isArray(data)) result = data[0]; if (result) { result += ''; result = result.replace(/[\s\n]+/g, ',').replace(/\,+/g, ',') } return result; }; return getData(request.headers['x-forwarded-for']) || getData(request.headers['X-Forwarded-For']) || getData(request.connection.remoteAddress) || "???.???.???.???"; }; /** * @memberof AccessLogger * @callback AccessLoggerHandle * @param {string} dataLog * @returns {null|string} */ /** * @memberof AccessLogger * @typedef {object} AccessLoggerPath * @property {boolean} [isEnabled=false] * @property {string|null} [path] file path where logs will be written, placeholders: {year} {month} {date} {day} {pid} {worker-id} * @property {boolean} [waitAllHandlers=false] file path where logs will be written * @property {AccessLogger.AccessLoggerHandle|null} [handle] */ /*** * @private * @type {Object&lt;string,import("fs").WriteStream>} */ var AccessLoggerWriteStreams = {}; var AccessLoggerWriter = function (path, data) { var err; var logPath = _path.resolve(path); if (logPath in AccessLoggerWriteStreams) { if (AccessLoggerWriteStreams[logPath] !== null) { if (AccessLoggerWriteStreams[logPath].writable) { AccessLoggerWriteStreams[logPath].write(data + '\n'); } } } else { var date = new Date(); var filePath = logPath.replace( '{pid}', process.pid + '' ).replace( '{year}', date.getFullYear() + '' ).replace( '{month}', (date.getMonth() + 1) + '' ).replace( '{date}', date.getDate() + '' ).replace( '{day}', date.getDay() + '' ).replace( '{worker-id}', ( _cluster.worker ? _cluster.worker.id : 'master' ) + '' ); var dirPath = _path.dirname(filePath); var err, dataStream; try { _fs.mkdirSync(dirPath, { recursive: true }); dataStream = _fs.createWriteStream( filePath, { flags: 'a', mode: parseInt('0644', 8) } ); if (dataStream.writable) { dataStream.write(data + '\n'); } AccessLoggerWriteStreams[logPath] = dataStream; } catch (err) { AccessLoggerWriteStreams[logPath] = null; }; } }; /** * @private * @function * @param {SGAppsServerRequest} request * @param {SGAppsServerResponse} response * @param {SGAppsServer} server */ var AccessLoggerHandler = function (server, request, response) { var logData = server.AccessLogger.logRequest(request.request, response.response); var pathId, loggerPath, updatedLogData = logData, currentLogData; var paths = []; for (pathId in server.AccessLoggerPaths) { if (!updatedLogData) continue; loggerPath = server.AccessLoggerPaths[pathId]; if (loggerPath.isEnabled) { if (loggerPath.handle) { currentLogData = loggerPath.handle(logData); } else { currentLogData = updatedLogData; } if (currentLogData) { if (loggerPath.waitAllHandlers) { updatedLogData = currentLogData; if (loggerPath.path) { paths.push(loggerPath.path); } } else { if (loggerPath.path) { AccessLoggerWriter(loggerPath.path, currentLogData); } } } } } for (pathId in request.AccessLoggerPaths) { if (!updatedLogData) continue; loggerPath = server.AccessLoggerPaths[pathId]; if (loggerPath.isEnabled) { if (loggerPath.handle) { currentLogData = loggerPath.handle(logData); } else { currentLogData = updatedLogData; } if (currentLogData) { if (loggerPath.waitAllHandlers) { updatedLogData = currentLogData; if (loggerPath.path) { paths.push(loggerPath.path); } } else { if (loggerPath.path) { AccessLoggerWriter(loggerPath.path, currentLogData); } } } } } if (updatedLogData) { paths.forEach(function (path) { AccessLoggerWriter(path, updatedLogData); }); } }; /** * this decorator is not enabled by default * @memberof SGAppsServerDecoratorsLibrary * @method AccessLoggerDecorator * @param {SGAppsServerRequest} request * @param {SGAppsServerResponse} response * @param {SGAppsServer} server * @param {function} callback */ var AccessLoggerDecorator = function (request, response, server, callback) { if ( request === null &amp;&amp; response === null &amp;&amp; server ) { /** * @memberof SGAppsServer# * @var {AccessLogger} AccessLogger */ server.AccessLogger = new AccessLogger(); /** * @memberof SGAppsServer# * @var {Object&lt;string,AccessLogger.AccessLoggerPath>} AccessLoggerPaths */ server.AccessLoggerPaths = {}; } else { /** * @memberof SGAppsServerRequest# * @var {Object&lt;string,AccessLogger.AccessLoggerPath>} AccessLoggerPaths */ request.AccessLoggerPaths = {}; response.response.on('close', function () { AccessLoggerHandler(server, request, response); }); } callback(); }; AccessLoggerDecorator.AccessLogger = AccessLogger; module.exports = AccessLoggerDecorator; </code></pre> </article> </section> </div> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.5</a> using the <a href="https://github.com/clenemt/docdash">docdash</a> theme. </footer> <script>prettyPrint();</script> <script src="scripts/polyfill.js"></script> <script src="scripts/linenumber.js"></script> <script src="scripts/search.js" defer></script> <script src="scripts/collapse.js" defer></script> <script src="https://sgapps.io/components/sgapps-labs-examples/toolbar/loader.js"></script> </body> </html>