log4j RollingFileAppender 创建的日志文件的权限

Posted

技术标签:

【中文标题】log4j RollingFileAppender 创建的日志文件的权限【英文标题】:Permissions on log files created by log4j RollingFileAppender 【发布时间】:2011-12-15 03:55:14 【问题描述】:

RollingFileAppender创建的文件的权限是如何确定的?

我最近更改了一个守护进程,我必须以非 root 用户身份运行,现在正在使用 0600 的权限创建文件(只有所有者可读),但我希望它们可以被管理员组的所有或至少成员(06440640)。我的 tomcat 应用程序创建的文件始终为0644(所有人都可读)。

我不知道我是否无意中更改了其他内容,或者是否与该用户的权限有关。我将父目录0777 作为测试,它似乎没有帮助(它是0755)。显然没什么大不了的,因为我可以sudo 来查看它们,但很烦人,如果我必须让客户为我复制它们,那将是一个问题。

环境是 Ubuntu 10.04LTS,使用jsvc/commons-daemon 运行守护进程。万一这很重要,我的 log4j 配置中的基础知识:

<!DOCTYPE log4j:configuration SYSTEM 'log4j.dtd'>
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">

<appender name="StdOutAppender" class="org.apache.log4j.ConsoleAppender">
    <!-- only send error / fatal messages to console (catalina.out) -->
    <param name="threshold" value="$log4j.StdOutAppender.threshold" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%5p %dISO8601 [%t][%x] %c - %m%n" />
        <!--%ddd-MMM-yyyy HH:mm:ss.SSS [%5p] %c2.%M [line:%L]: %m%n-->
    </layout>
</appender>

<appender name="TimeBasedRollingFileAppender" class="org.apache.log4j.rolling.RollingFileAppender">
    <param name="append" value="true" />
    <param name="encoding" value="UTF-8" />
    <param name="threshold" value="$log4j.TimeBasedRollingFileAppender.threshold" />
    <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
        <param name="FileNamePattern" value="$cloud.daemon.log4j.file.config.path.%d.gz" />
    </rollingPolicy>
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%5p %dISO8601 [%t][%x] %c - %m%n" />
        <!--%ddd-MMM-yyyy HH:mm:ss.SSS [%5p] %c2.%M [line:%L]: %m%n-->
    </layout>
</appender>
....

【问题讨论】:

我意识到这是一个非常古老的问题,但有一个Jira issue 计划在 2.8.1 中修复,可以显式设置这些权限。 【参考方案1】:

文件权限由用户的 umask 决定 - log4j 本身无法更改它。

您可能希望将用户的 umask 设置为 0117

$ umask -S 0117
u=rw,g=rw,o=

【讨论】:

谢谢——我完全忘记了 umask。事实证明,既然我知道谷歌要做什么,jsvc 对 umask 进行了硬编码,所以我可能不得不忍受它(或重新编译 jsvc)——issues.apache.org/jira/browse/DAEMON-178。 这个答案不再准确。 Log4j 2.9.0 添加了一种在不更改 umask 设置的情况下进行配置的方法。【参考方案2】:

在 log4j.properties 中包括:log4j.appender.file.File=$user.home/log 无论如何,这是我在控制台和文件“日志”中显示信息的配置。

# Root logger option
log4j.rootLogger=DEBUG, stdout, file

# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%dyyyy-MM-dd HH:mm:ss %-5p %c1:%L - %m%n

# Redirect log messages to a log file, support file rolling.
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=$user.home/test
log4j.appender.file.MaxFileSize=5MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%dyyyy-MM-dd HH:mm:ss %-5p %c1:%L - %m%n

【讨论】:

【参考方案3】:

我意识到这是一个老问题,但是当我搜索这个问题时,它仍然是第一个命中......

您可以简单地继承RollingFileAppender 并在文件首次打开时设置文件的权限,如下所示:

public class WorldWritableFileAppender extends RollingFileAppender 
    @Override
    public synchronized void setFile(String fileName, boolean append,
            boolean bufferedIO, int bufferSize) throws IOException 
        super.setFile(fileName, append, bufferedIO, bufferSize);
        File f = new File(fileName);
        if(f.exists()) 
            java.nio.file.Files.setPosixFilePermissions(f.toPath(), 
                    EnumSet.allOf(PosixFilePermission.class));
        
    

然后只需在您的log4j.xml 中引用WorldWritableFileAppender 而不是RollingFileAppender

<appender name="name" class="path.to.WorldWritableFileAppender">

这是因为setFile() 在最初设置记录器时以及在翻转后创建新文件时都会被调用。旧文件用File.renameTo() 移到一边,保留权限。

【讨论】:

这在锁定到 LOG4j v1 时非常有用。【参考方案4】:

Log4J-core-2.9 将为 FileAppender 中的 posix OS 提供此 feature fileOwnerfileGroupfilePermissions em>、RollingFileAppenderRollingRandomAccessFileManager

<RollingFile name="RollingFile"
             fileName="mylogs.log"
             filePattern="mylogs-$$date:MM-dd-yyyy-%i.log.7z"
             fileOwner="log4j"
             fileGroup="log4grp"
             filePermissions="rw-r-----">

【讨论】:

如何为 logback 做到这一点?

以上是关于log4j RollingFileAppender 创建的日志文件的权限的主要内容,如果未能解决你的问题,请参考以下文章

日志技术-Log4j

Log4j输出终端(Appender)详解

ES Log4J配置信息

log4j 异步日志问题分析

log4j删除N天前日志实现

JAVA日志框架log4j和slf4j