logback.xml相关配置——springboot项目

要在 Spring Boot 项目中将日志写入到 Logback 的配置文件 logback.xml 中,你可以按照以下步骤进行设置:

  1. 创建 Logback 配置文件

    • 在 src/main/resources 目录下创建一个名为 logback.xml 的文件。这是默认的 Logback 配置文件名,Spring Boot 会自动加载这个文件。
  2. 配置 Logback 输出到文件

    • 在 logback.xml 文件中,配置一个 <appender> 来定义日志输出的方式。你可以使用 RollingFileAppender 李定义日志输出到文件中。
    • 配置 <file> 标签来指定日志文件的路径和文件名。确保路径是相对于项目根目录的。
    • 配置 <encoder> 标签来定义日志的格式。
  3. 配置日志级别

    • 使用 <root> 标签来配置根日志记录器,并设置合适的日志级别,例如 <level value="INFO" />
  4. Spring Boot 应用中使用 Logback

    • 在 Spring Boot 项目中,Logback 通常是默认的日志框架。你不需要额外的配置来使用 Logback,只需确保 logback.xml 文件正确配置即可。
  5. 重启应用

    • 一旦你修改了 logback.xml 文件,你可能需要重启你的 Spring Boot 应用程序,以使新的日志配置生效。

下面是一个示例的 logback.xml 配置文件,用于将日志输出到 logs/app.log 文件中:

<configuration>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/app.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>7</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>


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

</configuration>

在这个配置中:

  • <maxFileSize>10MB</maxFileSize> 设置了日志文件的最大大小为 10MB。
  • <fileNamePattern>logs/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern> 定义了日志文件的命名模式,%i 表示当文件大小超过限制时,新文件会被命名为 app.日期.序号.log,例如 app.2024-05-21.1.log
  • <maxHistory>7</maxHistory> 表示保留的历史日志文件数量为 7 个,超过这个数量的日志文件将被删除。

通过这样的配置,当 app.log 文件大小超过 10MB 时,Logback 会自动将该文件改名为 app1.log,并创建新的 app.log 文件来继续写入日志。同时,历史日志文件会根据 maxHistory 的设置进行保留和管理。

  • <timeBasedFileNamingAndTriggeringPolicy> 是 Logback 中的一个类,具体是 ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP。这个类是用于基于时间和文件大小来命名和触发日志文件滚动的策略。

在 Logback 的 RollingFileAppender 中,你可以配置一个 RollingPolicy 来定义日志文件滚动的方式。SizeAndTimeBasedFNATP 是一个结合了时间和文件大小的策略,它可以根据时间和文件大小来触发日志文件的滚动。

具体来说,SizeAndTimeBasedFNATP 可以根据以下两个条件来触发日志文件的滚动:

  1. 时间条件:根据时间来触发日志文件的滚动,例如每天、每小时或者其他时间间隔。
  2. 文件大小条件:根据日志文件的大小来触发日志文件的滚动,当日志文件达到设定的最大大小时,会触发滚动。

通过结合时间和文件大小条件,SizeAndTimeBasedFNATP 可以帮助你控制日志文件的大小和保留历史日志的数量,以避免日志文件过大或占用过多磁盘空间。

在 Logback 的配置中,你可以使用 <timeBasedFileNamingAndTriggeringPolicy> 元素来配置这种基于时间和文件大小的日志文件滚动策略,以便更灵活地管理日志文件的滚动和保留。

下面是一个完整的logback.xml的配置,可根据自己的要求自行修改

