缓冲记录器(Java)

缓冲记录器(Java),java,logging,log4j,Java,Logging,Log4j,我一直在考虑构建一个日志系统,将日志语句推送到内部缓冲区,直到达到预定义的容量,然后立即转储(刷新)整个缓冲区 这是因为我喜欢在我的方法中散布大量的跟踪语句(这样我就可以每隔几行看到发生了什么;至少对我来说,这样更容易调试)。我担心,由于(可能)成百上千的日志语句到处都是,如此大的I/O需求将使我的程序陷入困境 “缓冲”记录器解决方案可能会缓解这一问题 三个问题: 这样的事情已经存在了吗?我讨厌在这里重新发明轮子,但在线搜索并没有改变任何事情 我在考虑这样一个事实:每当程序意外停止(运行时异常等

我一直在考虑构建一个日志系统,将日志语句推送到内部缓冲区,直到达到预定义的容量,然后立即转储(刷新)整个缓冲区

这是因为我喜欢在我的方法中散布大量的跟踪语句(这样我就可以每隔几行看到发生了什么;至少对我来说,这样更容易调试)。我担心,由于(可能)成百上千的日志语句到处都是,如此大的I/O需求将使我的程序陷入困境

“缓冲”记录器解决方案可能会缓解这一问题

三个问题:

  • 这样的事情已经存在了吗?我讨厌在这里重新发明轮子,但在线搜索并没有改变任何事情
  • 我在考虑这样一个事实:每当程序意外停止(运行时异常等)并且记录器没有被刷新时,我很可能会丢失日志语句。在这种情况下,我希望记录器重写finalize(),这样,如果程序终止时缓冲区中仍有项目,它可以在退出之前刷新(发布)它们。想法
  • 这是个糟糕的主意吗?如果是,为什么
    如果可以避免的话,不要重新发明这个特殊的轮子。看看吧,或者更好

    如果不进行跟踪,Log4j和slf4j的性能都非常好,因此在生产系统中,您可以降低日志记录的级别,并且仍然具有良好的性能

    log4j和slf4j都会立即写入日志文件并刷新,默认情况下不执行缓冲,因为您希望在日志文件中看到导致崩溃的异常。如果您真的想添加缓冲,可以这样做()

    就finalize()而言,不能保证在退出时调用它。从

    不赞成。这种方法本质上是不安全的。这可能会导致 在激活其他线程时对活动对象调用终结器 同时操纵这些对象,导致行为不稳定 或者僵局。在退出时启用或禁用终结;这样做 指定具有终结器的所有对象的终结器 尚未被自动调用的都是要在Java之前运行的 运行时退出默认情况下,退出时的终结被禁用


    我的重点。因此,不,似乎一个缓冲的记录器会有固有的问题。

    不知道现有的框架,因为本地内存中没有“缓冲区”。但请查看标准Log4J等


    finalize()
    不是正确的选择。使用
    Runtime.addShutdownHook()
    。最近见。

    我将证实你提出的第三个问题。这是一个糟糕的想法,它与您作为程序员的技能无关。它与log4j等项目所暴露的场景数量以及它们所解释的不同边缘案例有关。我认为这项任务对你们来说是相当大的,在今后的道路上会引起很多麻烦

    Log4J已经支持IO缓冲。Log4J上的一些不错的性能提示

    我们对生产服务器做了类似的事情,只是它们通过网络连接触发日志消息。我们只是有一个有界链接队列,并决定在队列已满时弹出调试消息和保留错误。然后,我们在后台有一个线程将消息发送到服务器

  • 我不知道log4j或slf4j中有这样的东西

  • 丢失消息的唯一方法是JVM崩溃,在这种情况下,缓冲区写入程序也会遇到同样的问题。如果您编写的线程不是守护进程,那么在退出应用程序之前,它可以在应用程序停止时完成日志消息的编写

  • 这是一个糟糕想法的唯一原因是如果日志记录确实没有性能问题。最好确保将日志调用隔离到自己的日志包装器中,以防将来需要将它们排队。但就短期而言,只需直接写信给log4j或其他什么。您还可以在这个包装类中放入一些统计信息,以查看日志消息是否阻碍了进程,然后做出明智的决定,通过排队来提高它的性能


  • 如前所述——不要再发明轮子——使用log4j甚至更好的logback(它的继承者),但要明智地使用它。默认的简单附加器会立即写入并刷新到磁盘,这将影响应用程序的整体性能。通常,appender在调用程序的线程上执行繁重的工作。为了避免这种情况,您可以编写自己的appender(使用缓冲)或使用wrappers(根据框架的不同,您可以使用异步行为包装某些appender,而无需编写单行代码)。我有这样一个appender(见页面底部),你可以自由使用代码,或者只是想一想。我的appender针对TCP套接字工作,但问题是相同的——防止阻塞调用方,并在单独的线程上进行刷新,以便顶部的应用程序永远感觉不到它。

    大多数文件系统已经处理缓冲,我怀疑(未经确认)基于文件的记录器已经使用了缓冲写入程序<如果程序退出,可能会调用或不调用代码>finalize()。这不是一个糟糕的想法,我只是不确定这是否是一个好的投资回报率,因为只有在开发过程中才会发生。感谢Dave的洞察力。问:我的想法是,这对于任何环境都是一个好工具,包括生产环境。这样,我就可以检查生产日志,快速地重新创建任何缺陷,等等。您能否分享一下您的想法,为什么这只适合在开发过程中使用(我很好奇!)?再次感谢您,因为跟踪和调试日志级别仅用于跟踪和调试,而不是用于生产。如果您的系统需要那么多信息来跟踪问题,那么可能是其他问题。如果你真的相信