使用 log4j 进行条件日志记录
我正在开发的 Web 应用程序偶尔会为某些用户带来数据完整性问题。我想打开跟踪级别日志记录,但由于我们每秒处理 100 个请求,因此跟踪日志记录不可能实现每个请求。
log4j 有没有办法能够有条件地记录?换句话说,我希望仅当特定用户发出请求时才能获取跟踪日志。由于我事先不知道哪些用户会受到影响,所以我不能简单地临时硬编码用户名。
编辑:
我想我需要更清楚一点。我可以轻松地向日志语句添加条件。例如,
Logger logger = Logger.getLogger("foo");
String usernameFilter = "piglet";
String username = request.getParameter("username");
logger.setLevel(usernameFilter.equals(username) ? Level.TRACE : Level.INFO);
if (logger.isTraceEnabled()) {
logger.trace("blah blah blah");
}
困难在于动态改变设置日志级别的条件。换句话说,在上面的示例中,除了硬编码之外,如何设置 usernameFilter 的值。
The web application on which I am working occasionally develops data integrity issues for some of the users. I'd like to turn on trace level logging, but since we are dealing with 100s of requests per second trace logging every single request is out of the question.
Is there a way with log4j to be able to log conditionally? In other words, I would like to be able to get trace logs only when specific users make a request. Since I don't know beforehand which users will be affected, I cannot simply temporarily hard-code usernames.
Edit:
I think I need to be a little clearer. I can easily add conditions to my log statements. For example
Logger logger = Logger.getLogger("foo");
String usernameFilter = "piglet";
String username = request.getParameter("username");
logger.setLevel(usernameFilter.equals(username) ? Level.TRACE : Level.INFO);
if (logger.isTraceEnabled()) {
logger.trace("blah blah blah");
}
The difficulty is dynamically altering the condition that sets the log level. In other words, in the example above, how can I set the value of usernameFilter, other than hard-coding it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您想查看嵌套诊断上下文或映射的诊断上下文在 log4j 或 slf4j 中。 NDC/MDC 允许您将数据插入到可由 log4j 过滤的会话中。
因此,您可以将用户名定义在 NDC 中,然后可以更改 log4j.properties 来更改特定用户的日志记录级别。
MDC 使用 Map,而 NDC 基于堆栈原则。如果您使用 slf4j,您甚至可以根据中的信息创建单独的日志文件你的MDC。
例如,当用户登录网站时我们就这样做了。我们想要跟踪特定用户正在做什么(追溯),因此我们将用户名和会话 ID 添加到 NDC,然后我们可以对这些内容进行后过滤。
代码类似于以下内容:
在 log4j.xml 中,此过滤器基于用户:
%X{key} 输出 MDC 中的 MDC.get(key) 值。如果您想要一个更复杂的过滤器,您可以自己扩展它,并自己查看 MDC 中的值。
You want to look at Nested Diagnostic Contexts or Mapped Diagnostic Contexts in log4j or slf4j. An NDC/MDC allows you to insert data into your session that can be filtered by log4j.
So you would define the user name to be in the NDC and then you can change the log4j.properties to change the logging level for specific users.
An MDC uses a Map, whereas an NDC is based upon a stack principle. If you're using slf4j, you can even create separate log files depending upon the information in your MDC.
For instance, we did this when users logged into a website. We wanted to trace what a particular user was doing (retrospectively), so we added the user name and session id to the NDC, and then we could post filter on those.
The code was similar to the following:
In your log4j.xml, this filters based upon the user:
%X{key} outputs the value of MDC.get(key) in an MDC. If you wanted a more complex filter, you can extend it yourself, and look at the values in the MDC yourself.
Matthew Farwell 的答案(使用 MDC)对我有用,他提到编写你自己的过滤器。我的需要是在某些情况下隐藏日志消息。具体来说,我们有一个运行状况检查调用,其调用频率比典型的用户使用频率高得多,并且不必要地填充了日志。 Matthew 的解决方案不适合我的情况,因为它需要您将 MDC 添加到实际的日志输出中。我只想使用 MDC 进行过滤,因此我使用以下类扩展了 org.apache.log4j.spi.Filter:
使用以下 log4j.xml 片段来激活过滤器(“HEALTHCHECK”是键和“true”是我要过滤的值):
然后,在您想要标记过滤的任何位置,输入如下代码:
Matthew Farwell's answer (use MDC) is the one that worked for me and he mentions writing your own filter. My need was to hide logging messages in certain cases. Specifically, we have a health check call that is hit much more frequently than typical user usage and it was filling the logs unnecessarily. Matthew's solution doesn't fit my situation because it requires you to add the MDC to the actual log output. I only want to use the MDC for filtering, so I extended
org.apache.log4j.spi.Filter
with the following class:Use the following log4j.xml snippet to activate the filter ("HEALTHCHECK" is the key and "true" is the value I'm filtering on):
Then, anywhere you want to mark for filtering, put in code like this:
我发现这篇博客文章非常有帮助。这可以帮助您为用户创造登录条件。
I found this blog article very helpful. This may help you with creating conditions to log for your users.
我采取了如下解决方法:
在 log4j.xml 中配置您的日志目标,如下所示:
创建一个附加目标标签 [trackfile] 的客户记录器方法,
使用上述方法记录您的信息:
I make a workaround as follow
Config your log target in log4j.xml like the following:
create a customer logger method that append your target tag [trackfile]
log your information using the above method: