Java 如何记录来自多个线程的数据?

Java 如何记录来自多个线程的数据?,java,multithreading,logging,Java,Multithreading,Logging,有大量线程以并行方式连续运行(假设这是连续的)。所有线程都希望记录一些应用程序数据,基本上是一组值 记录这些数据的最佳方法是什么?单个/多个文件 备份此日志的最佳方法是什么 从备份文件中读取数据并将其转换为有用内容的方法是什么 有几个线程喜欢并建议使用log4net和log4j,但我想知道实际的过程?多个线程如何写入同一个日志文件?每个线程都需要文件级锁吗?这一切是如何运作的 任何有助于理解所有细节的建议都将不胜感激 谢谢。关于第1点,我通常将所有内容(功能相关)记录到同一个文件中,但日志行始终

有大量线程以并行方式连续运行(假设这是连续的)。所有线程都希望记录一些应用程序数据,基本上是一组值

  • 记录这些数据的最佳方法是什么?单个/多个文件
  • 备份此日志的最佳方法是什么
  • 从备份文件中读取数据并将其转换为有用内容的方法是什么
  • 有几个线程喜欢并建议使用log4net和log4j,但我想知道实际的过程?多个线程如何写入同一个日志文件?每个线程都需要文件级锁吗?这一切是如何运作的

    任何有助于理解所有细节的建议都将不胜感激


    谢谢。

    关于第1点,我通常将所有内容(功能相关)记录到同一个文件中,但日志行始终包含一些上下文信息,允许我(通过grep或其他方式)跟踪上下文/请求流

    示例(包含调用的场景):

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

    其他内容,如聊天、状态等,都会放在自己的文件中(将这些信息混合在一个单一的文件中没有多大意义)

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

    关于第2点,每日旋转log4j


    我不确定我是否理解第三点。。。也许你的意思是解析一个日志文件来检索一些模式?任何支持regex的工具都可以做到这一点(grep是最方便的工具)。

    正如上面的评论所说,日志框架的存在正是为了让您不用担心这些低级细节。Log4J或其后继者(如LogBack)可以安全有效地处理多线程的日志记录。您只需告诉日志框架要记录什么以及记录在哪里,就可以了(通常是:-)

    <>对于日志记录特定数据,可以考虑使用诊断上下文。这通过Log4J的一个例子来解释这一点。在Logback中,它已重命名为


    至于备份和后期处理,这一切都取决于您的实际目标。通常,您只需要简单的脚本或单个命令,如
    gzip
    grep
    。如果没有具体的信息,很难说出更多信息。

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

  • 分割成太多的文件会使调试某些问题变得困难,但是一个单一的文件会导致混合进程的出现。每个原子进程都有一个文件,也就是说,邮件管理器可以使用自己的日志文件。jdbc的额外调试信息可能有自己的日志文件,但错误和主要事件仍将在主应用程序日志中报告

  • 主要日志库支持日志拆分和循环。对于一个使用良好的web应用程序,我更喜欢为每天创建一个日志文件,并将其拆分为一定大小。您可以构建一个cron来压缩较旧的日志,根据应用程序的不同,您可能希望将它们备份几个月或无限期

  • 就调试有用性而言,您可以grep某些字符串,例如“Exception”,以便报告。如果您正在查找统计信息,那么除了流程日志之外,还应该为该特定目的创建一个日志


  • 日志可以是同步的,也可以是异步的,后者通常对性能最好。通常,消息队列是构建的,然后由单独的线程写入。因此,多个线程可以写入内存中的一个队列或缓冲区,一个线程将锁定并写入文件。它几乎是在后台进行的,除非您正在编写大量数据,否则您不必考虑它。

    通常日志记录方法是同步的,这样您就不必担心从多个线程访问它。至于备份,在大多数文件系统中,文件系统级别上都有卷影副本——我怀疑您是否应该从应用程序内部担心这一点。使用日志框架的目的就是让您不用担心所有这些细节。@Michael Borgwardt:我明白您的意思,但我想知道细节。向下滚动至“性能”。我应该给你一些提示。
    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)