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.
In the original version, the following operation looks synchronic, however it is not:
```
res.end = end;
res.end(data,enc);
//emit the log entry
```
In fact, it starts a series of async operations, in which the request may yet be changed after the request log has already been emitted
(in our case - a change on request headers was observed, probably by some low level hook or hacky wrap of some http.ServerResponse method that's involved on the process - but called asynchronously)
what leads to situation that the request log does not capture valid data.
(observed by us:
- request headers
- calculated end time, when concerning big content
)
The fix just used `setTimeout(function() { /*emit the log entry*/ }, 1)`, but I'm afraid it may not hold true for big contents.
Well. maybe the headers part will, but the response time calculation will lie.
The fix relays on: http://nodejs.org/api/http.html#http_event_finish
This function should be useful when you need to log during async
parallel operations, without having a mess in logs.
For example when you walk asynchronously a directory and you want logs
to be grouped by file.
It returns the same getLogger() object but messages are stored
internally and sent to appenders only when you call the flush() method
on it.