<?xml version="1.0" encoding="UTF-8"?>
<!-- scan : 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true-->
<configuration scan="false" scanPeriod="60 seconds" debug="false">
    <!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
    <!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
    <!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
    <!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
    <contextName>logback</contextName>
    <property name="log.path" value="logs"></property>
    <property name="Console_Pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%logger{50}] - %msg%n"/>

    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <Pattern>${Console_Pattern}</Pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 时间滚动输出 level为 INFO 日志 -->
    <appender name="RollingFileInfo" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/info.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{50}] - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>1  MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 时间滚动输出 level为 WARN 日志 -->
    <appender name="RollingFileWarn" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/warn.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{50}] - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>1MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录warn级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 时间滚动输出 level为 ERROR 日志 -->
    <appender name="RollingFileError" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/error.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{50}] - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>1MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录ERROR级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!--additivity:是否继承root节点,默认是true继承。默认情况下子Logger会继承父Logger的appender,
    也就是说子Logger会在父Logger的appender里输出。
    若是additivity设为false,则子Logger只会在自己的appender里输出,而不会在父Logger的appender里输出。-->
    <logger name="org.springframework" level="INFO" additivity="false">
        <appender-ref ref="Console"/>
        <appender-ref ref="RollingFileInfo"/>
    </logger>
    <logger name="org.mybatis" level="INFO"></logger>
    <Logger name="org.apache.catalina" level="info"/>
    <Logger name="org.apache.tomcat.util" level="info"/>
    <!-- 从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF-->
    <root level="ALL">
        <appender-ref ref="Console"/>
        <appender-ref ref="RollingFileInfo"/>
        <appender-ref ref="RollingFileWarn"/>
        <appender-ref ref="RollingFileError"/>
    </root>

    <!--生产环境:输出到文件-->
    <springProfile name="pro">
        <root level="info">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileWarn"/>
            <appender-ref ref="RollingFileError"/>
        </root>
    </springProfile>
</configuration>

