24

How are the permissions for files created by RollingFileAppender determined?

I recently changed a daemon process I have to be run as a non-root user and the files are now being created with permissions of 0600 (only readable by the owner), but I would like them to be readable by all or at least members of an admin group (0644 or 0640). Files created by my tomcat apps are always 0644 (readable by all).

I don't know if I inadvertently changed something else or if it is something to do with permissions of that user. I made the parent directory 0777 as a test and it didn't seem to help (it was 0755). Obviously not a big deal since I can sudo to look at them, but rather annoying and it will be a problem if I have to have a customer copy them for me.

Environment is Ubuntu 10.04LTS using jsvc/commons-daemon to run the daemon. In case it matters here is the basics on my log4j config:

<!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 %d{ISO8601} [%t][%x] %c - %m%n" />
        <!--%d{dd-MMM-yyyy HH:mm:ss.SSS} [%5p] %c{2}.%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 %d{ISO8601} [%t][%x] %c - %m%n" />
        <!--%d{dd-MMM-yyyy HH:mm:ss.SSS} [%5p] %c{2}.%M [line:%L]: %m%n-->
    </layout>
</appender>
....
ADTC
  • 8,999
  • 5
  • 68
  • 93
Ken Waln
  • 388
  • 1
  • 2
  • 10
  • I realize this is a very old question, but there is a [Jira issue](https://issues.apache.org/jira/browse/LOG4J2-1699) scheduled to be fixed in 2.8.1 that would enable setting these permissions explicitly. – Jeff G Feb 09 '17 at 21:05
  • Numerical permissions are more clearly expressed as positional r w x characters, as suggested by your parenthetical notes. The "symbolic mode" of chmod supports these too. – Arthur Jul 07 '22 at 21:20

4 Answers4

22

File permissions are determined by the user's umask - there's not a way to change it in log4j itself.

You probably want to set the user's umask to 0117

$ umask -S 0117
u=rw,g=rw,o=
Brian Roach
  • 76,169
  • 12
  • 136
  • 161
  • 1
    Thanks -- I completely forgot about the umask. Turns out, now that I know what to google for, that jsvc hard codes the umask so I may have to live with it (or recomplie jsvc) -- https://issues.apache.org/jira/browse/DAEMON-178. – Ken Waln Oct 25 '11 at 19:42
  • 1
    This answer is no longer accurate. Log4j 2.9.0 added a way to configure this without changing the umask setting. – Jeff G Dec 04 '17 at 22:31
12

Log4J-core-2.9 will provide this feature fileOwner, fileGroup and filePermissions for posix OS in FileAppender, RollingFileAppender and RollingRandomAccessFileManager:

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

I realize this is an old question, but since it was the first hit still when I searched for this problem...

You can simply subclass RollingFileAppender and set the permission on the file when it is first opened, like this:

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));
        }
    }
}

Then just reference WorldWritableFileAppender instead of RollingFileAppender in your log4j.xml.

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

This works because setFile() is called both when originally setting up the logger, and when creating a new file after rollover. The old file is moved aside with File.renameTo(), which preserves the permissions.

Russell Zahniser
  • 16,188
  • 39
  • 30
2

inside log4j.properties include this: log4j.appender.file.File=${user.home}/log anyway, this is my configuration that show info in console and file "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=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%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=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
Pichitron
  • 159
  • 5