如何从多个线程记录数据?

时间:2010-10-05 12:17:47

标签: java multithreading logging

巨大的线程并行运行连续(让我们假设这个连续的部分))。所有线程都想记录一些应用程序数据,基本上是一组值。

  1. 记录此数据的最佳方法是什么?单/多文件?
  2. 备份此日志的最佳方法是什么?
  3. 从备份文件读取数据并将其转换为有用的东西的方法是什么?
  4. thisthis这样的几个主题提示了log4net和log4j,但我想知道实际的过程?多个线程如何写入同一个日志文件?每个线程都需要文件级锁定吗?这一切是如何运作的?

    任何指向理解所有细节的指标都将不胜感激。

    感谢。

3 个答案:

答案 0 :(得分:6)

可以根据您的需要配置像log4j这样的库。

  1. 分成太多文件会使调试某些问题变得困难,但是有一个单片文件会留下混合进程。我会为每个原子进程提供一个文件,也就是说,邮件管理器可能会使用自己的日志文件。 jdbc的额外调试信息可能有自己的日志文件,但主应用程序日志中仍会报告错误和重大事件。

  2. 主要日志记录库支持日志拆分和轮换。对于一个使用良好的Web应用程序,我更喜欢为每天制作一个日志文件,并且还要分割一定大小。您可以构建一个cron来压缩旧日志,根据应用程序的不同,您可能需要将它们备份几个月或无限期。

  3. 就调试实用性而言,您可以grep某些字符串,例如“Exception”来报告。如果您要查找统计信息,除了过程日志之外,还应该为该特定目的创建日志。

  4. 日志可以是同步的,也可以是异步的,后者通常最适合性能。通常,构建消息队列然后由单独的线程写入。因此,多个线程可以写入内存中的那个队列或缓冲区,一个线程将锁定并写入该文件。它几乎在后台,你不必考虑它,除非你写了大量的数据。

答案 1 :(得分:1)

关于第1点,我通常会将所有内容(与功能相关的)记录到同一个文件中,但是日志行总是包含一些上下文信息,这些信息允许我跟踪(通过grep或其他内容)上下文/请求的流程。 / p>

示例(带调用的方案):

DEBUG|CallID#12: Establishing new AUDIO call from AA to BB
DEBUG|CallID#34: Call accepted by ZZ at ...
DEBUG|CallID#99: Call terminated by callee (SS)

这样,如果有人问“今天12:34从AA到BB发生了什么事?”我只是从AA到BB(或它发生的时间)grep然后,一旦我得到了呼叫ID,获取呼叫的全部细节只是再次使用id进行重击。

聊天,在线等其他内容会出现在自己的文件中(将这些信息全部混合在一个整体文件中没有多大意义。)

如果您需要每个线程(而不是每个操作/请求),只需记录正在执行操作的线程的名称。

关于第2点,使用log4j进行每日轮换。

不确定我理解第3点......也许你的意思是解析日志文件以检索某些模式?任何支持正则表达式的工具都可以解决问题(grep是最方便的)。

答案 2 :(得分:1)

正如上面的评论所说,日志记录框架正是为了让您免于担心这些低级细节。 Log4J或其后续版本如LogBack可以安全有效地处理多个线程的日志记录。您只需告诉日志记录框架要记录的内容和位置,并且一切正常(通常: - )

对于记录特定于线程的数据,您可以考虑使用诊断上下文。这个earlier answer of mine用Log4J的例子解释了这一点。在Logback中,它已重命名为Mapped Diagnostic Context

至于备份和后期处理,一切都取决于您的实际目标。通常只需要简单的脚本或gzipgrep这样的单个命令。没有具体信息就很难说清楚。