18:00:32,438 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [CONFIG_LOG_FILE] 18:00:32,439 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:00:32,464 |-INFO in ch.qos.logback.core.rolling.FixedWindowRollingPolicy@366d8b97 - No compression will be used 18:00:32,467 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:32,483 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[CONFIG_LOG_FILE] - Active log file name: /root/logs/nacos/config.log 18:00:32,483 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[CONFIG_LOG_FILE] - File property is set to [/root/logs/nacos/config.log] 18:00:32,484 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [ASYNC-CONFIG] 18:00:32,484 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender] 18:00:32,486 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [CONFIG_LOG_FILE] to ch.qos.logback.classic.AsyncAppender[ASYNC-CONFIG] 18:00:32,487 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-CONFIG] - Attaching appender named [CONFIG_LOG_FILE] to AsyncAppender. 18:00:32,487 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-CONFIG] - Setting discardingThreshold to 0 18:00:32,487 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [NAMING_LOG_FILE] 18:00:32,487 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:00:32,488 |-INFO in ch.qos.logback.core.rolling.FixedWindowRollingPolicy@feb98ef - No compression will be used 18:00:32,488 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:32,489 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[NAMING_LOG_FILE] - Active log file name: /root/logs/nacos/naming.log 18:00:32,489 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[NAMING_LOG_FILE] - File property is set to [/root/logs/nacos/naming.log] 18:00:32,489 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [ASYNC-NAMING] 18:00:32,489 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender] 18:00:32,489 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [NAMING_LOG_FILE] to ch.qos.logback.classic.AsyncAppender[ASYNC-NAMING] 18:00:32,489 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-NAMING] - Attaching appender named [NAMING_LOG_FILE] to AsyncAppender. 18:00:32,489 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-NAMING] - Setting discardingThreshold to 0 18:00:32,489 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [REMOTE_LOG_FILE] 18:00:32,489 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:00:32,490 |-INFO in ch.qos.logback.core.rolling.FixedWindowRollingPolicy@7654f833 - No compression will be used 18:00:32,490 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:32,490 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[REMOTE_LOG_FILE] - Active log file name: /root/logs/nacos/remote.log 18:00:32,490 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[REMOTE_LOG_FILE] - File property is set to [/root/logs/nacos/remote.log] 18:00:32,491 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [ASYNC-REMOTE] 18:00:32,491 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender] 18:00:32,491 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [REMOTE_LOG_FILE] to ch.qos.logback.classic.AsyncAppender[ASYNC-REMOTE] 18:00:32,491 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-REMOTE] - Attaching appender named [REMOTE_LOG_FILE] to AsyncAppender. 18:00:32,491 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-REMOTE] - Setting discardingThreshold to 0 18:00:32,491 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.alibaba.nacos.client] to INFO 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.alibaba.nacos.client] to false 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [ASYNC-CONFIG] to Logger[com.alibaba.nacos.client] 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.alibaba.nacos.common.labels] to INFO 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.alibaba.nacos.common.labels] to false 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [ASYNC-REMOTE] to Logger[com.alibaba.nacos.common.labels] 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.alibaba.nacos.common.remote.client] to INFO 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.alibaba.nacos.common.remote.client] to false 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [ASYNC-REMOTE] to Logger[com.alibaba.nacos.common.remote.client] 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.alibaba.nacos.shaded.io.grpc] to INFO 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.alibaba.nacos.shaded.io.grpc] to false 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [ASYNC-REMOTE] to Logger[com.alibaba.nacos.shaded.io.grpc] 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.alibaba.nacos.client.config] to INFO 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.alibaba.nacos.client.config] to false 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [ASYNC-CONFIG] to Logger[com.alibaba.nacos.client.config] 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting level of logger [com.alibaba.nacos.client.naming] to INFO 18:00:32,494 |-INFO in ch.qos.logback.classic.model.processor.LoggerModelHandler - Setting additivity of logger [com.alibaba.nacos.client.naming] to false 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [ASYNC-NAMING] to Logger[com.alibaba.nacos.client.naming] 18:00:32,494 |-INFO in ch.qos.logback.core.model.processor.DefaultProcessor@571a01f9 - End of configuration. 18:00:32,495 |-INFO in com.alibaba.nacos.logbackadapter.NacosLogbackConfiguratorAdapterV2@42f33b5d - Registering current configuration as safe fallback point 18:00:33,840 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-CONFIG] - Worker thread will flush remaining events before exiting. 18:00:33,841 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-CONFIG] - Queue flush finished successfully within timeout. 18:00:33,841 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-NAMING] - Worker thread will flush remaining events before exiting. 18:00:33,841 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-NAMING] - Queue flush finished successfully within timeout. 18:00:33,841 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-REMOTE] - Worker thread will flush remaining events before exiting. 18:00:33,841 |-INFO in ch.qos.logback.classic.AsyncAppender[ASYNC-REMOTE] - Queue flush finished successfully within timeout. 18:00:33,847 |-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList@d7109be - URL [jar:nested:/app/workflow.jar/!BOOT-INF/classes/!/logback-plus.xml] is not of type file 18:00:33,855 |-INFO in ch.qos.logback.core.joran.util.ConfigurationWatchListUtil@5e0ec41f - Adding [jar:nested:/app/workflow.jar/!BOOT-INF/lib/ruoyi-common-web-2.2.1.jar!/logback-common.xml] to configuration watch list. 18:00:33,855 |-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList@d7109be - URL [jar:nested:/app/workflow.jar/!BOOT-INF/lib/ruoyi-common-web-2.2.1.jar!/logback-common.xml] is not of type file 18:00:33,863 |-WARN in ch.qos.logback.core.joran.action.IncludeAction - Could not find resource corresponding to [logback-logstash.xml] 18:00:33,864 |-WARN in ch.qos.logback.core.joran.action.IncludeAction - Could not find resource corresponding to [logback-skylog.xml] 18:00:33,869 |-INFO in ch.qos.logback.classic.model.processor.ConfigurationModelHandlerFull - Registering a new ReconfigureOnChangeTask ReconfigureOnChangeTask(born:1749722433867) 18:00:33,869 |-INFO in ch.qos.logback.classic.model.processor.ConfigurationModelHandlerFull - Will scan for changes in [jar:nested:/app/workflow.jar/!BOOT-INF/classes/!/logback-plus.xml] 18:00:33,869 |-INFO in ch.qos.logback.classic.model.processor.ConfigurationModelHandlerFull - Setting ReconfigureOnChangeTask scanning period to 1 minutes 18:00:33,870 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [console] 18:00:33,870 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender] 18:00:33,870 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:33,872 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [file_console] 18:00:33,872 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:00:33,873 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@256522893 - No compression will be used 18:00:33,874 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@256522893 - Will use the pattern logs/ruoyi-workflow/console.%d{yyyy-MM-dd}.log for the active file 18:00:33,883 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - The date pattern is 'yyyy-MM-dd' from file name pattern 'logs/ruoyi-workflow/console.%d{yyyy-MM-dd}.log'. 18:00:33,883 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Roll-over at midnight. 18:00:33,883 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Setting initial period to 2025-06-12T10:00:33.883Z 18:00:33,884 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:33,888 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[file_console] - Active log file name: logs/ruoyi-workflow/console.log 18:00:33,888 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[file_console] - File property is set to [logs/ruoyi-workflow/console.log] 18:00:33,888 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [file_info] 18:00:33,888 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:00:33,888 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@148436820 - No compression will be used 18:00:33,888 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@148436820 - Will use the pattern logs/ruoyi-workflow/info.%d{yyyy-MM-dd}.log for the active file 18:00:33,889 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - The date pattern is 'yyyy-MM-dd' from file name pattern 'logs/ruoyi-workflow/info.%d{yyyy-MM-dd}.log'. 18:00:33,889 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Roll-over at midnight. 18:00:33,889 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Setting initial period to 2025-06-12T10:00:33.889Z 18:00:33,889 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:33,891 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[file_info] - Active log file name: logs/ruoyi-workflow/info.log 18:00:33,891 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[file_info] - File property is set to [logs/ruoyi-workflow/info.log] 18:00:33,891 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [file_error] 18:00:33,891 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 18:00:33,892 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@224473864 - No compression will be used 18:00:33,892 |-INFO in c.q.l.core.rolling.TimeBasedRollingPolicy@224473864 - Will use the pattern logs/ruoyi-workflow/error.%d{yyyy-MM-dd}.log for the active file 18:00:33,892 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - The date pattern is 'yyyy-MM-dd' from file name pattern 'logs/ruoyi-workflow/error.%d{yyyy-MM-dd}.log'. 18:00:33,892 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Roll-over at midnight. 18:00:33,893 |-INFO in c.q.l.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy - Setting initial period to 2025-06-12T10:00:33.893Z 18:00:33,893 |-INFO in ch.qos.logback.core.model.processor.ImplicitModelHandler - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 18:00:33,893 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[file_error] - Active log file name: logs/ruoyi-workflow/error.log 18:00:33,893 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[file_error] - File property is set to [logs/ruoyi-workflow/error.log] 18:00:33,894 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [async_info] 18:00:33,894 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender] 18:00:33,894 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [file_info] to ch.qos.logback.classic.AsyncAppender[async_info] 18:00:33,894 |-INFO in ch.qos.logback.classic.AsyncAppender[async_info] - Attaching appender named [file_info] to AsyncAppender. 18:00:33,894 |-INFO in ch.qos.logback.classic.AsyncAppender[async_info] - Setting discardingThreshold to 0 18:00:33,894 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - Processing appender named [async_error] 18:00:33,894 |-INFO in ch.qos.logback.core.model.processor.AppenderModelHandler - About to instantiate appender of type [ch.qos.logback.classic.AsyncAppender] 18:00:33,894 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [file_error] to ch.qos.logback.classic.AsyncAppender[async_error] 18:00:33,894 |-INFO in ch.qos.logback.classic.AsyncAppender[async_error] - Attaching appender named [file_error] to AsyncAppender. 18:00:33,894 |-INFO in ch.qos.logback.classic.AsyncAppender[async_error] - Setting discardingThreshold to 0 18:00:33,895 |-INFO in ch.qos.logback.classic.model.processor.RootLoggerModelHandler - Setting level of ROOT logger to INFO 18:00:33,895 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@25673087 - Propagating INFO level on Logger[ROOT] onto the JUL framework 18:00:33,895 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [async_info] to Logger[ROOT] 18:00:33,895 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [async_error] to Logger[ROOT] 18:00:33,895 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [file_console] to Logger[ROOT] 18:00:33,895 |-INFO in ch.qos.logback.classic.model.processor.RootLoggerModelHandler - Setting level of ROOT logger to INFO 18:00:33,895 |-INFO in ch.qos.logback.core.model.processor.AppenderRefModelHandler - Attaching appender named [console] to Logger[ROOT] 18:00:33,896 |-INFO in ch.qos.logback.core.model.processor.DefaultProcessor@7b27e8f4 - End of configuration. 18:00:33,896 |-INFO in org.springframework.boot.logging.logback.SpringBootJoranConfigurator@348ad293 - Registering current configuration as safe fallback point :: Dubbo (v3.2.14) : https://github.com/apache/dubbo :: Discuss group : dev@dubbo.apache.org Spring Boot Version: 3.2.9 Spring Application Name: ruoyi-workflow _ _ __ _ (_) | | / _| | _ __ _ _ ___ _ _ _ ________ _____ _ __| | _| |_| | _____ __ | '__| | | |/ _ \| | | | |______\ \ /\ / / _ \| '__| |/ / _| |/ _ \ \ /\ / / | | | |_| | (_) | |_| | | \ V V / (_) | | | <| | | | (_) \ V V / |_| \__,_|\___/ \__, |_| \_/\_/ \___/|_| |_|\_\_| |_|\___/ \_/\_/ __/ | |___/ 2025-06-12 18:00:34 [main] INFO  o.d.w.RuoYiWorkflowApplication  - Starting RuoYiWorkflowApplication using Java 17.0.2 with PID 1 (/app/workflow.jar started by root in /app) 2025-06-12 18:00:34 [main] INFO  o.d.w.RuoYiWorkflowApplication  - The following 1 profile is active: "prod" 2025-06-12 18:00:34 [main] INFO  c.a.c.n.c.NacosConfigDataLoader  - [Nacos Config] Load config[dataId=ruoyi-workflow.yml, group=ARCHIVES] success 2025-06-12 18:00:34 [main] INFO  c.a.c.n.c.NacosConfigDataLoader  - [Nacos Config] Load config[dataId=datasource.yml, group=ARCHIVES] success 2025-06-12 18:00:34 [main] INFO  c.a.c.n.c.NacosConfigDataLoader  - [Nacos Config] Load config[dataId=application-common.yml, group=ARCHIVES] success 2025-06-12 18:00:41 [main] WARN  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext  - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server 2025-06-12 18:00:41 [main] ERROR o.s.b.d.LoggingFailureAnalysisReporter  - *************************** APPLICATION FAILED TO START *************************** Description: Web application could not be started as there was no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context. Action: Check your application's dependencies for a supported servlet web server. Check the configured web application type. 2025-06-12 18:00:41 [Thread-6] WARN  c.a.nacos.common.notify.NotifyCenter  - [NotifyCenter] Start destroying Publisher 2025-06-12 18:00:41 [Thread-6] WARN  c.a.nacos.common.notify.NotifyCenter  - [NotifyCenter] Destruction of the end 2025-06-12 18:00:41 [Thread-4] WARN  c.a.n.c.http.HttpClientBeanHolder  - [HttpClientBeanHolder] Start destroying common HttpClient 2025-06-12 18:00:41 [Thread-4] WARN  c.a.n.c.http.HttpClientBeanHolder  - [HttpClientBeanHolder] Destruction of the end 分析日志给出解决办法
06-13
<think>我们正在解决SpringBoot应用启动失败的问题,报错信息是“Unabletostartwebserver,缺少org.springframework.boot.web.servlet.server.ServletWebServerFactorybean”。这个错误通常是由于SpringBoot无法找到合适的ServletWebServerFactory来创建Web服务器(如Tomcat)导致的。根据提供的引用,我们可以总结出以下几个常见原因及解决方法:1.**缺少必要的依赖**:SpringBoot默认使用Tomcat作为内嵌容器,依赖包含在`spring-boot-starter-web`中。如果项目中缺少这个依赖,就会导致无法创建Web服务器。2.**排除了Tomcat依赖**:有时项目需要外置Tomcat,可能会排除内置Tomcat,但如果没有正确配置外置容器,就会导致此错误。3.**依赖冲突**:项目中可能存在与Tomcat相关的依赖冲突,导致SpringBoot无法正常创建ServletWebServerFactorybean。###解决方法:####1.检查并添加`spring-boot-starter-web`依赖确保项目的构建文件(如pom.xml)中包含`spring-boot-starter-web`依赖。如果没有,请添加:```xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>```####2.检查是否排除了Tomcat依赖如果项目需要使用外置Tomcat,通常会排除内置Tomcat,但必须确保同时提供了ServletAPI的依赖。检查是否在排除内置Tomcat的同时没有提供ServletAPI,或者没有正确配置外置Tomcat。-**错误示例**:排除了Tomcat但没有提供ServletAPI依赖:```xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency>```此时,需要添加ServletAPI依赖:```xml<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency>```或者,如果使用JakartaServlet(如SpringBoot3.x以上),则使用:```xml<dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><version>6.0.0</version><scope>provided</scope></dependency>```####3.检查依赖冲突使用Maven的依赖树命令检查是否有冲突的依赖:```bashmvndependency:tree```查看是否有多个不同版本的Tomcat相关依赖,或者有依赖排除了Tomcat。解决冲突可能需要排除一些传递依赖。####4.检查SpringBoot自动配置确保应用主类(带有`@SpringBootApplication`注解的类)所在的包位置正确,并且能够扫描到配置。如果使用了`@SpringBootApplication(exclude=...)`排除了自动配置,确保没有排除与Web服务器相关的自动配置。####5.检查是否错误地配置了Web服务器类型在`application.properties`或`application.yml`中,检查是否设置了正确的服务器类型,例如:```propertiesspring.main.web-application-type=none```如果设置为`none`,则SpringBoot不会启动Web服务器。如果需要Web服务器,请删除此配置或设置为`servlet`(默认值)。####6.检查自定义的ServletWebServerFactory配置如果自定义了`ServletWebServerFactory`bean,确保它被正确创建。例如,在配置类中:```java@BeanpublicServletWebServerFactoryservletWebServerFactory(){returnnewTomcatServletWebServerFactory();}```如果配置不正确,可能导致SpringBoot无法创建该bean。###总结步骤:1.检查`spring-boot-starter-web`依赖是否存在。2.检查是否排除了Tomcat而没有提供ServletAPI(外置Tomcat情况)。3.检查依赖冲突。4.检查自动配置和主类配置。5.检查配置文件中的`spring.main.web-application-type`设置。6.检查自定义的`ServletWebServerFactory`配置。通过以上步骤,通常可以解决“缺少ServletWebServerFactorybean”的问题。§§相关问题§§1.如何排查SpringBoot应用启动时的依赖冲突?2.SpringBoot如何切换内嵌服务器(例如从Tomcat切换到Jetty)?3.使用外置Tomcat启动SpringBoot应用需要哪些配置?4.SpringBoot自动配置的原理是什么?</think>### Spring Boot应用启动失败:缺少ServletWebServerFactory Bean的解决方案 该报错表明Spring Boot无法创建Web服务器,通常由以下原因导致。请按顺序排查: #### 1. **检查基础依赖配置** Spring Boot默认使用Tomcat容器,依赖包含在`spring-boot-starter-web`中: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- 必须存在 --> </dependency> </dependencies> ``` **解决方法**: - 若缺失该依赖,在`pom.xml`中添加 - 若使用Gradle,添加:`implementation 'org.springframework.boot:spring-boot-starter-web'` #### 2. **排查Tomcat依赖被排除** 当需要外置Tomcat时,开发者可能误排除内置Tomcat: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <!-- 错误示例:移除了Tomcat导致容器缺失 --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> ``` **解决方法**: - **方案1**:移除`<exclusion>`标签恢复内置Tomcat - **方案2**:改用外置Tomcat时,**必须同步添加Servlet API依赖**: ```xml <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> </dependency> ``` #### 3. **检查依赖冲突** 其他依赖可能覆盖Spring Boot默认配置: - 执行`mvn dependency:tree`查看依赖树 - 重点关注冲突的Servlet/Tomcat版本(如旧版`javax.servlet-api`) **解决方法**: ```xml <dependency> <groupId>冲突的groupId</groupId> <artifactId>冲突的artifactId</artifactId> <exclusions> <exclusion> <!-- 排除冲突的Servlet/Tomcat包 --> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> </exclusion> </exclusions> </dependency> ``` #### 4. **检查自动配置排除** 若手动排除了Web自动配置: ```java @SpringBootApplication(exclude = { WebMvcAutoConfiguration.class, // 错误排除会导致容器失效 ServletWebServerFactoryAutoConfiguration.class }) ``` **解决方法**:移除不必要的`exclude`配置项。 #### 5. **验证项目结构** 确保主启动类位于根包下: ``` src/main/java └── com.example └── Application.java // 带有@SpringBootApplication的类 └── controller // 子包能被自动扫描 ``` #### 6. **检查特殊配置** 确认`application.properties`中未禁用Web服务器: ```properties # 错误配置示例 spring.main.web-application-type=none // 改为servlet或删除 ``` > **关键总结**: > 80%的案例源于依赖问题——要么缺少`spring-boot-starter-web`,要么误排除了Tomcat而未补充Servlet API[^1][^3]。优先检查`pom.xml`中的依赖配置,再排查其他可能性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值