2011-05-25 132 views
3

我有一个在其线程中运行的MySession对象(一个通用会话,而不是web)。我想使用NDC类来包含从我的MySession的字段中获取的一些数据:创建它的用户,开始时间等等。我想将字段“渲染”为消息。它是可能的还是仅支持消息? 在此先感谢log4j,嵌套的诊断上下文

public class MySession { 
    String userName; 
    Date startTime; 

    public void doSomething() { 
     NDC.push(this);         //cannot do something like this? 
     NDC.push(this.userName 
        + " " + startTime.toString());   //or should I do this? 
    } 

} 

回答

3

NDC仅向所有日志消息(根据日志格式可能输出或不输出)添加“上下文”(自由格式字符串)。嵌套部分意味着NDC.pop()返回到前一个(下一层向上)上下文。

尽管如此,在任何给定的点上下文都是一个自由格式的字符串 - 所以你是对的,你必须像this.username + '.' + this.startTime.toString()那样推送类似于你的第二个例子。你可以从API看到push接受一个String参数;这个上下文只用于记录消息的一部分(隐式地是一个String),所以在接受不同类型的任意对象时没有任何好处。

2

你可以把几乎任何你想要的文字(或其他对象的文本表示)到NDC。不支持将对象渲染到NDC,因为toString()(或至少应该)几乎总是足够的。 NDC中太多和/或复杂的东西会使日志更难读取,因此建议将NDC内容限制在最低限度。

例如在你的情况下,将会话开始时间放在每条日志消息中会是过度的(也可能不明确)。最好只将某种唯一的会话ID推入NDC(如果您有这种情况,那就是),并在设置后立即在专用消息中记录任何其他会话详细信息,例如用户名,启动时间NDC。这仍允许您从日志中检索所有必需的会话数据,并为任何特定的日志消息标识相应的会话。

+0

好的,但如果是这样简单,是不是一个克隆,一个简单的“好名字”的线程标识符已经提供没有NDC? – AgostinoX 2011-05-25 12:24:26

+0

@AgostinoX,不,它更通用,可以以线程ID不能使用的方式使用。例如。在Web应用程序中,它可以包含会话ID,其中会话通常跨越多个请求(并且因此由多个不同的线程处理)。 – 2011-05-25 12:53:09