如何配置嵌入式Undertow将服务器日志保存至每日滚动文件
实现Undertow日志按日滚动存储
好的,要给你的嵌入式Undertow实现类似JBoss的按日滚动日志,最灵活的方案是用SLF4J + Logback接管所有日志输出,下面一步步来实现:
一、引入必要依赖(Maven为例)
Undertow默认使用Java Util Logging(JUL),我们需要把JUL的日志桥接到SLF4J,再用Logback实现按日滚动。在pom.xml里添加以下依赖:
<!-- SLF4J API 核心 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.9</version> </dependency> <!-- Logback 日志实现 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.4.11</version> </dependency> <!-- 桥接JUL到SLF4J,确保Undertow的日志能被统一处理 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>2.0.9</version> </dependency>
二、配置Logback实现按日滚动
在src/main/resources下创建logback.xml配置文件,这是核心的滚动日志规则配置:
<configuration> <!-- 可选:保留控制台日志输出 --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <!-- 按日滚动的文件输出核心配置 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 当前日志文件的路径和名称 --> <file>logs/undertow-service.log</file> <!-- 按日期滚动的策略 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 归档日志的文件名格式,自动追加日期 --> <fileNamePattern>logs/undertow-service.%d{yyyy-MM-dd}.log</fileNamePattern> <!-- 保留历史日志的天数,按需调整 --> <maxHistory>30</maxHistory> <!-- 可选:设置总日志容量上限,超过后自动清理旧日志 --> <totalSizeCap>10GB</totalSizeCap> </rollingPolicy> <!-- 日志内容格式 --> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <!-- 根日志级别,指定输出目标 --> <root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/> </root> <!-- 单独设置Undertow相关包的日志级别,比如DEBUG可以查看更详细的服务器日志 --> <logger name="io.undertow" level="INFO"/> </configuration> 这个配置会实现: - 在项目根目录下自动生成`logs`文件夹,`undertow-service.log`作为当前日志文件 - 每天零点自动将当日日志归档为`undertow-service.xxxx-xx-xx.log`格式的文件 - 保留最近30天的历史日志,总容量超过10GB时自动清理旧文件 - 同时保留控制台日志(不需要的话可以删除`<appender-ref ref="CONSOLE"/>`) ## 三、修改启动代码,启用JUL到SLF4J的桥接 在你的`Server`类启动前,需要初始化桥接逻辑,确保Undertow的JUL日志能被SLF4J接管。补全并修改你的代码: ```java import org.slf4j.bridge.SLF4JBridgeHandler; import java.util.logging.LogManager; import io.undertow.Undertow; import io.undertow.servlet.Servlets; import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer; import org.jboss.resteasy.spi.ResteasyDeployment; import org.jboss.resteasy.core.ResteasyDeploymentImpl; public class Server { public static void main(String[] args) { // 初始化JUL到SLF4J的桥接,避免日志丢失 LogManager.getLogManager().reset(); SLF4JBridgeHandler.install(); UndertowJaxrsServer server = new UndertowJaxrsServer(); ResteasyDeployment deployment = new ResteasyDeploymentImpl(); deployment.setApplicationClass(ExampleApplication.class.getName()); deployment.setInjectorFactoryClass("org.jboss.resteasy.cdi.CdiInjectorFactory"); DeploymentInfo deploymentInfo = server.undertowDeployment(deployment, "/"); deploymentInfo.setClassLoader(Server.class.getClassLoader()); deploymentInfo.setDeploymentName("service"); deploymentInfo.setContextPath("/service"); deploymentInfo.addListener(Servlets.listener(Listener.class)); server.deploy(deploymentInfo); // 补全Undertow启动逻辑 Undertow.builder() .addHttpListener(8080, "localhost") .setHandler(server.start()) .build() .start(); } }
四、验证效果
启动服务器后,你会看到项目根目录下生成logs文件夹,里面有当前的日志文件和每日归档的历史文件,完全符合JBoss的按日滚动模式。
补充:原生JUL配置(不推荐)
如果不想引入SLF4J和Logback,也可以用JUL的FileHandler实现滚动,但需要自定义处理器或使用第三方JUL滚动组件,灵活性远不如Logback,因此更推荐上面的方案。
内容的提问来源于stack exchange,提问作者fareed
相关产品推荐
相关产品推荐

