在带有 logback 配置的 Ubuntu 上部署 SpringBoot 失败并出现 FileNotFoundException (Permission Denied)

Posted

技术标签:

【中文标题】在带有 logback 配置的 Ubuntu 上部署 SpringBoot 失败并出现 FileNotFoundException (Permission Denied)【英文标题】:SpringBoot deployment on Ubuntu with logback configuration fails with FileNotFoundException (Permission Denied) 【发布时间】:2021-05-21 04:25:04 【问题描述】:

我正在尝试在ubuntu 服务器上部署简单的 SpringBoot 应用程序作为Upstart 服务。 此应用程序具有logback-spring.xml 配置,它指向创建服务日志文件的完全相同的位置,即/var/log/upstart 目录。

但是当我部署此应用程序时,它会失败并出现以下错误,表明存在一些权限问题 (Permission Denied),

线程“main”java.lang.IllegalStateException 中的异常:检测到 Logback 配置错误: java.lang.IllegalStateException:检测到 Logback 配置错误: ch.qos.logback.core.rolling.RollingFileAppender[FILE] 中的错误 - openFile(/var/log/upstart/app.log,true) 调用失败。 java.io.FileNotFoundException:/var/log/upstart.app.log(权限被拒绝) ch.qos.logback.core.rolling.RollingFileAppender[FILE] 中的错误 - openFile(/var/log/upstart/app.log,true) 调用失败。 java.io.FileNotFoundException:/var/log/upstart/app.log(权限被拒绝) 在 org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:153) 在 org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:153) ~[spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 在 org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:71) 在 org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:71) ~[spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 在 org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:49) 在 org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:49) ~[spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 在 org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:106) 在 org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:106) ~[spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 在 org.springframework.boot.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:262) 在 org.springframework.boot.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:262) ~[spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 在 org.springframework.boot.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:233) 在 org.springframework.boot.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:233) ~[spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 在 org.springframework.boot.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:200) 在 org.springframework.boot.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:200) ~[spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 在 org.springframework.boot.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:176) 在 org.springframework.boot.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:176) ~[spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE] 在 org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:163) 在 org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:163) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] 在 org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:136) 在 org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:136) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] 在 org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:119) 在 org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:119) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] 在 org.springframework.boot.context.event.EventPublishingRunListener.publishEvent(EventPublishingRunListener.java:111) 在 org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:65) 在 org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54) 在 org.springframework.boot.context.event.EventPublishingRunListener.publishEvent(EventPublishingRunListener.java:111) ~[spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE]

Logback-spring.xml 文件,

<?xml version="1.0" encoding="UTF-8"?>
<!-- Enable jmxConfiguration to allow dynamic level change through spring boot admin -->
<jmxConfigurator/>

<property resource="log.properties" />

<!-- Standard console appender used in all environments. Upstart catches logs and stores in /var/log/upstart-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>[%-5level] [%t] %d %logger35 - %msg%n</pattern>
    </encoder>
</appender>

<springProfile name="local">
    <appender name="local" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>$log.local.path/$log.name.async.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- daily rollover -->
            <fileNamePattern>$log.local.path/%dyyyy-MM-dd,aux/$log.name.async.%dyyyy-MM-dd.%i.log</fileNamePattern>
            <!-- keep 30 days' worth of history -->
            <maxHistory>7</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 256MB -->
                <maxFileSize>256MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%-5level [%t] %dyyyy-MM-dd_HH:mm:ss.SSS %logger35 - %msg%n</Pattern>
        </encoder>
    </appender>
</springProfile>

<root level="INFO">
    <appender-ref ref="console"/>
    <appender-ref ref="local"/>
</root>

log.properties 文件,

log.local.path=/var/log/upstart
log.name.async=propspace-async

【问题讨论】:

您是否尝试过授予该位置的读写权限,您可以尝试chmod 777 /var/log/upstart/ /var/log/upstart 是一个系统目录,我认为不应更改。对于使用 logback 或任何日志框架的任何此类应用程序,此问题应该很常见。@Karim 这不是 logback 的问题,而是 Linux 不允许您的应用程序写入该目录的问题,因此如果您不想更改对该目录的写入权限,请选择不同的一个 @Karim 如果我没有提供任何文件附加程序而不是部署工作,它会在同一目录中创建默认日志。所以它是特定于 logback 的。 您可以通过运行此命令ls -l /var/log/upstart 来验证权限并将结果添加到此处 【参考方案1】:

我终于找到了问题所在。尽管错误非常简单,但我还是需要重新审视一些事情。

service 是 ubuntu 上用户 'appuser'owned

日志指向的目录 (/var/log/upstart/) 不允许用户“appuser”使用。日志目录归用户“root”所有。因此,我创建了另一个目录 (/var/log/app/),该目录也属于同一用户,即“appuser”并启动了应用程序。

它解决了这个问题。

【讨论】:

以上是关于在带有 logback 配置的 Ubuntu 上部署 SpringBoot 失败并出现 FileNotFoundException (Permission Denied)的主要内容,如果未能解决你的问题,请参考以下文章

带有弹簧属性占位符的 Spring Boot 和 Logback logging.config 文件

如何使用SBT和Scala正确管理开发和生产中的logback配置?

二十SpringBoot2核心技术——整合logback

二十SpringBoot2核心技术——整合logback

Logback - C3P0 和 HSQLDB

带有 Logback 的 JOOQ