expresser
Version:
A ready-to-use platform for Node.js web apps, built on top of Express.
757 lines (411 loc) • 37.4 kB
HTML
<html>
<head>
<title>logger.coffee</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" media="all" href="public/stylesheets/normalize.css" />
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div class="container">
<div class="page">
<div class="header">
<h1>logger.coffee</h1>
<div class="toc">
<h3>Table of Contents</h3>
<ol>
<li>
<a class="source" href="index.html">
index.coffee
</a>
</li>
<li>
<a class="source" href="app.html">
app.coffee
</a>
</li>
<li>
<a class="source" href="cron.html">
cron.coffee
</a>
</li>
<li>
<a class="source" href="database.html">
database.coffee
</a>
</li>
<li>
<a class="source" href="downloader.html">
downloader.coffee
</a>
</li>
<li>
<a class="source" href="events.html">
events.coffee
</a>
</li>
<li>
<a class="source" href="firewall.html">
firewall.coffee
</a>
</li>
<li>
<a class="source" href="imaging.html">
imaging.coffee
</a>
</li>
<li>
<a class="source" href="logger.html">
logger.coffee
</a>
</li>
<li>
<a class="source" href="mailer.html">
mailer.coffee
</a>
</li>
<li>
<a class="source" href="settings.html">
settings.coffee
</a>
</li>
<li>
<a class="source" href="sockets.html">
sockets.coffee
</a>
</li>
<li>
<a class="source" href="utils.html">
utils.coffee
</a>
</li>
</ol>
</div>
</div>
<h2 id="expresser-logger">EXPRESSER LOGGER</h2>
<p>Handles server logging using local files, Logentries or Loggly.
Multiple services can be enabled at the same time.
<!--
@see Settings.logger
--></p>
<div class='highlight'><pre><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Logger</span></span>
events = <span class="hljs-built_in">require</span> <span class="hljs-string">"./events.coffee"</span>
fs = <span class="hljs-built_in">require</span> <span class="hljs-string">"fs"</span>
lodash = <span class="hljs-built_in">require</span> <span class="hljs-string">"lodash"</span>
moment = <span class="hljs-built_in">require</span> <span class="hljs-string">"moment"</span>
path = <span class="hljs-built_in">require</span> <span class="hljs-string">"path"</span>
settings = <span class="hljs-built_in">require</span> <span class="hljs-string">"./settings.coffee"</span>
utils = <span class="hljs-built_in">require</span> <span class="hljs-string">"./utils.coffee"</span></pre></div>
<p>Local logging objects will be set on <code>init</code>.</p>
<div class='highlight'><pre> bufferDispatcher = <span class="hljs-literal">null</span>
localBuffer = <span class="hljs-literal">null</span>
flushing = <span class="hljs-literal">false</span></pre></div>
<p>Remote logging providers will be set on <code>init</code>.</p>
<div class='highlight'><pre> logentries = <span class="hljs-literal">null</span>
loggly = <span class="hljs-literal">null</span>
loggerLogentries = <span class="hljs-literal">null</span>
loggerLoggly = <span class="hljs-literal">null</span></pre></div>
<p>The <code>serverIP</code> will be set on init, but only if <code>settings.logger.sendIP</code> is true.</p>
<div class='highlight'><pre> serverIP = <span class="hljs-literal">null</span></pre></div>
<p>Timer used for automatic logs cleaning.</p>
<div class='highlight'><pre> timerCleanLocal = <span class="hljs-literal">null</span></pre></div>
<p>@property [Method] Custom method to call when logs are sent to logging server or flushed to disk.</p>
<div class='highlight'><pre> <span class="hljs-attribute">onLogSuccess</span>: <span class="hljs-literal">null</span></pre></div>
<p>@property [Method] Custom method to call when errors are triggered by the logging transport.</p>
<div class='highlight'><pre> <span class="hljs-attribute">onLogError</span>: <span class="hljs-literal">null</span></pre></div>
<p>@property [Array] Holds a list of current active logging services.
@private</p>
<div class='highlight'><pre> activeServices = []</pre></div>
<p>Holds a copy of emails sent for critical logs.</p>
<div class='highlight'><pre> <span class="hljs-attribute">criticalEmailCache</span>: {}</pre></div>
<h1 id="constructor-init-and-stop">CONSTRUCTOR, INIT AND STOP</h1>
<hr>
<p>Logger constructor.</p>
<div class='highlight'><pre> <span class="hljs-attribute">constructor</span>:<span class="hljs-function"> -></span>
<span class="hljs-property">@setEvents</span>() <span class="hljs-keyword">if</span> settings.events.enabled</pre></div>
<p>Bind event listeners.</p>
<div class='highlight'><pre> <span class="hljs-attribute">setEvents</span>:<span class="hljs-function"> =></span>
events.<span class="hljs-literal">on</span> <span class="hljs-string">"logger.debug"</span>, <span class="hljs-property">@debug</span>
events.<span class="hljs-literal">on</span> <span class="hljs-string">"logger.info"</span>, <span class="hljs-property">@info</span>
events.<span class="hljs-literal">on</span> <span class="hljs-string">"logger.warn"</span>, <span class="hljs-property">@warn</span>
events.<span class="hljs-literal">on</span> <span class="hljs-string">"logger.error"</span>, <span class="hljs-property">@error</span>
events.<span class="hljs-literal">on</span> <span class="hljs-string">"logger.critical"</span>, <span class="hljs-property">@critical</span></pre></div>
<p>Init the Logger module. Verify which services are set, and add the necessary transports.
IP address and timestamp will be appended to logs depending on the settings.
@param [Object] options Logger init options.</p>
<div class='highlight'><pre> <span class="hljs-attribute">init</span>: <span class="hljs-function"><span class="hljs-params">(options)</span> =></span>
bufferDispatcher = <span class="hljs-literal">null</span>
localBuffer = <span class="hljs-literal">null</span>
logentries = <span class="hljs-literal">null</span>
loggly = <span class="hljs-literal">null</span>
serverIP = <span class="hljs-literal">null</span>
activeServices = []</pre></div>
<p>Get a valid server IP to be appended to logs.</p>
<div class='highlight'><pre> <span class="hljs-keyword">if</span> settings.logger.sendIP
serverIP = utils.getServerIP <span class="hljs-literal">true</span></pre></div>
<p>Define server IP.</p>
<div class='highlight'><pre> <span class="hljs-keyword">if</span> serverIP?
ipInfo = <span class="hljs-string">"IP <span class="hljs-subst">#{serverIP}</span>"</span>
<span class="hljs-keyword">else</span>
ipInfo = <span class="hljs-string">"No server IP set."</span></pre></div>
<p>Init transports.</p>
<div class='highlight'><pre> <span class="hljs-property">@initLocal</span>()
<span class="hljs-property">@initLogentries</span>()
<span class="hljs-property">@initLoggly</span>()</pre></div>
<p>Check if uncaught exceptions should be logged. If so, try logging unhandled
exceptions using the logger, otherwise log to the console.</p>
<div class='highlight'><pre> <span class="hljs-keyword">if</span> settings.logger.uncaughtException
<span class="hljs-property">@debug</span> <span class="hljs-string">"Logger.init"</span>, <span class="hljs-string">"Catching unhandled exceptions."</span>
process.<span class="hljs-literal">on</span> <span class="hljs-string">"uncaughtException"</span>, <span class="hljs-function"><span class="hljs-params">(err)</span> =></span>
<span class="hljs-keyword">try</span>
<span class="hljs-property">@error</span> <span class="hljs-string">"Unhandled exception!"</span>, err
<span class="hljs-keyword">catch</span> ex
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"Unhandled exception!"</span>, err</pre></div>
<p>Start logging!</p>
<div class='highlight'><pre> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> localBuffer? <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> logentries? <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> loggly?
<span class="hljs-property">@warn</span> <span class="hljs-string">"Logger.init"</span>, <span class="hljs-string">"No transports enabled."</span>, <span class="hljs-string">"Logger module will only log to the console!"</span>
<span class="hljs-keyword">else</span>
<span class="hljs-property">@info</span> <span class="hljs-string">"Logger.init"</span>, activeServices.join(), ipInfo</pre></div>
<p>Init the Local transport. Check if logs should be saved locally. If so, create the logs buffer
and a timer to flush logs to disk every X milliseconds.</p>
<div class='highlight'><pre> <span class="hljs-attribute">initLocal</span>:<span class="hljs-function"> =></span>
<span class="hljs-keyword">if</span> settings.logger.local.enabled
<span class="hljs-keyword">if</span> fs.existsSync?
folderExists = fs.existsSync settings.path.logsDir
<span class="hljs-keyword">else</span>
folderExists = path.existsSync settings.path.logsDir</pre></div>
<p>Create logs folder, if it doesn’t exist.</p>
<div class='highlight'><pre> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> folderExists
fs.mkdirSync settings.path.logsDir
<span class="hljs-keyword">if</span> settings.general.debug
<span class="hljs-built_in">console</span>.log <span class="hljs-string">"Logger.initLocal"</span>, <span class="hljs-string">"Created <span class="hljs-subst">#{settings.path.logsDir}</span> folder."</span></pre></div>
<p>Set local buffer.</p>
<div class='highlight'><pre> localBuffer = {<span class="hljs-attribute">info</span>: [], <span class="hljs-attribute">warn</span>: [], <span class="hljs-attribute">error</span>: []}
bufferDispatcher = setInterval <span class="hljs-property">@flushLocal</span>, settings.logger.local.bufferInterval
activeServices.push <span class="hljs-string">"Local"</span></pre></div>
<p>Check the maxAge of local logs.</p>
<div class='highlight'><pre> <span class="hljs-keyword">if</span> settings.logger.local.maxAge? <span class="hljs-keyword">and</span> settings.logger.local.maxAge > <span class="hljs-number">0</span>
<span class="hljs-keyword">if</span> timerCleanLocal?
clearInterval timerCleanLocal
timerCleanLocal = setInterval <span class="hljs-property">@cleanLocal</span>, <span class="hljs-number">86400</span>
<span class="hljs-keyword">else</span>
<span class="hljs-property">@stopLocal</span>()</pre></div>
<p>Init the Logentries transport. Check if Logentries should be used, and create the Logentries objects.</p>
<div class='highlight'><pre> <span class="hljs-attribute">initLogentries</span>:<span class="hljs-function"> =></span>
<span class="hljs-keyword">if</span> settings.logger.logentries.enabled <span class="hljs-keyword">and</span> settings.logger.logentries.token? <span class="hljs-keyword">and</span> settings.logger.logentries.token <span class="hljs-keyword">isnt</span> <span class="hljs-string">""</span>
logentries = <span class="hljs-built_in">require</span> <span class="hljs-string">"node-logentries"</span>
loggerLogentries = logentries.logger {<span class="hljs-attribute">token</span>: settings.logger.logentries.token, <span class="hljs-attribute">timestamp</span>: settings.logger.sendTimestamp}
loggerLogentries.<span class="hljs-literal">on</span>(<span class="hljs-string">"log"</span>, <span class="hljs-property">@onLogSuccess</span>) <span class="hljs-keyword">if</span> lodash.isFunction <span class="hljs-property">@onLogSuccess</span>
loggerLogentries.<span class="hljs-literal">on</span>(<span class="hljs-string">"error"</span>, <span class="hljs-property">@onLogError</span>) <span class="hljs-keyword">if</span> lodash.isFunction <span class="hljs-property">@onLogError</span>
activeServices.push <span class="hljs-string">"Logentries"</span>
<span class="hljs-keyword">else</span>
<span class="hljs-property">@stopLogentries</span>()</pre></div>
<p>Init the Loggly transport. Check if Loggly should be used, and create the Loggly objects.</p>
<div class='highlight'><pre> <span class="hljs-attribute">initLoggly</span>:<span class="hljs-function"> =></span>
<span class="hljs-keyword">if</span> settings.logger.loggly.enabled <span class="hljs-keyword">and</span> settings.logger.loggly.subdomain? <span class="hljs-keyword">and</span> settings.logger.loggly.token? <span class="hljs-keyword">and</span> settings.logger.loggly.token <span class="hljs-keyword">isnt</span> <span class="hljs-string">""</span>
loggly = <span class="hljs-built_in">require</span> <span class="hljs-string">"loggly"</span>
loggerLoggly = loggly.createClient {<span class="hljs-attribute">token</span>: settings.logger.loggly.token, <span class="hljs-attribute">subdomain</span>: settings.logger.loggly.subdomain, <span class="hljs-attribute">json</span>: <span class="hljs-literal">false</span>}
activeServices.push <span class="hljs-string">"Loggly"</span>
<span class="hljs-keyword">else</span>
<span class="hljs-property">@stopLoggly</span>()</pre></div>
<p>Disable and remove Local transport from the list of active services.</p>
<div class='highlight'><pre> <span class="hljs-attribute">stopLocal</span>:<span class="hljs-function"> =></span>
<span class="hljs-property">@flushLocal</span>()
clearInterval bufferDispatcher <span class="hljs-keyword">if</span> bufferDispatcher?
bufferDispatcher = <span class="hljs-literal">null</span>
localBuffer = <span class="hljs-literal">null</span>
i = activeServices.indexOf <span class="hljs-string">"Local"</span>
activeServices.splice(i, <span class="hljs-number">1</span>) <span class="hljs-keyword">if</span> i >= <span class="hljs-number">0</span></pre></div>
<p>Disable and remove Logentries transport from the list of active services.</p>
<div class='highlight'><pre> <span class="hljs-attribute">stopLogentries</span>:<span class="hljs-function"> =></span>
logentries = <span class="hljs-literal">null</span>
loggerLogentries = <span class="hljs-literal">null</span>
i = activeServices.indexOf <span class="hljs-string">"Logentries"</span>
activeServices.splice(i, <span class="hljs-number">1</span>) <span class="hljs-keyword">if</span> i >= <span class="hljs-number">0</span></pre></div>
<p>Disable and remove Loggly transport from the list of active services.</p>
<div class='highlight'><pre> <span class="hljs-attribute">stopLoggly</span>:<span class="hljs-function"> =></span>
loggly = <span class="hljs-literal">null</span>
loggerLoggly = <span class="hljs-literal">null</span>
i = activeServices.indexOf <span class="hljs-string">"Loggly"</span>
activeServices.splice(i, <span class="hljs-number">1</span>) <span class="hljs-keyword">if</span> i >= <span class="hljs-number">0</span></pre></div>
<h2 id="log-methods">LOG METHODS</h2>
<p>Generic log method.
@param [String] logType The log type (for example: warning, error, info, security, etc).
@param [String] logFunc Optional, the logging function name to be passed to the console and Logentries.
@param [Array] args Array of arguments to be stringified and logged.</p>
<div class='highlight'><pre> <span class="hljs-attribute">log</span>: <span class="hljs-function"><span class="hljs-params">(logType, logFunc, args)</span> =></span>
<span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> args? <span class="hljs-keyword">and</span> logFunc?
args = logFunc
logFunc = <span class="hljs-string">"info"</span></pre></div>
<p>Get message out of the arguments.</p>
<div class='highlight'><pre> msg = <span class="hljs-property">@getMessage</span> args</pre></div>
<p>Log to different transports.</p>
<div class='highlight'><pre> <span class="hljs-keyword">if</span> settings.logger.local.enabled <span class="hljs-keyword">and</span> localBuffer?
<span class="hljs-property">@logLocal</span> logType, msg
<span class="hljs-keyword">if</span> settings.logger.logentries.enabled <span class="hljs-keyword">and</span> loggerLogentries?
loggerLogentries.log logFunc, msg
<span class="hljs-keyword">if</span> settings.logger.loggly.enabled <span class="hljs-keyword">and</span> loggerLoggly?
loggerLoggly.log msg, <span class="hljs-property">@logglyCallback</span></pre></div>
<p>Log to the console depending on <code>console</code> setting.</p>
<div class='highlight'><pre> <span class="hljs-keyword">if</span> settings.logger.<span class="hljs-built_in">console</span>
args.unshift moment().format <span class="hljs-string">"HH:mm:ss.SS"</span>
<span class="hljs-keyword">if</span> settings.logger.errorLogTypes.indexOf(logType) >= <span class="hljs-number">0</span>
<span class="hljs-built_in">console</span>.error.apply <span class="hljs-keyword">this</span>, args
<span class="hljs-keyword">else</span>
<span class="hljs-built_in">console</span>.log.apply <span class="hljs-keyword">this</span>, args</pre></div>
<p>Log to the active transports as <code>debug</code>, only if the debug flag is enabled.
All arguments are transformed to readable strings.</p>
<div class='highlight'><pre> <span class="hljs-attribute">debug</span>:<span class="hljs-function"> =></span>
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> settings.general.debug
args = Array.prototype.slice.call arguments
args.unshift <span class="hljs-string">"DEBUG"</span>
<span class="hljs-property">@log</span> <span class="hljs-string">"debug"</span>, <span class="hljs-string">"info"</span>, args</pre></div>
<p>Log to the active transports as <code>log</code>.
All arguments are transformed to readable strings.</p>
<div class='highlight'><pre> <span class="hljs-attribute">info</span>:<span class="hljs-function"> =></span>
args = Array.prototype.slice.call arguments
args.unshift <span class="hljs-string">"INFO"</span>
<span class="hljs-property">@log</span> <span class="hljs-string">"info"</span>, <span class="hljs-string">"info"</span>, args</pre></div>
<p>Log to the active transports as <code>warn</code>.
All arguments are transformed to readable strings.</p>
<div class='highlight'><pre> <span class="hljs-attribute">warn</span>:<span class="hljs-function"> =></span>
args = Array.prototype.slice.call arguments
args.unshift <span class="hljs-string">"WARN"</span>
<span class="hljs-property">@log</span> <span class="hljs-string">"warn"</span>, <span class="hljs-string">"warning"</span>, args</pre></div>
<p>Log to the active transports as <code>error</code>.
All arguments are transformed to readable strings.</p>
<div class='highlight'><pre> <span class="hljs-attribute">error</span>:<span class="hljs-function"> =></span>
args = Array.prototype.slice.call arguments
args.unshift <span class="hljs-string">"ERROR"</span>
<span class="hljs-property">@log</span> <span class="hljs-string">"error"</span>, <span class="hljs-string">"err"</span>, args</pre></div>
<p>Log to the active transports as <code>critical</code>.
All arguments are transformed to readable strings.</p>
<div class='highlight'><pre> <span class="hljs-attribute">critical</span>:<span class="hljs-function"> =></span>
args = Array.prototype.slice.call arguments
args.unshift <span class="hljs-string">"CRITICAL"</span>
<span class="hljs-property">@log</span> <span class="hljs-string">"critical"</span>, <span class="hljs-string">"err"</span>, args</pre></div>
<p>If the <code>criticalEmailTo</code> is set, dispatch a mail send event.</p>
<div class='highlight'><pre> <span class="hljs-keyword">if</span> settings.logger.criticalEmailTo? <span class="hljs-keyword">and</span> settings.logger.criticalEmailTo <span class="hljs-keyword">isnt</span> <span class="hljs-string">""</span>
body = args.join <span class="hljs-string">", "</span>
maxAge = moment().subtract(<span class="hljs-string">"m"</span>, settings.logger.criticalEmailExpireMinutes).unix()</pre></div>
<p>Do not proceed if this critical email was sent recently.</p>
<div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@criticalEmailCache</span>[body]? <span class="hljs-keyword">and</span> <span class="hljs-property">@criticalEmailCache</span>[body] > maxAge</pre></div>
<p>Set mail options.</p>
<div class='highlight'><pre> mailOptions =
<span class="hljs-attribute">subject</span>: <span class="hljs-string">"CRITICAL: <span class="hljs-subst">#{args[<span class="hljs-number">1</span>]}</span>"</span>
<span class="hljs-attribute">body</span>: body
<span class="hljs-attribute">to</span>: settings.logger.criticalEmailTo
<span class="hljs-attribute">logError</span>: <span class="hljs-literal">false</span></pre></div>
<p>Emit mail send message.</p>
<div class='highlight'><pre> events.emit <span class="hljs-string">"mailer.send"</span>, mailOptions, <span class="hljs-function"><span class="hljs-params">(err)</span> -></span>
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"Logger.critical"</span>, <span class="hljs-string">"Can't send email!"</span>, err <span class="hljs-keyword">if</span> err?</pre></div>
<p>Save to critical email cache.</p>
<div class='highlight'><pre> <span class="hljs-property">@criticalEmailCache</span>[body] = moment().unix()</pre></div>
<h2 id="local-logging">LOCAL LOGGING</h2>
<p>Log locally. The path is defined on <code>Settings.Path.logsDir</code>.
@param [String] logType The log type (info, warn, error, debug, etc).
@param [String] message Message to be logged.
@private</p>
<div class='highlight'><pre> <span class="hljs-attribute">logLocal</span>: <span class="hljs-function"><span class="hljs-params">(logType, message)</span> -></span>
now = moment()
message = now.format(<span class="hljs-string">"HH:mm:ss.SSS"</span>) + <span class="hljs-string">" - "</span> + message
localBuffer[logType] = [] <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> localBuffer[logType]?
localBuffer[logType].push message</pre></div>
<p>Flush all local buffered log messages to disk. This is usually called by the <code>bufferDispatcher</code> timer.</p>
<div class='highlight'><pre> <span class="hljs-attribute">flushLocal</span>:<span class="hljs-function"> -></span>
<span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> flushing</pre></div>
<p>Set flushing and current date.</p>
<div class='highlight'><pre> flushing = <span class="hljs-literal">true</span>
now = moment()
date = now.format <span class="hljs-string">"YYYYMMDD"</span></pre></div>
<p>Flush all buffered logs to disk. Please note that messages from the last seconds of the previous day
can be saved to the current day depending on how long it takes for the bufferDispatcher to run.
Default is every 10 seconds, so messages from 23:59:50 onwards could be saved on the next day.</p>
<div class='highlight'><pre> <span class="hljs-keyword">for</span> key, logs <span class="hljs-keyword">of</span> localBuffer
<span class="hljs-keyword">if</span> logs.length > <span class="hljs-number">0</span>
writeData = logs.join(<span class="hljs-string">"\n"</span>)
filePath = path.join settings.path.logsDir, <span class="hljs-string">"<span class="hljs-subst">#{date}</span>.<span class="hljs-subst">#{key}</span>.log"</span>
successMsg = <span class="hljs-string">"<span class="hljs-subst">#{logs.length}</span> records logged to disk."</span></pre></div>
<p>Reset this local buffer.</p>
<div class='highlight'><pre> localBuffer[key] = []</pre></div>
<p>Only use <code>appendFile</code> on new versions of Node.</p>
<div class='highlight'><pre> <span class="hljs-keyword">if</span> fs.appendFile?
fs.appendFile filePath, writeData, <span class="hljs-function"><span class="hljs-params">(err)</span> =></span>
flushing = <span class="hljs-literal">false</span>
<span class="hljs-keyword">if</span> err?
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"Logger.flushLocal"</span>, err
<span class="hljs-property">@onLogError</span> err <span class="hljs-keyword">if</span> <span class="hljs-property">@onLogError</span>?
<span class="hljs-keyword">else</span>
<span class="hljs-property">@onLogSuccess</span> successMsg <span class="hljs-keyword">if</span> <span class="hljs-property">@onLogSuccess</span>?
<span class="hljs-keyword">else</span>
fs.open filePath, <span class="hljs-string">"a"</span>, <span class="hljs-number">666</span>, <span class="hljs-function"><span class="hljs-params">(err1, fd)</span> =></span>
<span class="hljs-keyword">if</span> err1?
flushing = <span class="hljs-literal">false</span>
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"Logger.flushLocal.open"</span>, err1
<span class="hljs-property">@onLogError</span> err1 <span class="hljs-keyword">if</span> <span class="hljs-property">@onLogError</span>?
<span class="hljs-keyword">else</span>
fs.write fd, writeData, <span class="hljs-literal">null</span>, settings.general.encoding, <span class="hljs-function"><span class="hljs-params">(err2)</span> =></span>
flushing = <span class="hljs-literal">false</span>
<span class="hljs-keyword">if</span> err2?
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"Logger.flushLocal.write"</span>, err2
<span class="hljs-property">@onLogError</span> err2 <span class="hljs-keyword">if</span> <span class="hljs-property">@onLogError</span>?
<span class="hljs-keyword">else</span>
<span class="hljs-property">@onLogSuccess</span> successMsg <span class="hljs-keyword">if</span> <span class="hljs-property">@onLogSuccess</span>?
fs.closeSync fd</pre></div>
<p>Delete old log files from disk. The maximum date is defined on the settings.</p>
<div class='highlight'><pre> <span class="hljs-attribute">cleanLocal</span>:<span class="hljs-function"> -></span>
maxDate = moment().subtract <span class="hljs-string">"d"</span>, settings.logger.local.maxAge
fs.readdir settings.path.logsDir, <span class="hljs-function"><span class="hljs-params">(err, files)</span> -></span>
<span class="hljs-keyword">if</span> err?
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"Logger.cleanLocal"</span>, err
<span class="hljs-keyword">else</span>
<span class="hljs-keyword">for</span> f <span class="hljs-keyword">in</span> files
date = moment f.split(<span class="hljs-string">"."</span>)[<span class="hljs-number">1</span>], <span class="hljs-string">"yyyyMMdd"</span>
<span class="hljs-keyword">if</span> date.isBefore maxDate
fs.unlink path.join<span class="hljs-function"><span class="hljs-params">(settings.path.logsDir, f)</span>, <span class="hljs-params">(err)</span> -></span>
<span class="hljs-built_in">console</span>.error <span class="hljs-string">"Logger.cleanLocal"</span>, err <span class="hljs-keyword">if</span> err?</pre></div>
<h2 id="helper-methods">HELPER METHODS</h2>
<p>Returns a human readable message out of the arguments.
@return [String] The human readable, parsed JSON message.
@private</p>
<div class='highlight'><pre> <span class="hljs-attribute">getMessage</span>:<span class="hljs-function"> -></span>
separated = []
args = arguments
args = args[<span class="hljs-number">0</span>] <span class="hljs-keyword">if</span> args.length <span class="hljs-keyword">is</span> <span class="hljs-number">1</span></pre></div>
<p>Parse all arguments and stringify objects. Please note that fields defined
on the <code>Settings.logger.removeFields</code> won’t be added to the message.</p>
<div class='highlight'><pre> <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> args
<span class="hljs-keyword">if</span> settings.logger.removeFields.indexOf(a) < <span class="hljs-number">0</span>
<span class="hljs-keyword">if</span> lodash.isArray a
<span class="hljs-keyword">for</span> b <span class="hljs-keyword">in</span> a
separated.push b <span class="hljs-keyword">if</span> settings.logger.removeFields.indexOf(b) < <span class="hljs-number">0</span>
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> lodash.isObject a
<span class="hljs-keyword">try</span>
separated.push JSON.stringify a
<span class="hljs-keyword">catch</span> ex
separated.push a
<span class="hljs-keyword">else</span>
separated.push a</pre></div>
<p>Append IP address, if <code>serverIP</code> is set.</p>
<div class='highlight'><pre> separated.push <span class="hljs-string">"IP <span class="hljs-subst">#{serverIP}</span>"</span> <span class="hljs-keyword">if</span> serverIP?</pre></div>
<p>Return single string log message.</p>
<div class='highlight'><pre> <span class="hljs-keyword">return</span> separated.join <span class="hljs-string">" | "</span></pre></div>
<p>Wrapper callback for <code>onLogSuccess</code> and <code>onLogError</code> to be used by Loggly.
@param [String] err The Loggly error.
@param [String] result The Loggly logging result.
@private</p>
<div class='highlight'><pre> <span class="hljs-attribute">logglyCallback</span>: <span class="hljs-function"><span class="hljs-params">(err, result)</span> =></span>
<span class="hljs-keyword">if</span> err? <span class="hljs-keyword">and</span> <span class="hljs-property">@onLogError</span>?
<span class="hljs-property">@onLogError</span> err
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@onLogSuccess</span>?
<span class="hljs-property">@onLogSuccess</span> result</pre></div>
<h2 id="singleton-implementation">Singleton implementation</h2>
<div class='highlight'><pre>Logger.<span class="hljs-function"><span class="hljs-title">getInstance</span> = -></span>
<span class="hljs-property">@instance</span> = <span class="hljs-keyword">new</span> Logger() <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> <span class="hljs-property">@instance</span>?
<span class="hljs-keyword">return</span> <span class="hljs-property">@instance</span>
<span class="hljs-built_in">module</span>.<span class="hljs-built_in">exports</span> = <span class="hljs-built_in">exports</span> = Logger.getInstance()</pre></div>
<div class="fleur">h</div>
</div>
</div>
</body>
</html>