When logging an `Error` object using the clustered appender, the logged event is a JSON representation of the error, ex:
[2015-06-09 11:13:48.257] [ERROR] middleware.Security - { stack: 'Error: User is not authorized\n at Object.exec (D:\\Borealis\\demoux\\IMS\\server\\IMS\\middleware\\SecurityCheck\\Instance.js:41:14)\n [...] at applyArgs (D:\\Borealis\\demoux\\IMS\\server\\node_modules\\flow\\flow.js:9:15)\n at Function.flowState (D:\\Borealis\\demoux\\IMS\\server\\node_modules\\flow\\flow.js:39:6)\n at applyArgs (D:\\Borealis\\demoux\\IMS\\server\\node_modules\\flow\\flow.js:9:15)\n at Function.thisFlow.exec (D:\\Borealis\\demoux\\IMS\\server\\node_modules\\flow\\flow.js:94:4)\n at applyArgs (D:\\Borealis\\demoux\\IMS\\server\\node_modules\\flow\\flow.js:9:15)\n at thisFlow (D:\\Borealis\\demoux\\IMS\\server\\node_modules\\flow\\flow.js:15:4)\n at Object.exec (D:\\Borealis\\demoux\\IMS\\server\\node_modules\\flow\\flow.js:103:42)' }
The error should be formatted identically as with other appenders (e.g. only printing the stack).
This changes adds a check for a `stack` attribute on the serialized loggingEvent and unwraps the errors while deserializing it. Result is:
[2015-06-09 11:13:48.257] [ERROR] middleware.Security - Error: User is not authorized
at Object.exec (D:\Borealis\demoux\IMS\server\IMS\middleware\SecurityCheck\Instance.js:41:14)
at applyArgs (D:\Borealis\demoux\IMS\server\node_modules\flow\flow.js:9:15)
at Function.flowState (D:\Borealis\demoux\IMS\server\node_modules\flow\flow.js:39:6)
at applyArgs (D:\Borealis\demoux\IMS\server\node_modules\flow\flow.js:9:15)
at Function.thisFlow.exec (D:\Borealis\demoux\IMS\server\node_modules\flow\flow.js:94:4)
at applyArgs (D:\Borealis\demoux\IMS\server\node_modules\flow\flow.js:9:15)
at thisFlow (D:\Borealis\demoux\IMS\server\node_modules\flow\flow.js:15:4)
at Object.exec (D:\Borealis\demoux\IMS\server\node_modules\flow\flow.js:103:42)
Example:
log4js.configure({
appenders: [{type: 'console', timezoneOffset: -540}],
replaceConsole: true
});
The expected value is the equivalent of (new Date).getTimezoneOffset()
In this example, -540 is the value for JST.
This allows machines members of world-wide-spread cluster to all report
log time-stamps using the same timezone (or adapt the timezone to a
local different from the system)
Metadata for users such as name, email, etc are not always present for users. For example, I am running express and I want to log the %x{company}%x{username} so that when I look at my logs I can immediately understand which user this affects. Or for example, I could log %x{payingOrTial} the type of user.
This works well when the user is logged in. However, my logger encompasses everything. I log when the server boots up. I log during the login screen where a user is not yet logged in. In these circumstances there is no way to retrieve this metadata.
So for example
```
"username": function () {
var session = require('continuation-local-storage').getNamespace('api.callinize');
if(!session) session = require('continuation-local-storage').getNamespace('dashboard.callinize');
var username = session && session.get('user') && session.get('user').username;
if(!username) return "";
return " " + username + " ";
}
```
I try to get the metadata. If I get no metdata I return a blank string. Unfortunately, in the current implementation, due to the OR operator, even if I have a replacement of "" || matchedString,
```
replaceToken(conversionCharacter, loggingEvent, specifier) ||
matchedString;
```
the blank string equals false and puts the token in the log instead of the blank string. This makes the log lines get long with information that is not relevant. The better thing to do is simply allow for blank strings. This lets the user have control over their logs and also allows for more metadata to go in the logs, without having to pick only metadata that is always present.