我希望你能帮助我。
我有一个需要记录事务的网络服务。由于有很多命中,日志语句在日志文件中显得不相交/碎片化。
我已经考虑通过层传递一个 StringBuilder 实例并将语句附加到该实例,然后在向客户端返回响应之前在最后(主控制器中的 finally 子句)记录其内容一次。这似乎没有必要,我确信使用 Log4J 有一种更简洁的方法。
任何人都可以阐明这个问题吗?
谢谢
the good things is that you are using Log4j. The library itself implements the concept of nested diagnostic context (org.apache.log4j.NDC
) and mapped diagnostic context (org.apache.log4j.MDC
). I reckon you should definitely have a look at both, because those allows you to build some sort of the context that you can use in your log output layout.
您可能会考虑扭转问题:在运行时记录日志时不要合并条目的所有部分,而是稍后在数据分析期间合并它们。
例如,我们有一个记录大量数据的应用程序,其中快速响应很重要。我们最近实现了一个(定制的)系统,该系统记录到一个有效的关系数据库。但是,它的日志记录部分已针对日志记录进行了优化;我们只需按照应用程序生成它的顺序将元组数据附加到日志文件中。我们有可以针对这种格式进行查询的工具,并且当我们开始对针对日志格式的每个查询实际上都需要对数据库中的每个表进行表扫描感到恼火时,我们还计划生成以不同格式存储的新数据库版本。
即使您不能直接使用这种技术,只要考虑一下它就可以为您提供在 Log4J 中做得更好的想法。
Do you really need to have all the log statements in order I mean they are being logged as they occur. If you change the order you might miss the sequence of some events which you may need to track down tricky bugs.
Can you not add an identifier to your messages like start them with a thread id or user id from which the request is originating, this way you can then run queries on the logs using something like grep.
grep userId *.log
the statement will return all the log statements for that user in the correct order and its fast.
We use this technique on a high throughput trading platform and it is the easiest way of following a trade or user request through the system in the log files. It also doesn't require extending or writing your own logger.
我们需要解决过去类似的问题。我们创建了一个封装的消息对象,其中还包含有关消息的元数据(例如用户事务 ID)和一个自定义附加程序类。在这个 appender 类中,我们使用 instanceof 语句从信封中获取元数据,而不是简单地调用 toString(它应该为一般的 appender 返回一个不错的日志)。
或者您可以考虑使用 SLF4J,它是通过日志消息传递标记对象的标准功能。例如,查看 Javadoc 以了解他们的debug(Marker marker, String msg)方法重载。
One more idea, instead of passing a StringBuilder instance through-out the layers, which might lead to pretty awkward API (additional method parameters), you could consider using java.lang.ThreadLocal
to hold the current context that could be dumped to the log at the very end.