You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2017/06/23 04:51:33 UTC
logging-log4j2 git commit: [LOG4J2-1699] Configurable Log File
Permissions with PosixFilePermission. Apply patch.
Repository: logging-log4j2
Updated Branches:
refs/heads/master 5b2df230d -> 9d32793b1
[LOG4J2-1699] Configurable Log File Permissions with
PosixFilePermission. Apply patch.
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/9d32793b
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/9d32793b
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/9d32793b
Branch: refs/heads/master
Commit: 9d32793b12e2fe9b7a77519e59f5027942db4917
Parents: 5b2df23
Author: Pierrick HYMBERT <pi...@gmail.com>
Authored: Thu Jun 22 21:51:30 2017 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Jun 22 21:51:30 2017 -0700
----------------------------------------------------------------------
.../rolling/DefaultRolloverStrategy.java | 20 +-
.../rolling/DirectWriteRolloverStrategy.java | 20 +-
.../action/PosixViewAttributeAction.java | 216 ++++++++++++----
.../logging/log4j/core/util/FileUtils.java | 9 +
.../appender/FileAppenderPermissionsTest.java | 211 ++++++++++++++++
.../FileAppenderPermissionsXmlConfigTest.java | 66 +++++
.../core/appender/FilePermissionsTest.java | 244 -------------------
...lingAppenderSizeCompressPermissionsTest.java | 9 +-
8 files changed, 492 insertions(+), 303 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9d32793b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
index a91a453..4141195 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java
@@ -356,14 +356,18 @@ public class DefaultRolloverStrategy extends AbstractRolloverStrategy {
if (manager.isPosixSupported()) {
// Propagate posix attribute view to rolled/compressed file
- Action posixAttributeViewAction = new PosixViewAttributeAction(compressedName,
- false,
- 1,
- new PathCondition[0],
- getStrSubstitutor(),
- manager.getFilePermissions(),
- manager.getFileOwner(),
- manager.getFileGroup());
+ // @formatter:off
+ Action posixAttributeViewAction = PosixViewAttributeAction.newBuilder()
+ .withBasePath(compressedName)
+ .withFollowLinks(false)
+ .withMaxDepth(1)
+ .withPathConditions(new PathCondition[0])
+ .withSubst(getStrSubstitutor())
+ .withFilePermissions(manager.getFilePermissions())
+ .withFileOwner(manager.getFileOwner())
+ .withFileGroup(manager.getFileGroup())
+ .build();
+ // @formatter:on
if (compressAction == null) {
compressAction = posixAttributeViewAction;
} else {
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9d32793b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java
index feff516..6ce58d8 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DirectWriteRolloverStrategy.java
@@ -197,14 +197,18 @@ public class DirectWriteRolloverStrategy extends AbstractRolloverStrategy implem
if (manager.isPosixSupported()) {
// Propagate posix attribute view to rolled/compressed file
- Action posixAttributeViewAction = new PosixViewAttributeAction(compressedName,
- false,
- 1,
- new PathCondition[0],
- getStrSubstitutor(),
- manager.getFilePermissions(),
- manager.getFileOwner(),
- manager.getFileGroup());
+ // @formatter:off
+ Action posixAttributeViewAction = PosixViewAttributeAction.newBuilder()
+ .withBasePath(compressedName)
+ .withFollowLinks(false)
+ .withMaxDepth(1)
+ .withPathConditions(new PathCondition[0])
+ .withSubst(getStrSubstitutor())
+ .withFilePermissions(manager.getFilePermissions())
+ .withFileOwner(manager.getFileOwner())
+ .withFileGroup(manager.getFileGroup())
+ .build();
+ // @formatter:on
if (compressAction == null) {
compressAction = posixAttributeViewAction;
} else {
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9d32793b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PosixViewAttributeAction.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PosixViewAttributeAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PosixViewAttributeAction.java
index 7603e75..d74fcbd 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PosixViewAttributeAction.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PosixViewAttributeAction.java
@@ -32,15 +32,19 @@ import java.util.Set;
import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.Plugin;
-import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
-import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.apache.logging.log4j.core.util.FileUtils;
+import org.apache.logging.log4j.util.Strings;
/**
- * File posix attribute action.
+ * File posix attribute view action.
+ *
+ * Allow to define file permissions, user and group for log files on posix supported OS.
*/
@Plugin(name = "PosixViewAttribute", category = Core.CATEGORY_NAME, printObject = true)
public class PosixViewAttributeAction extends AbstractPathAction {
@@ -60,19 +64,7 @@ public class PosixViewAttributeAction extends AbstractPathAction {
*/
private final String fileGroup;
- /**
- * Constructor of the posix view attribute action.
- *
- * @param basePath {@link AbstractPathAction#getBasePath()}
- * @param followSymbolicLinks {@link AbstractPathAction#isFollowSymbolicLinks()}
- * @param pathConditions {@link AbstractPathAction#getPathConditions()}
- * @param subst {@link AbstractPathAction#getStrSubstitutor()}
- * @param filePermissions Permissions to apply
- * @param fileOwner File owner
- * @param fileGroup File group
- * @param followSymbolicLinks
- */
- public PosixViewAttributeAction(final String basePath, final boolean followSymbolicLinks,
+ private PosixViewAttributeAction(final String basePath, final boolean followSymbolicLinks,
final int maxDepth, final PathCondition[] pathConditions, final StrSubstitutor subst,
final Set<PosixFilePermission> filePermissions,
final String fileOwner, final String fileGroup) {
@@ -82,35 +74,177 @@ public class PosixViewAttributeAction extends AbstractPathAction {
this.fileGroup = fileGroup;
}
+ @PluginBuilderFactory
+ public static Builder newBuilder() {
+ return new Builder();
+ }
+
/**
- * Creates a PosixViewAttributeAction action that defined posix attribute view on a file.
- *
- * @param basePath {@link AbstractPathAction#getBasePath()}
- * @param followSymbolicLinks {@link AbstractPathAction#isFollowSymbolicLinks()}
- * @param pathConditions {@link AbstractPathAction#getPathConditions()}
- * @param subst {@link AbstractPathAction#getStrSubstitutor()}
- * @param filePermissions File permissions
- * @param fileOwner File owner
- * @param fileGroup File group
- * @return PosixViewAttribute action
+ * Builder for the posix view attribute action.
*/
- @PluginFactory
- public static PosixViewAttributeAction createNameCondition(
- // @formatter:off
- @PluginAttribute("basePath") final String basePath, //
- @PluginAttribute(value = "followLinks") final boolean followLinks,
- @PluginAttribute(value = "maxDepth", defaultInt = 1) final int maxDepth,
- @PluginElement("PathConditions") final PathCondition[] pathConditions,
- @PluginAttribute("filePermissions") final String filePermissions,
- @PluginAttribute("fileOwner") final String fileOwner,
- @PluginAttribute("fileGroup") final String fileGroup,
- @PluginConfiguration final Configuration config) {
- // @formatter:on
- return new PosixViewAttributeAction(basePath, followLinks, maxDepth,
- pathConditions, config.getStrSubstitutor(),
- filePermissions != null ? PosixFilePermissions.fromString(filePermissions) : null,
+ public static class Builder implements org.apache.logging.log4j.core.util.Builder<PosixViewAttributeAction> {
+
+ @PluginConfiguration
+ private Configuration configuration;
+
+ private StrSubstitutor subst;
+
+ @PluginBuilderAttribute
+ @Required(message = "No base path provided")
+ private String basePath;
+
+ @PluginBuilderAttribute
+ private boolean followLinks = false;
+
+ @PluginBuilderAttribute
+ private int maxDepth = 1;
+
+ @PluginElement("PathConditions")
+ private PathCondition[] pathConditions;
+
+ @PluginBuilderAttribute(value = "filePermissions")
+ private String filePermissionsString;
+
+ private Set<PosixFilePermission> filePermissions;
+
+ @PluginBuilderAttribute
+ private String fileOwner;
+
+ @PluginBuilderAttribute
+ private String fileGroup;
+
+ @Override
+ public PosixViewAttributeAction build() {
+ if (Strings.isEmpty(basePath)) {
+ LOGGER.error("Posix file attribute view action not valid because base path is empty.");
+ return null;
+ }
+
+ if (filePermissions == null && Strings.isEmpty(filePermissionsString)
+ && Strings.isEmpty(fileOwner) && Strings.isEmpty(fileGroup)) {
+ LOGGER.error("Posix file attribute view not valid because nor permissions, user and group defined.");
+ return null;
+ }
+
+ if (!FileUtils.isFilePosixAttributeViewSupported()) {
+ LOGGER.warn("Posix file attribute view defined but it is not supported by this file system.");
+// return null; // FIXME Should we avoid operations not permitted or unsupported exception ?
+ }
+
+ return new PosixViewAttributeAction(basePath, followLinks, maxDepth, pathConditions,
+ subst != null ? subst : configuration.getStrSubstitutor(),
+ filePermissions != null ? filePermissions :
+ filePermissionsString != null ? PosixFilePermissions.fromString(filePermissionsString) : null,
fileOwner,
fileGroup);
+ }
+
+ /**
+ * Define required configuration, used to retrieve string substituter.
+ *
+ * @param configuration {@link AbstractPathAction#getStrSubstitutor()}
+ * @return This builder
+ */
+ public Builder withConfiguration(Configuration configuration) {
+ this.configuration = configuration;
+ return this;
+ }
+
+ /**
+ * Define string substituter.
+ *
+ * @param subst {@link AbstractPathAction#getStrSubstitutor()}
+ * @return This builder
+ */
+ public Builder withSubst(StrSubstitutor subst) {
+ this.subst = subst;
+ return this;
+ }
+
+ /**
+ * Define base path to apply condition before execute posix file attribute action.
+ * @param basePath {@link AbstractPathAction#getBasePath()}
+ * @return This builder
+ */
+ public Builder withBasePath(String basePath) {
+ this.basePath = basePath;
+ return this;
+ }
+
+ /**
+ * True to allow synonyms links during search of eligible files.
+ * @param followLinks Follow synonyms links
+ * @return This builder
+ */
+ public Builder withFollowLinks(boolean followLinks) {
+ this.followLinks = followLinks;
+ return this;
+ }
+
+ /**
+ * Define max folder depth to search for eligible files to apply posix attribute view.
+ * @param maxDepth Max search depth
+ * @return This builder
+ */
+ public Builder withMaxDepth(int maxDepth) {
+ this.maxDepth = maxDepth;
+ return this;
+ }
+
+ /**
+ * Define path conditions to filter files in {@link PosixViewAttributeAction#getBasePath()}.
+ *
+ * @param pathConditions {@link AbstractPathAction#getPathConditions()}
+ * @return This builder
+ */
+ public Builder withPathConditions(PathCondition[] pathConditions) {
+ this.pathConditions = pathConditions;
+ return this;
+ }
+
+ /**
+ * Define file permissions in posix format to apply during action execution eligible files.
+ *
+ * Example:
+ * <p>rw-rw-rw
+ * <p>r--r--r--
+ * @param filePermissionsString Permissions to apply
+ * @return This builder
+ */
+ public Builder withFilePermissionsString(String filePermissionsString) {
+ this.filePermissionsString = filePermissionsString;
+ return this;
+ }
+
+ /**
+ * Define file permissions to apply during action execution eligible files.
+ * @param filePermissions Permissions to apply
+ * @return This builder
+ */
+ public Builder withFilePermissions(Set<PosixFilePermission> filePermissions) {
+ this.filePermissions = filePermissions;
+ return this;
+ }
+
+ /**
+ * Define file owner to apply during action execution eligible files.
+ * @param fileOwner File owner
+ * @return This builder
+ */
+ public Builder withFileOwner(String fileOwner) {
+ this.fileOwner = fileOwner;
+ return this;
+ }
+
+ /**
+ * Define file group to apply during action execution eligible files.
+ * @param fileGroup File group
+ * @return This builder
+ */
+ public Builder withFileGroup(String fileGroup) {
+ this.fileGroup = fileGroup;
+ return this;
+ }
}
@Override
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9d32793b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/FileUtils.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/FileUtils.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/FileUtils.java
index f82e738..c486d64 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/FileUtils.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/FileUtils.java
@@ -186,4 +186,13 @@ public final class FileUtils {
}
}
}
+
+ /**
+ * Check if posix file attribute view is supported on the default FileSystem.
+ *
+ * @return true if posix file attribute view supported, false otherwise
+ */
+ public static boolean isFilePosixAttributeViewSupported() {
+ return FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
+ }
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9d32793b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderPermissionsTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderPermissionsTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderPermissionsTest.java
new file mode 100644
index 0000000..ec12e00
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderPermissionsTest.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.appender;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.PosixFileAttributes;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.apache.logging.log4j.core.util.FileUtils;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/**
+ * Tests {@link FileAppender}.
+ */
+@RunWith(Parameterized.class)
+public class FileAppenderPermissionsTest {
+
+ private static final String DIR = "target/permissions1";
+
+ @Parameterized.Parameters(name = "{0} {1} {2}")
+ public static Collection<Object[]> data() throws IOException {
+ return Arrays.asList(new Object[][] { //
+ // @formatter:off
+ {"rwxrwxrwx", true, 2},
+ {"rw-r--r--", false, 3},
+ {"rw-------", true, 4},
+ {"rw-rw----", false, 5},
+ });
+ // @formatter:on
+ }
+
+ private final boolean createOnDemand;
+ private final String filePermissions;
+ private final int fileIndex;
+
+ public FileAppenderPermissionsTest(final String filePermissions, final boolean createOnDemand, final int fileIndex) {
+ this.filePermissions = filePermissions;
+ this.createOnDemand = createOnDemand;
+ this.fileIndex = fileIndex;
+ }
+
+ @BeforeClass
+ public static void beforeClass() {
+ Assume.assumeTrue(FileUtils.isFilePosixAttributeViewSupported());
+ }
+
+ @Test
+ public void testFilePermissionsAPI() throws Exception {
+ final File file = new File(DIR, "AppenderTest-" + fileIndex + ".log");
+ final Path path = file.toPath();
+ final Layout<String> layout = PatternLayout.newBuilder().withPattern(PatternLayout.SIMPLE_CONVERSION_PATTERN)
+ .build();
+ // @formatter:off
+ final FileAppender appender = FileAppender.newBuilder()
+ .withFileName(file.getAbsolutePath())
+ .withName("test")
+ .withImmediateFlush(false)
+ .withIgnoreExceptions(false)
+ .withBufferedIo(false)
+ .withBufferSize(1)
+ .withLayout(layout)
+ .withCreateOnDemand(createOnDemand)
+ .withFilePermissions(filePermissions)
+ .build();
+ // @formatter:on
+ try {
+ appender.start();
+ assertTrue("Appender did not start", appender.isStarted());
+ Assert.assertNotEquals(createOnDemand, Files.exists(path));
+ long curLen = file.length();
+ long prevLen = curLen;
+ assertTrue("File length: " + curLen, curLen == 0);
+ for (int i = 0; i < 100; ++i) {
+ final LogEvent event = Log4jLogEvent.newBuilder().setLoggerName("TestLogger") //
+ .setLoggerFqcn(FileAppenderPermissionsTest.class.getName()).setLevel(Level.INFO) //
+ .setMessage(new SimpleMessage("Test")).setThreadName(this.getClass().getSimpleName()) //
+ .setTimeMillis(System.currentTimeMillis()).build();
+ try {
+ appender.append(event);
+ curLen = file.length();
+ assertTrue("File length: " + curLen, curLen > prevLen);
+ // Give up control long enough for another thread/process to occasionally do something.
+ Thread.sleep(25);
+ } catch (final Exception ex) {
+ throw ex;
+ }
+ prevLen = curLen;
+ }
+ assertEquals(filePermissions, PosixFilePermissions.toString(Files.getPosixFilePermissions(path)));
+ } finally {
+ appender.stop();
+ }
+ assertFalse("Appender did not stop", appender.isStarted());
+ }
+
+ @Test
+ public void testFileUserGroupAPI() throws Exception {
+ final File file = new File(DIR, "AppenderTest-" + (1000 + fileIndex) + ".log");
+ final Path path = file.toPath();
+ String user = findAUser();
+ assertNotNull(user);
+ String group = findAGroup(user);
+ assertNotNull(group);
+
+ final Layout<String> layout = PatternLayout.newBuilder().withPattern(PatternLayout.SIMPLE_CONVERSION_PATTERN)
+ .build();
+ // @formatter:off
+ final FileAppender appender = FileAppender.newBuilder()
+ .withFileName(file.getAbsolutePath())
+ .withName("test")
+ .withImmediateFlush(true)
+ .withIgnoreExceptions(false)
+ .withBufferedIo(false)
+ .withBufferSize(1)
+ .withLayout(layout)
+ .withFilePermissions(filePermissions)
+ .withFileOwner(user)
+ .withFileGroup(group)
+ .build();
+ // @formatter:on
+ try {
+ appender.start();
+ assertTrue("Appender did not start", appender.isStarted());
+ long curLen = file.length();
+ long prevLen = curLen;
+ assertTrue(file + " File length: " + curLen, curLen == 0);
+ for (int i = 0; i < 100; ++i) {
+ final LogEvent event = Log4jLogEvent.newBuilder().setLoggerName("TestLogger") //
+ .setLoggerFqcn(FileAppenderPermissionsTest.class.getName()).setLevel(Level.INFO) //
+ .setMessage(new SimpleMessage("Test")).setThreadName(this.getClass().getSimpleName()) //
+ .setTimeMillis(System.currentTimeMillis()).build();
+ try {
+ appender.append(event);
+ curLen = file.length();
+ assertTrue("File length: " + curLen, curLen > prevLen);
+ // Give up control long enough for another thread/process to occasionally do something.
+ Thread.sleep(25);
+ } catch (final Exception ex) {
+ throw ex;
+ }
+ prevLen = curLen;
+ }
+ assertEquals(filePermissions, PosixFilePermissions.toString(Files.getPosixFilePermissions(path)));
+ assertEquals(user, Files.getOwner(path).getName());
+ assertEquals(group, Files.readAttributes(path, PosixFileAttributes.class).group().getName());
+ } finally {
+ appender.stop();
+ }
+ assertFalse("Appender did not stop", appender.isStarted());
+ }
+
+ public static String findAGroup(String user) throws IOException {
+ String group = user;
+ try (FileInputStream fis = new FileInputStream("/etc/group")) {
+ List<String> groups = org.apache.commons.io.IOUtils.readLines(fis, Charset.defaultCharset());
+ for (int i = 0; i < groups.size(); i++) {
+ String aGroup = groups.get(i);
+ if (!aGroup.startsWith(user) && aGroup.contains(user)) {
+ group = aGroup.split(":")[0];
+ break;
+ }
+ }
+ }
+ return group;
+ }
+
+ private static String findAUser() throws IOException {
+ // On jenkins build within ubuntu, it is not possible to chmod to another user
+ return System.getProperty("user.name");
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9d32793b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderPermissionsXmlConfigTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderPermissionsXmlConfigTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderPermissionsXmlConfigTest.java
new file mode 100644
index 0000000..941e785
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderPermissionsXmlConfigTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender;
+
+import static org.junit.Assert.assertEquals;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.attribute.PosixFilePermissions;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.util.FileUtils;
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+
+/**
+ * Tests {@link FileAppender}.
+ */
+public class FileAppenderPermissionsXmlConfigTest {
+
+ private static final String DIR = "target/permissions1";
+
+ private static final String CONFIG = "log4j-posix.xml";
+
+ public static LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG);
+
+ @Rule
+ public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR);
+
+ @BeforeClass
+ public static void beforeClass() {
+ Assume.assumeTrue(FileUtils.isFilePosixAttributeViewSupported());
+ }
+
+ @Test
+ public void testFilePermissions() throws Exception {
+ Logger logger = loggerContextRule.getLogger(FileAppenderPermissionsTest.class);
+ for (int i = 0; i < 1000; ++i) {
+ String message = "This is test message number " + i;
+ logger.debug(message);
+ }
+ assertEquals("rw-------", PosixFilePermissions.toString(
+ Files.getPosixFilePermissions(Paths.get("target/permissions1/AppenderTest-1.log"))));
+ }
+
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9d32793b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FilePermissionsTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FilePermissionsTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FilePermissionsTest.java
deleted file mode 100644
index 40c4e7b..0000000
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FilePermissionsTest.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.core.appender;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.attribute.PosixFileAttributes;
-import java.nio.file.attribute.PosixFilePermissions;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.Layout;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.core.layout.PatternLayout;
-import org.apache.logging.log4j.junit.LoggerContextRule;
-import org.apache.logging.log4j.message.SimpleMessage;
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.RuleChain;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-/**
- * Tests {@link FileAppender}.
- */
-public class FilePermissionsTest {
-
- private static final String DIR = "target/permissions1";
-
- @RunWith(Parameterized.class)
- public static final class TestParameterized {
-
- @Parameterized.Parameters(name = "{0} {1} {2}")
- public static Collection<Object[]> data() throws IOException {
- return Arrays.asList(new Object[][] { //
- // @formatter:off
- {"rwxrwxrwx", true, 2},
- {"rw-r--r--", false, 3},
- {"rw-------", true, 4},
- {"rw-rw----", false, 5},
- });
- // @formatter:on
- }
-
- private final boolean createOnDemand;
- private final String filePermissions;
- private final int fileIndex;
-
- public TestParameterized(final String filePermissions, final boolean createOnDemand, final int fileIndex) {
- this.filePermissions = filePermissions;
- this.createOnDemand = createOnDemand;
- this.fileIndex = fileIndex;
- }
-
- @BeforeClass
- public static void beforeClass() {
- Assume.assumeTrue(FileSystems.getDefault().supportedFileAttributeViews().contains("posix"));
- }
-
- @Test
- public void testFilePermissionsAPI() throws Exception {
- final File file = new File(DIR, "AppenderTest-" + fileIndex + ".log");
- final Path path = file.toPath();
- final Layout<String> layout = PatternLayout.newBuilder().withPattern(PatternLayout.SIMPLE_CONVERSION_PATTERN)
- .build();
- // @formatter:off
- final FileAppender appender = FileAppender.newBuilder()
- .withFileName(file.getAbsolutePath())
- .withName("test")
- .withImmediateFlush(false)
- .withIgnoreExceptions(false)
- .withBufferedIo(false)
- .withBufferSize(1)
- .withLayout(layout)
- .withCreateOnDemand(createOnDemand)
- .withFilePermissions(filePermissions)
- .build();
- // @formatter:on
- try {
- appender.start();
- assertTrue("Appender did not start", appender.isStarted());
- Assert.assertNotEquals(createOnDemand, Files.exists(path));
- long curLen = file.length();
- long prevLen = curLen;
- assertTrue("File length: " + curLen, curLen == 0);
- for (int i = 0; i < 100; ++i) {
- final LogEvent event = Log4jLogEvent.newBuilder().setLoggerName("TestLogger") //
- .setLoggerFqcn(FilePermissionsTest.class.getName()).setLevel(Level.INFO) //
- .setMessage(new SimpleMessage("Test")).setThreadName(this.getClass().getSimpleName()) //
- .setTimeMillis(System.currentTimeMillis()).build();
- try {
- appender.append(event);
- curLen = file.length();
- assertTrue("File length: " + curLen, curLen > prevLen);
- // Give up control long enough for another thread/process to occasionally do something.
- Thread.sleep(25);
- } catch (final Exception ex) {
- throw ex;
- }
- prevLen = curLen;
- }
- assertEquals(filePermissions, PosixFilePermissions.toString(Files.getPosixFilePermissions(path)));
- } finally {
- appender.stop();
- }
- assertFalse("Appender did not stop", appender.isStarted());
- }
-
- }
-
- public static class TestNotParameterized {
- private static final String CONFIG = "log4j-posix.xml";
-
- public static LoggerContextRule loggerContextRule = LoggerContextRule.createShutdownTimeoutLoggerContextRule(CONFIG);
-
- @Rule
- public RuleChain chain = loggerContextRule.withCleanFoldersRule(DIR);
-
- @BeforeClass
- public static void beforeClass() {
- Assume.assumeTrue(FileSystems.getDefault().supportedFileAttributeViews().contains("posix"));
- }
-
- @Test
- public void testFilePermissions() throws Exception {
- Logger logger = loggerContextRule.getLogger(FilePermissionsTest.class);
- for (int i = 0; i < 1000; ++i) {
- String message = "This is test message number " + i;
- logger.debug(message);
- }
- assertEquals("rw-------", PosixFilePermissions.toString(
- Files.getPosixFilePermissions(Paths.get("target/permissions1/AppenderTest-1.log"))));
- }
-
- @Test
- public void testFileUserGroupAPI() throws Exception {
- final File file = new File(DIR, "AppenderTest-0.log");
- final Path path = file.toPath();
- String user = findAUser();
- assertNotNull(user);
- String group = findAGroup(user);
- assertNotNull(group);
- String filePermissions = "rw-rw-rw-";
-
- final Layout<String> layout = PatternLayout.newBuilder().withPattern(PatternLayout.SIMPLE_CONVERSION_PATTERN)
- .build();
- // @formatter:off
- final FileAppender appender = FileAppender.newBuilder()
- .withFileName(file.getAbsolutePath())
- .withName("test")
- .withImmediateFlush(true)
- .withIgnoreExceptions(false)
- .withBufferedIo(false)
- .withBufferSize(1)
- .withLayout(layout)
- .withFilePermissions(filePermissions)
- .withFileOwner(user)
- .withFileGroup(group)
- .build();
- // @formatter:on
- try {
- appender.start();
- assertTrue("Appender did not start", appender.isStarted());
- long curLen = file.length();
- long prevLen = curLen;
- assertTrue("File length: " + curLen, curLen == 0);
- for (int i = 0; i < 100; ++i) {
- final LogEvent event = Log4jLogEvent.newBuilder().setLoggerName("TestLogger") //
- .setLoggerFqcn(FilePermissionsTest.class.getName()).setLevel(Level.INFO) //
- .setMessage(new SimpleMessage("Test")).setThreadName(this.getClass().getSimpleName()) //
- .setTimeMillis(System.currentTimeMillis()).build();
- try {
- appender.append(event);
- curLen = file.length();
- assertTrue("File length: " + curLen, curLen > prevLen);
- // Give up control long enough for another thread/process to occasionally do something.
- Thread.sleep(25);
- } catch (final Exception ex) {
- throw ex;
- }
- prevLen = curLen;
- }
- assertEquals(filePermissions, PosixFilePermissions.toString(Files.getPosixFilePermissions(path)));
- assertEquals(user, Files.getOwner(path).getName());
- assertEquals(group, Files.readAttributes(path, PosixFileAttributes.class).group().getName());
- } finally {
- appender.stop();
- }
- assertFalse("Appender did not stop", appender.isStarted());
- }
-
- public static String findAGroup(String user) throws IOException {
- String group = null;
- try (FileInputStream fis = new FileInputStream("/etc/group")) {
- List<String> groups = org.apache.commons.io.IOUtils.readLines(fis, Charset.defaultCharset());
- for (int i = 0; i < groups.size(); i++) {
- String aGroup = groups.get(i);
- if (!aGroup.startsWith(user) && aGroup.contains(user)) {
- group = aGroup.split(":")[0];
- break;
- }
- }
- }
- return group;
- }
-
- private static String findAUser() throws IOException {
- // On jenkins build within ubuntu, it is not possible to chmod to another user
- return System.getProperty("user.name");
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9d32793b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java
index c57705b..0ea11f7 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java
@@ -19,15 +19,16 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
-import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.util.FileUtils;
import org.apache.logging.log4j.junit.LoggerContextRule;
import org.junit.Assume;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
@@ -49,6 +50,11 @@ public class RollingAppenderSizeCompressPermissionsTest {
private Logger logger;
+ @BeforeClass
+ public static void beforeClass() {
+ Assume.assumeTrue(FileUtils.isFilePosixAttributeViewSupported());
+ }
+
@Before
public void setUp() throws Exception {
this.logger = loggerContextRule.getLogger(RollingAppenderSizeCompressPermissionsTest.class.getName());
@@ -56,7 +62,6 @@ public class RollingAppenderSizeCompressPermissionsTest {
@Test
public void testAppenderCompressPermissions() throws Exception {
- Assume.assumeTrue(FileSystems.getDefault().supportedFileAttributeViews().contains("posix"));
for (int i = 0; i < 500; ++i) {
String message = "This is test message number " + i;
logger.debug(message);