5

I want to log objects using log4javascript. For example consider the following code:

function LogObject() {
var blah = {
    one: 42,
    two: "486"
};
logger.Info(blah);

Assuming that logger is instance of log4javascript logger that is properly set up:

var logger = log4javascript.getLogger("InternalLogger");
var ajaxAppender = new log4javascript.AjaxAppender(url),
jsonLayout = new log4javascript.JsonLayout(false, false);
ajaxAppender.setLayout(jsonLayout);
ajaxAppender.addHeader("Content-Type", "application/json");
logger.addAppender(ajaxAppender);

I am expecting the result to the following: request payload contains array of messages first of which is my object serialized into JSON. What I see is array of messages first of which has string "Object object" (like toString() method was invoked). How can I achieve that?

4

3 回答 3

4

JsonLayout将日志记录事件(除了日志消息之外还包括日志级别、时间戳和记录器名称)格式化为 JSON 而不是日志消息,它几乎被假定为一个字符串。这样做的原因是为了避免旧浏览器对 JSON 库的依赖;如果没有 JSON 库,为处理的简单、已知数据生成 JSONJsonLayout是没有问题的,但处理任意对象肯定需要一个。

我建议的解决方法只是在将消息传递给日志记录调用之前对其进行格式化:

logger.info( JSON.stringify(blah) );
于 2013-08-13T21:31:42.930 回答
4

We were following @Tim Down's suggestion

logger.info( JSON.stringify(blah) );

But we had performance issues since the JSON.stringify happens before logger.info is called, therefore it will always happen even if the logging level is set to ignore this log.

In order to work around this I wrote a new lazy layout so that the stringification only happens if the log is actually output. In order to be more flexible it also alows passing a function, in which case it outputs the result of running said function.

Usage:

logger.trace("Received ", widget, " which has ", ()  => countFrimbles(widget), ' frimbles');

Implementation:

function LazyFormatLayout() { }
LazyFormatLayout.prototype = new log4javascript.Layout();
LazyFormatLayout.prototype.format = function (loggingEvent) {
    var time = loggingEvent.timeStamp.toTimeString().split(/\s/)[0];

    var head = time + ' ' + loggingEvent.logger.name + ' [' + loggingEvent.level.name + '] - ';
    var body = loggingEvent.messages.map(function (arg) {
        try {
            switch (typeof (arg)) {
                case 'function':
                    return arg();
                case 'object':
                    return JSON.stringify(arg);
            }
        }
        catch (e) {
            return '<<error while logging: ' + e.stack + '>>';
        }
        return arg;

    }).join('');
    if (!loggingEvent.exception)
        return head + body;

    return head + body + ' ==> Exception: ' + loggingEvent.exception.stack;
}

LazyFormatLayout.prototype.ignoresThrowable = function () { return false; };
LazyFormatLayout.prototype.toString = function () { return "LazyFormatLayout"; };
于 2016-02-10T15:38:47.793 回答
-1

问题有点过时了,但是一个简单的谷歌搜索出现了这个问题,似乎有一种内置的方式来记录对象:

var log = log4javascript.getDefaultLogger(); log.info("log following object",{ data:5, text:"bla" });

输出

12:49:43 信息 - 记录以下对象 { 数据:5,文本:bla }

于 2015-06-26T10:54:22.647 回答