java - Logback 日志由应用程序保持打开状态,不会从磁盘中删除

标签 java linux spring logging logback

我在 Linux 上有一个 Spring-Boot 应用程序,它使用 Logback 写入服务日志。 Logback 被设置为写入文件 (account-service.log) 并以 10.5MB 的速度旋转文件,最后在第 8 次旋转时删除文件。这是默认配置。

我遇到的问题是创建的第一个日志文件被写入到超过 10.5MB 的大小限制(它确实以 10.5MB 标记旋转)。所以它的大小一直在增加,直到它成为第 8 个文件,然后它试图被删除。此时文件大小为84MB(10.5MB * 8)。 You can see here the file increasing in size

主要问题是操作系统试图删除文件,但由于应用程序,由于 Logback,仍然保持打开状态,然后文件系统不显示已删除的文件(如命令 finddu),系统仍然保留磁盘上分配的空间。此外,该文件仍在写入,因此它占用了越来越多的磁盘空间。我跑了 sudo lsof | grep deleted 发现这个文件没有被完全删除。

同样有趣的是,第一个文件所属的组与其余的不同。第一个文件有组 root,而其余文件有正确的组名 account-service。这可能是应用程序无法关闭文件的原因,但我不确定。

Logback 依赖来 self 的 Spring-Boot pom:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.1.RELEASE</version>
</parent>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Dalston.SR4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

后续的日志文件确实可以正常删除,并且不会写入超过 10.5 MB 的限制。

有没有人看到过这个问题或找到了解决方法?

最佳答案

所以我能够解决我的大部分问题,但仍然存在一个问题。

主要问题是我使用内置的 logback xml 进行日志记录 (base.xml)。在那里它被配置为启用控制台和文件日志记录。

<root level="INFO">
    <appender-ref ref="CONSOLE" />
    <appender-ref ref="FILE" />
</root>

因此,当我在本地运行它时,我的日志会写入我的终端和服务日志文件,这很好,但问题出现在已部署的实例上。发生的事情是“CONSOLE”和“FILE”记录器都在写入文件,这就是为什么即使在第一个文件轮换之后,它仍然在被写入。 “CONSOLE”记录器正在写入第一个文件,即使它旋转了,因为从它的角度来看,该文件是终端。这也有助于解决我们看到的双重日志记录问题。

我的解决方法是添加我自己的 logback xml (logback-spring.xml) 来覆盖 base.xml。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<springProfile name="default">
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
</springProfile>
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<root level="INFO">
    <appender-ref ref="FILE" />
</root>

这会停止对已部署实例的控制台日志记录,从而防止第一个文件记录超过 10.5MB 的限制。此修复程序也解决了我们遇到的磁盘空间问题。

我唯一没能解决的问题是为什么文件被应用程序保持打开状态,因此不允许它从磁盘空间中完全删除。

关于java - Logback 日志由应用程序保持打开状态,不会从磁盘中删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47664337/

相关文章:

linux - 未记录的内核引导参数?

linux - Linux 中有暂停/恢复信号吗?

linux - 在 Linux 上通过 NFS 触发 inotify 事件?

java - Spring:验证整个对象的方法

spring - Spring-Websockets 4.2 中使用 SockJS 的部分消息

spring - 在 Spring LTW 环境中使用 Maven 运行单元测试

java - 如何使用 JDO 3.0 从 App Engine 数据存储区获取所有对象?

java - 在 Intellij : ClassNotFoundException: org. apache.woden.WSDLException 中生成 WSDL 时出错

java - windows认证方式JDBC连接MSSQL服务器

java - 这是将 MVVM 结构与 ViewModel 和 RecyclerView 一起使用而没有任何问题的正确方法吗?