diff --git a/log4j-compress/.log4j-plugin-processing-activator b/log4j-compress/.log4j-plugin-processing-activator new file mode 100644 index 00000000000..ba133f36961 --- /dev/null +++ b/log4j-compress/.log4j-plugin-processing-activator @@ -0,0 +1 @@ +This file is here to activate the `plugin-processing` Maven profile. diff --git a/log4j-compress/pom.xml b/log4j-compress/pom.xml new file mode 100644 index 00000000000..9aac4b63a0c --- /dev/null +++ b/log4j-compress/pom.xml @@ -0,0 +1,177 @@ + + + + 4.0.0 + + org.apache.logging.log4j + log4j + ${revision} + ../log4j-parent + + + log4j-compress + Apache Log4j Core: Extended Compression Support + Add additional compression formats to Log4j Core. + + + 1.27.1 + 1.3.0 + 1.10 + 1.5.6-5 + + + + + + + + org.tukaani + xz + ${xz.version} + + + + + com.github.luben + zstd-jni + ${zstd.version} + + + + + + + + + org.apache.commons + commons-compress + ${commons-compress.version} + + + + org.apache.logging.log4j + log4j-api + + + + org.apache.logging.log4j + log4j-core + + + + org.apache.logging.log4j + log4j-plugins + + + + org.assertj + assertj-core + test + + + + org.junit.jupiter + junit-jupiter-api + test + + + + org.junit.jupiter + junit-jupiter-params + test + + + + com.google.jimfs + jimfs + ${jimfs.version} + test + + + + org.apache.logging.log4j + log4j-api-test + test + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + default-test + + + org/apache/logging/log4j/compress/commons/xz/* + org/apache/logging/log4j/compress/commons/zstd/* + + + + + + test-xz + + test + + + + + org.tukaani + xz + ${xz.version} + + + + org/apache/logging/log4j/compress/commons/xz/*Test.class + + + + + + test-zstd + + test + + + + + com.github.luben + zstd-jni + ${zstd.version} + + + + org/apache/logging/log4j/compress/commons/zstd/*Test.class + + + + + + + + + diff --git a/log4j-compress/src/main/java/org/apache/logging/log4j/compress/commons/CommonsCompressAction.java b/log4j-compress/src/main/java/org/apache/logging/log4j/compress/commons/CommonsCompressAction.java new file mode 100644 index 00000000000..d0e3ec47000 --- /dev/null +++ b/log4j-compress/src/main/java/org/apache/logging/log4j/compress/commons/CommonsCompressAction.java @@ -0,0 +1,68 @@ +/* + * 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.compress.commons; + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Path; +import java.util.Objects; +import org.apache.commons.compress.compressors.CompressorException; +import org.apache.commons.compress.compressors.CompressorStreamProvider; +import org.apache.logging.log4j.core.appender.rolling.action.AbstractCompressAction; + +/** + * Compresses a file using bzip2 compression. + */ +final class CommonsCompressAction extends AbstractCompressAction { + + private final CompressorStreamProvider provider; + + /** + * Compressor name. One of "gz", "bzip2", "xz", "pack200" or "deflate". + */ + private final String name; + + /** + * Creates new instance of Bzip2CompressAction. + * + * @param name The compressor name. One of "gz", "bzip2", "xz", "pack200", or "deflate". + * @param source The file to compress, may not be null. + * @param destination The compressed file, may not be null. + */ + CommonsCompressAction( + final CompressorStreamProvider provider, final String name, final Path source, final Path destination) { + super(source, destination); + this.provider = Objects.requireNonNull(provider); + this.name = Objects.requireNonNull(name, "name"); + } + + @Override + protected OutputStream wrapOutputStream(OutputStream stream) throws IOException { + try { + return new BufferedOutputStream(provider.createCompressorOutputStream(name, stream), BUF_SIZE); + } catch (final CompressorException error) { + final String message = String.format("failed to wrap the output stream with the `%s` compressor", name); + throw new IOException(message, error); + } + } + + @Override + protected String getAlgorithmName() { + return name; + } +} diff --git a/log4j-compress/src/main/java/org/apache/logging/log4j/compress/commons/CommonsCompressActionFactory.java b/log4j-compress/src/main/java/org/apache/logging/log4j/compress/commons/CommonsCompressActionFactory.java new file mode 100644 index 00000000000..761c93a6006 --- /dev/null +++ b/log4j-compress/src/main/java/org/apache/logging/log4j/compress/commons/CommonsCompressActionFactory.java @@ -0,0 +1,47 @@ +/* + * 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.compress.commons; + +import java.nio.file.Path; +import java.util.Map; +import org.apache.commons.compress.compressors.CompressorStreamProvider; +import org.apache.logging.log4j.core.appender.rolling.action.Action; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactory; +import org.jspecify.annotations.NullMarked; + +@NullMarked +final class CommonsCompressActionFactory implements CompressActionFactory { + + private final CompressorStreamProvider provider; + + private final String name; + + CommonsCompressActionFactory(final String name, final CompressorStreamProvider provider) { + this.name = name; + this.provider = provider; + } + + @Override + public Action createCompressAction(final Path source, final Path destination, final Map ignored) { + return new CommonsCompressAction(provider, name, source, destination); + } + + @Override + public String getAlgorithmName() { + return name; + } +} diff --git a/log4j-compress/src/main/java/org/apache/logging/log4j/compress/commons/CommonsCompressActionFactoryProvider.java b/log4j-compress/src/main/java/org/apache/logging/log4j/compress/commons/CommonsCompressActionFactoryProvider.java new file mode 100644 index 00000000000..8dc39fe8716 --- /dev/null +++ b/log4j-compress/src/main/java/org/apache/logging/log4j/compress/commons/CommonsCompressActionFactoryProvider.java @@ -0,0 +1,91 @@ +/* + * 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.compress.commons; + +import static org.apache.logging.log4j.util.Strings.toRootLowerCase; +import static org.apache.logging.log4j.util.Strings.toRootUpperCase; + +import org.apache.commons.compress.compressors.CompressorStreamFactory; +import org.apache.commons.compress.compressors.CompressorStreamProvider; +import org.apache.commons.compress.compressors.lzma.LZMAUtils; +import org.apache.commons.compress.compressors.xz.XZUtils; +import org.apache.commons.compress.compressors.zstandard.ZstdUtils; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactory; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactoryProvider; +import org.apache.logging.log4j.plugins.Namespace; +import org.apache.logging.log4j.plugins.Ordered; +import org.apache.logging.log4j.plugins.Plugin; +import org.apache.logging.log4j.status.StatusLogger; +import org.jspecify.annotations.Nullable; + +@Plugin +@Namespace(CompressActionFactoryProvider.NAMESPACE) +@Ordered(0) +public final class CommonsCompressActionFactoryProvider implements CompressActionFactoryProvider { + + private static final Logger LOGGER = StatusLogger.getLogger(); + private static final String COMMONS_COMPRESS_DOCUMENTATION = + "See https://commons.apache.org/proper/commons-compress/index.html for more information."; + + private final CompressorStreamFactory factory = new CompressorStreamFactory(); + + private static void missingDependencyWarning(final String algorithm) { + LOGGER.warn( + "{} compression is not available due to a missing dependency. {}", + algorithm, + COMMONS_COMPRESS_DOCUMENTATION); + } + + private @Nullable CompressorStreamProvider getCompressorStreamProvider(String algorithm) { + switch (toRootLowerCase(algorithm)) { + case CompressorStreamFactory.LZMA: + if (!LZMAUtils.isLZMACompressionAvailable()) { + missingDependencyWarning("LZMA"); + return null; + } + break; + case CompressorStreamFactory.PACK200: + LOGGER.warn("Pack200 compression is not suitable for log files and will not be used."); + return null; + case CompressorStreamFactory.XZ: + if (!XZUtils.isXZCompressionAvailable()) { + missingDependencyWarning("XZ"); + return null; + } + break; + case CompressorStreamFactory.ZSTANDARD: + if (!ZstdUtils.isZstdCompressionAvailable()) { + missingDependencyWarning("Zstd"); + return null; + } + break; + } + // Commons Compress uses upper case keys. + return CompressorStreamFactory.findAvailableCompressorOutputStreamProviders() + .get(toRootUpperCase(algorithm)); + } + + @Override + public @Nullable CompressActionFactory createFactoryForAlgorithm(String algorithm) { + CompressorStreamProvider provider = getCompressorStreamProvider(algorithm); + if (provider != null) { + return new CommonsCompressActionFactory(algorithm, provider); + } + return null; + } +} diff --git a/log4j-compress/src/main/java/org/apache/logging/log4j/compress/commons/package-info.java b/log4j-compress/src/main/java/org/apache/logging/log4j/compress/commons/package-info.java new file mode 100644 index 00000000000..f37a194f328 --- /dev/null +++ b/log4j-compress/src/main/java/org/apache/logging/log4j/compress/commons/package-info.java @@ -0,0 +1,22 @@ +/* + * 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. + */ +@Export +@Version("3.0.0") +package org.apache.logging.log4j.compress.commons; + +import org.osgi.annotation.bundle.Export; +import org.osgi.annotation.versioning.Version; diff --git a/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/AbstractCompressActionTest.java b/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/AbstractCompressActionTest.java new file mode 100644 index 00000000000..3dc280ddf7c --- /dev/null +++ b/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/AbstractCompressActionTest.java @@ -0,0 +1,120 @@ +/* + * 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.compress.commons; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; + +import com.google.common.jimfs.Jimfs; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import org.apache.commons.compress.compressors.CompressorException; +import org.apache.commons.compress.compressors.CompressorStreamFactory; +import org.apache.commons.compress.compressors.CompressorStreamProvider; +import org.apache.logging.log4j.core.appender.rolling.action.Action; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactory; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactoryProvider; +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.config.NullConfiguration; + +/** + * Reusable tests to test compression actions. + */ +public abstract class AbstractCompressActionTest { + + private static final FileSystem FILE_SYSTEM = Jimfs.newFileSystem(com.google.common.jimfs.Configuration.unix()); + protected static final Path ROOT = FILE_SYSTEM.getPath("/"); + private static final Configuration CONFIGURATION = new NullConfiguration(); + protected static final CompressActionFactoryProvider PROVIDER = + CompressActionFactoryProvider.newInstance(CONFIGURATION); + + private static final CompressorStreamProvider COMPRESSOR_STREAM_PROVIDER = new CompressorStreamFactory(); + + public static final String LINE_1 = "Here is line 1. Random text: ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + public static final String LINE_2 = "Here is line 2. Random text: ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + public static final String LINE_3 = "Here is line 3. Random text: ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + /** + * Verifies that compression succeeds using {@code Path} parameters. + */ + protected static void verifyCompressionUsingPathParams(String algorithm, Map compressionOptions) + throws Exception { + Path tempDirectory = Files.createTempDirectory(ROOT, "test-compress"); + Path source = tempDirectory.resolve("source"); + Path destination = tempDirectory.resolve("destination"); + + writeTestData(source); + CompressActionFactory factory = PROVIDER.createFactoryForAlgorithm(algorithm); + assertThat(factory).isNotNull(); + Action action = factory.createCompressAction(source, destination, compressionOptions); + assertThat(action).isInstanceOf(CommonsCompressAction.class); + assertThat(action.execute()).as("Compression succeeds.").isTrue(); + verifiedCompressedData(destination, algorithm); + } + + /** + * Verifies that compression succeeds using {@code String} parameters. + *

+ * If @code source} and {@code destination} are not on the default file system, we need to make sure + * that {@link java.nio.file.Paths#get(URI)} is called instead of the + * {@link java.nio.file.Paths#get(String, String...)} variant. + *

+ */ + protected static void verifyCompressionUsingStringParams(String algorithm, Map compressionOptions) + throws Exception { + Path tempDirectory = Files.createTempDirectory(ROOT, "test-compress"); + Path source = tempDirectory.resolve("source"); + Path destination = tempDirectory.resolve("destination"); + + writeTestData(source); + CompressActionFactory factory = PROVIDER.createFactoryForAlgorithm(algorithm); + assertThat(factory).isNotNull(); + Action action = factory.createCompressAction( + source.toUri().toString(), destination.toUri().toString(), compressionOptions); + assertThat(action).isInstanceOf(CommonsCompressAction.class); + assertThat(action.execute()).as("Compression succeeds.").isTrue(); + verifiedCompressedData(destination, algorithm); + } + + private static void writeTestData(final Path destination) throws IOException { + try (final BufferedWriter writer = Files.newBufferedWriter(destination, UTF_8)) { + writer.write(LINE_1); + writer.write(System.lineSeparator()); + writer.write(LINE_2); + writer.write(System.lineSeparator()); + writer.write(LINE_3); + } + } + + private static void verifiedCompressedData(final Path source, final String algorithm) + throws IOException, CompressorException { + try (final InputStream fileInput = Files.newInputStream(source); + final InputStream uncompressedInput = + COMPRESSOR_STREAM_PROVIDER.createCompressorInputStream(algorithm, fileInput, true); + final BufferedReader reader = new BufferedReader(new InputStreamReader(uncompressedInput, UTF_8))) { + assertThat(reader.lines()).containsExactly(LINE_1, LINE_2, LINE_3); + } + } +} diff --git a/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/CommonsCompressActionTest.java b/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/CommonsCompressActionTest.java new file mode 100644 index 00000000000..ea8c7c549fe --- /dev/null +++ b/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/CommonsCompressActionTest.java @@ -0,0 +1,116 @@ +/* + * 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.compress.commons; + +import static org.apache.commons.compress.compressors.CompressorStreamFactory.BZIP2; +import static org.apache.commons.compress.compressors.CompressorStreamFactory.DEFLATE; +import static org.apache.commons.compress.compressors.CompressorStreamFactory.GZIP; +import static org.apache.commons.compress.compressors.CompressorStreamFactory.LZ4_BLOCK; +import static org.apache.commons.compress.compressors.CompressorStreamFactory.LZ4_FRAMED; +import static org.apache.commons.compress.compressors.CompressorStreamFactory.LZMA; +import static org.apache.commons.compress.compressors.CompressorStreamFactory.SNAPPY_FRAMED; +import static org.apache.commons.compress.compressors.CompressorStreamFactory.XZ; +import static org.apache.commons.compress.compressors.CompressorStreamFactory.ZSTANDARD; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import java.util.stream.Stream; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.appender.rolling.action.Action; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactory; +import org.apache.logging.log4j.test.ListStatusListener; +import org.apache.logging.log4j.test.junit.UsingStatusListener; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +/** + * Test the compression using the algorithms available without additional dependencies. + */ +@UsingStatusListener +class CommonsCompressActionTest extends AbstractCompressActionTest { + + private ListStatusListener statusListener; + + @Test + void testConstructorDisallowsNullSource() { + CompressActionFactory bzip2 = PROVIDER.createFactoryForAlgorithm("bzip2"); + assertThat(bzip2).isNotNull(); + assertThrows(NullPointerException.class, () -> bzip2.createCompressAction(null, ROOT.resolve("any"), Map.of())); + assertThrows(NullPointerException.class, () -> bzip2.createCompressAction(null, "any", Map.of())); + } + + @Test + public void testConstructorDisallowsNullDestination() { + CompressActionFactory bzip2 = PROVIDER.createFactoryForAlgorithm("bzip2"); + assertThat(bzip2).isNotNull(); + assertThrows(NullPointerException.class, () -> bzip2.createCompressAction(ROOT.resolve("any"), null, Map.of())); + assertThrows(NullPointerException.class, () -> bzip2.createCompressAction("any", null, Map.of())); + } + + @Test + void testExecuteReturnsFalseIfSourceDoesNotExist() throws IOException { + Path tempDirectory = Files.createTempDirectory(ROOT, "test"); + CompressActionFactory bzip2 = PROVIDER.createFactoryForAlgorithm("bzip2"); + assertThat(bzip2).isNotNull(); + final Action action = bzip2.createCompressAction( + tempDirectory.resolve("source"), tempDirectory.resolve("destination"), Map.of()); + + assertThat(action).isNotNull(); + assertThat(action.execute()).as("Compress non-existent file").isEqualTo(false); + } + + static Stream algorithms() { + return Stream.of( + GZIP, BZIP2, DEFLATE, SNAPPY_FRAMED, LZ4_BLOCK, LZ4_FRAMED, CustomCompressorStreamProvider.ALGORITHM); + } + + @ParameterizedTest + @MethodSource("algorithms") + void verify_compression_using_Path_params(final String algorithm) throws Exception { + verifyCompressionUsingPathParams(algorithm, Map.of()); + } + + @ParameterizedTest + @MethodSource("algorithms") + void verify_compression_using_String_params(final String algorithm) throws Exception { + verifyCompressionUsingStringParams(algorithm, Map.of()); + } + + static Stream when_dependency_missing_factory_returns_null_and_warns() { + return Stream.of(XZ, LZMA, ZSTANDARD); + } + + @ParameterizedTest + @MethodSource + @UsingStatusListener + void when_dependency_missing_factory_returns_null_and_warns(final String algorithm) throws Exception { + CompressActionFactory factory = PROVIDER.createFactoryForAlgorithm(algorithm); + assertThat(factory) + .as("Compression action factory for disabled algorithm.") + .isNull(); + // We warn the user that the algorithm is not available + assertThat(statusListener.findStatusData(Level.WARN)).anySatisfy(data -> { + assertThat(data.getMessage().getFormattedMessage()) + .contains("missing dependency", "https://commons.apache.org/proper/commons-compress/index.html"); + }); + } +} diff --git a/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/CustomCompressorStreamProvider.java b/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/CustomCompressorStreamProvider.java new file mode 100644 index 00000000000..7b3eec4e94f --- /dev/null +++ b/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/CustomCompressorStreamProvider.java @@ -0,0 +1,80 @@ +/* + * 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.compress.commons; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Set; +import org.apache.commons.compress.compressors.CompressorException; +import org.apache.commons.compress.compressors.CompressorInputStream; +import org.apache.commons.compress.compressors.CompressorOutputStream; +import org.apache.commons.compress.compressors.CompressorStreamProvider; + +public class CustomCompressorStreamProvider implements CompressorStreamProvider { + + static final String ALGORITHM = "custom"; + + @Override + public CompressorInputStream createCompressorInputStream(String name, InputStream in, boolean decompressUntilEOF) + throws CompressorException { + if (ALGORITHM.equalsIgnoreCase(name)) { + return new CustomCompressorInputStream(in); + } + throw new CompressorException("Compressor: " + name + " not found."); + } + + @Override + public CompressorOutputStream createCompressorOutputStream(String name, OutputStream out) + throws CompressorException { + if (ALGORITHM.equalsIgnoreCase(name)) { + return new CustomCompressorOutputStream(out); + } + throw new CompressorException("Compressor: " + name + " not found."); + } + + @Override + public Set getInputStreamCompressorNames() { + return Set.of(ALGORITHM); + } + + @Override + public Set getOutputStreamCompressorNames() { + return Set.of(ALGORITHM); + } + + private static class CustomCompressorInputStream extends CompressorInputStream { + + private final InputStream in; + + public CustomCompressorInputStream(InputStream in) { + this.in = in; + } + + @Override + public int read() throws IOException { + return in.read(); + } + } + + private static class CustomCompressorOutputStream extends CompressorOutputStream { + + public CustomCompressorOutputStream(OutputStream out) { + super(out); + } + } +} diff --git a/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/xz/XzCompressActionTest.java b/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/xz/XzCompressActionTest.java new file mode 100644 index 00000000000..ecd0bbb30d5 --- /dev/null +++ b/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/xz/XzCompressActionTest.java @@ -0,0 +1,45 @@ +/* + * 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.compress.commons.xz; + +import java.util.Map; +import java.util.stream.Stream; +import org.apache.logging.log4j.compress.commons.AbstractCompressActionTest; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +/** + * The XZ and LZMA algorithms have additional dependencies and requires a separate Surefire run. + */ +public class XzCompressActionTest extends AbstractCompressActionTest { + + static Stream algorithms() { + return Stream.of("lzma", "xz"); + } + + @ParameterizedTest + @MethodSource("algorithms") + void verify_compression_using_Path_params(String algorithm) throws Exception { + verifyCompressionUsingPathParams(algorithm, Map.of()); + } + + @ParameterizedTest + @MethodSource("algorithms") + void verify_compression_using_String_params(String algorithm) throws Exception { + verifyCompressionUsingStringParams(algorithm, Map.of()); + } +} diff --git a/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/zstd/ZstdCompressActionTest.java b/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/zstd/ZstdCompressActionTest.java new file mode 100644 index 00000000000..9bdd3546365 --- /dev/null +++ b/log4j-compress/src/test/java/org/apache/logging/log4j/compress/commons/zstd/ZstdCompressActionTest.java @@ -0,0 +1,39 @@ +/* + * 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.compress.commons.zstd; + +import java.util.Map; +import org.apache.logging.log4j.compress.commons.AbstractCompressActionTest; +import org.junit.jupiter.api.Test; + +/** + * The Zstd algorithm has additional dependencies and requires a separate Surefire run. + */ +public class ZstdCompressActionTest extends AbstractCompressActionTest { + + private static final String ALGORITHM = "zstd"; + + @Test + void verify_compression_using_Path_params() throws Exception { + verifyCompressionUsingPathParams(ALGORITHM, Map.of()); + } + + @Test + void verify_compression_using_String_params() throws Exception { + verifyCompressionUsingStringParams(ALGORITHM, Map.of()); + } +} diff --git a/log4j-compress/src/test/resources/META-INF/services/org.apache.commons.compress.compressors.CompressorStreamProvider b/log4j-compress/src/test/resources/META-INF/services/org.apache.commons.compress.compressors.CompressorStreamProvider new file mode 100644 index 00000000000..dfe7b8fcc3d --- /dev/null +++ b/log4j-compress/src/test/resources/META-INF/services/org.apache.commons.compress.compressors.CompressorStreamProvider @@ -0,0 +1,4 @@ +## +# BND does not register services in the `src/test` folder automatically, +# therefore, we need a manual registration +org.apache.logging.log4j.compress.commons.CustomCompressorStreamProvider \ No newline at end of file diff --git a/log4j-core-test/pom.xml b/log4j-core-test/pom.xml index e492bff9177..47ca1a22d8c 100644 --- a/log4j-core-test/pom.xml +++ b/log4j-core-test/pom.xml @@ -64,50 +64,51 @@ + org.osgi org.osgi.framework provided + org.osgi org.osgi.resource provided + org.apache.logging.log4j log4j-api - + org.apache.logging.log4j log4j-api-test + org.apache.logging.log4j log4j-core + org.apache.logging.log4j log4j-plugins + org.apache.logging.log4j log4j-plugins-test + org.assertj assertj-core - - - org.apache.commons - commons-compress - true - @@ -115,138 +116,164 @@ disruptor true + org.hamcrest hamcrest + com.fasterxml.jackson.core jackson-core true + com.fasterxml.jackson.core jackson-databind true + com.fasterxml.jackson.dataformat jackson-dataformat-xml true + com.fasterxml.jackson.dataformat jackson-dataformat-yaml true + org.fusesource.jansi jansi true + org.junit.jupiter junit-jupiter-engine + org.junit.jupiter junit-jupiter-migrationsupport + org.junit.jupiter junit-jupiter-params + org.junit-pioneer junit-pioneer true + org.junit.vintage junit-vintage-engine + org.awaitility awaitility test + commons-codec commons-codec test + commons-io commons-io test + org.apache.commons commons-lang3 test + com.h2database h2 test + org.hdrhistogram HdrHistogram test + org.hsqldb hsqldb test + org.jmdns jmdns test + log4j log4j test + com.github.ivandzf log4j2-custom-layout test + com.vlkan.log4j2 log4j2-logstash-layout test + org.mockito mockito-core test + org.mockito mockito-subclass test + org.mockito mockito-junit-jupiter test + @@ -254,39 +281,39 @@ nashorn-core test + org.slf4j slf4j-api test + org.graalvm.truffle truffle-api test + com.github.tomakehurst wiremock-jre8 test + org.xmlunit xmlunit-core test + org.xmlunit xmlunit-matchers test - - - org.tukaani - xz - test - + diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/EligibleFilesTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/EligibleFilesTest.java index ec3600d9e6a..6c5c28a1bb6 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/EligibleFilesTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/EligibleFilesTest.java @@ -16,42 +16,66 @@ */ package org.apache.logging.log4j.core.appender.rolling; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; +import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactoryProvider; import org.apache.logging.log4j.core.pattern.NotANumber; +import org.apache.logging.log4j.test.junit.TempLoggingDir; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; /** * Test getEligibleFiles method. */ -public class EligibleFilesTest { +class EligibleFilesTest { + + private static final int COUNT_1 = 20; + private static final int COUNT_2 = 30; + private static final String PREFIX_1 = "log4j.txt.20170112_09-"; + private static final String PREFIX_2 = "log4j.20211028T194500+0200."; + + @TempLoggingDir + private static Path loggingPath; + + @BeforeAll + static void setup() throws IOException { + int i; + // Create files for tests + for (i = 1; i < COUNT_1; i++) { + Files.createFile(loggingPath.resolve(String.format("%s%02d%s", PREFIX_1, i, ".gz"))); + } + Files.createFile(loggingPath.resolve(String.format("%s%02d", PREFIX_1, i))); + + for (i = 1; i < COUNT_2; i++) { + Files.createFile(loggingPath.resolve(String.format("%s%d%s", PREFIX_2, i, ".log.gz"))); + } + Files.createFile(loggingPath.resolve(String.format("%s%d%s", PREFIX_2, i, ".log"))); + } @Test - public void runTest() throws Exception { - final String path = "target/test-classes/rolloverPath/log4j.txt.20170112_09-" + NotANumber.VALUE + ".gz"; + void runTest() throws Exception { + final String path = loggingPath + "/" + PREFIX_1 + NotANumber.VALUE + ".gz"; final TestRolloverStrategy strategy = new TestRolloverStrategy(); final Map files = strategy.findFilesInPath(path); - assertTrue(files.size() > 0, "No files found"); - assertEquals(30, files.size(), "Incorrect number of files found. Should be 30, was " + files.size()); + assertThat(files).isNotEmpty().hasSize(COUNT_1); } @Test - public void runTestWithPlusCharacter() throws Exception { - final String path = - "target/test-classes/rolloverPath/log4j.20211028T194500+0200." + NotANumber.VALUE + ".log.gz"; + void runTestWithPlusCharacter() throws Exception { + final String path = loggingPath + "/" + PREFIX_2 + NotANumber.VALUE + ".log.gz"; final TestRolloverStrategy strategy = new TestRolloverStrategy(); final Map files = strategy.findFilesWithPlusInPath(path); - assertTrue(files.size() > 0, "No files found"); - assertEquals(30, files.size(), "Incorrect number of files found. Should be 30, was " + files.size()); + assertThat(files).isNotEmpty().hasSize(COUNT_2); } private static class TestRolloverStrategy extends AbstractRolloverStrategy { public TestRolloverStrategy() { - super(null); + super(CompressActionFactoryProvider.newInstance(null), null); } @Override diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/OnStartupTriggeringPolicyTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/OnStartupTriggeringPolicyTest.java index 5417f446955..0254773222a 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/OnStartupTriggeringPolicyTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/OnStartupTriggeringPolicyTest.java @@ -87,7 +87,6 @@ public void testPolicy() throws Exception { .setConfiguration(configuration) .build(); final RolloverStrategy strategy = DefaultRolloverStrategy.newBuilder() - .setCompressionLevelStr("0") .setStopCustomActionsOnError(true) .setConfig(configuration) .build(); diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java index 3603f75dbcf..1578daf897c 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java @@ -26,6 +26,8 @@ import java.util.concurrent.TimeUnit; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactory; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactoryProvider; import org.apache.logging.log4j.core.test.junit.LoggerContextSource; import org.apache.logging.log4j.core.util.FileUtils; import org.apache.logging.log4j.test.junit.CleanUpDirectories; @@ -68,7 +70,8 @@ public void testAppenderCompressPermissions(final Logger logger, final LoggerCon int gzippedFiles1 = 0; int gzippedFiles2 = 0; for (final File file : files) { - final FileExtension ext = FileExtension.lookupForFile(file.getName()); + final CompressActionFactory ext = CompressActionFactoryProvider.newInstance(context.getConfiguration()) + .createFactoryForFileName(file.getName()); if (ext != null) { if (file.getName().startsWith("test1")) { gzippedFiles1++; diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java index 58b4fb63afd..ddbc479d398 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java @@ -16,24 +16,19 @@ */ package org.apache.logging.log4j.core.appender.rolling; -import static org.apache.logging.log4j.util.Strings.toRootLowerCase; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; +import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; -import java.util.stream.Stream; -import org.apache.commons.compress.compressors.CompressorStreamFactory; -import org.apache.commons.compress.utils.IOUtils; -import org.apache.commons.io.FileUtils; +import java.util.zip.GZIPInputStream; +import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.appender.RollingFileAppender; import org.apache.logging.log4j.core.impl.Log4jLogEvent; @@ -41,34 +36,27 @@ import org.apache.logging.log4j.message.ParameterizedMessage; import org.apache.logging.log4j.test.junit.TempLoggingDir; import org.apache.logging.log4j.test.junit.UsingStatusListener; +import org.jspecify.annotations.NullMarked; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; @UsingStatusListener -public class RollingAppenderSizeTest { +@NullMarked +class RollingAppenderSizeTest { - private static long DEFAULT_SHUTDOWN_MS = 500; + private static final long DEFAULT_SHUTDOWN_MS = 500; - private static final Pattern MESSAGE_PATTERN = Pattern.compile("This is test message numer \\d+."); - - private static final List FILE_EXTENSIONS = Arrays.asList("gz", "zip", "bz2", "deflate", "pack200", "xz"); - - static Stream parameters() { - return FILE_EXTENSIONS.stream().flatMap(fileExtension -> { - return Stream.of(Arguments.of(fileExtension, true), Arguments.of(fileExtension, false)); - }); - } + private static final String MESSAGE = "This is test message number {}."; + private static final Pattern MESSAGE_PATTERN = Pattern.compile("This is test message number \\d+."); @TempLoggingDir private static Path loggingPath; private static RollingFileAppender createRollingFileAppender( - final String fileExtension, final boolean createOnDemand) { - final Path folder = loggingPath.resolve(fileExtension); - final String fileName = folder.resolve("rollingtest.log").toString(); + final Path perTestFolder, final boolean createOnDemand) { + final String fileName = perTestFolder.resolve("rollingtest.log").toString(); final String filePattern = - folder.resolve("rollingtest-%i.log." + fileExtension).toString(); + perTestFolder.resolve("rollingtest-%i.log.gz").toString(); final RollingFileAppender appender = RollingFileAppender.newBuilder() .setName("RollingFile") .setFileName(fileName) @@ -81,73 +69,63 @@ private static RollingFileAppender createRollingFileAppender( return appender; } - private static LogEvent createEvent(final String pattern, final Object p0) { + private static LogEvent createEvent(final Integer number) { return Log4jLogEvent.newBuilder() - .setMessage(new ParameterizedMessage(pattern, p0)) + .setMessage(new ParameterizedMessage(MESSAGE, number)) .build(); } @ParameterizedTest - @MethodSource("parameters") - public void testIsCreateOnDemand(final String fileExtension, final boolean createOnDemand) throws IOException { - final Path extensionFolder = loggingPath.resolve(fileExtension); + @ValueSource(booleans = {true, false}) + void testIsCreateOnDemand(final boolean createOnDemand) { + Path perTestFolder = loggingPath.resolve(Boolean.toString(createOnDemand)); RollingFileAppender appender = null; try { - appender = createRollingFileAppender(fileExtension, createOnDemand); + appender = createRollingFileAppender(perTestFolder, createOnDemand); final RollingFileManager manager = appender.getManager(); assertThat(manager).isNotNull().extracting("createOnDemand").isEqualTo(createOnDemand); } finally { - appender.stop(DEFAULT_SHUTDOWN_MS, TimeUnit.MILLISECONDS); - FileUtils.deleteDirectory(extensionFolder.toFile()); + if (appender != null && appender.isStarted()) { + appender.stop(DEFAULT_SHUTDOWN_MS, TimeUnit.MILLISECONDS); + } } } @ParameterizedTest - @MethodSource("parameters") - public void testAppender(final String fileExtension, final boolean createOnDemand) throws Exception { - final Path extensionFolder = loggingPath.resolve(fileExtension); + @ValueSource(booleans = {true, false}) + void testAppender(final boolean createOnDemand) throws IOException { + Path perTestFolder = loggingPath.resolve(Boolean.toString(createOnDemand)); RollingFileAppender appender = null; try { - appender = createRollingFileAppender(fileExtension, createOnDemand); - final Path currentLog = extensionFolder.resolve("rollingtest.log"); + appender = createRollingFileAppender(perTestFolder, createOnDemand); + final Path currentLog = perTestFolder.resolve("rollingtest.log"); if (createOnDemand) { assertThat(currentLog).as("file created on demand").doesNotExist(); } for (int i = 0; i < 500; ++i) { - appender.append(createEvent("This is test message numer {}.", i)); + appender.append(createEvent(i)); } appender.stop(DEFAULT_SHUTDOWN_MS, TimeUnit.MILLISECONDS); - assertThat(extensionFolder).isDirectoryContaining("glob:**/*." + fileExtension); - - final FileExtension ext = FileExtension.lookup(fileExtension); - if (ext == null || FileExtension.ZIP == ext || FileExtension.PACK200 == ext) { - return; // Apache Commons Compress cannot deflate zip? TODO test decompressing these - // formats - } - - for (final Path file : Files.newDirectoryStream(extensionFolder)) { - if (file.getFileName().endsWith(fileExtension)) { - try (final InputStream fis = Files.newInputStream(file); - final InputStream in = new CompressorStreamFactory() - .createCompressorInputStream(toRootLowerCase(ext.name()), fis)) { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - assertThat(in).as("compressed input stream").isNotNull(); - assertDoesNotThrow(() -> IOUtils.copy(in, baos)); - final String text = new String(baos.toByteArray(), Charset.defaultCharset()); - final String[] lines = text.split("[\\r\\n]+"); - assertThat(lines) - .allMatch(message -> - MESSAGE_PATTERN.matcher(message).matches()); + assertThat(perTestFolder).isDirectoryContaining("glob:**/*.gz"); + + try (DirectoryStream files = Files.newDirectoryStream(perTestFolder)) { + assertThat(files).allSatisfy(file -> { + if (file.getFileName().endsWith(".gz")) { + try (final InputStream fileInput = Files.newInputStream(file); + final InputStream input = new GZIPInputStream(fileInput)) { + List lines = IOUtils.readLines(input, Charset.defaultCharset()); + assertThat(lines) + .allMatch(m -> MESSAGE_PATTERN.matcher(m).matches()); + } } - } + }); } } finally { - if (appender.isStarted()) { + if (appender != null && appender.isStarted()) { appender.stop(DEFAULT_SHUTDOWN_MS, TimeUnit.MILLISECONDS); } - FileUtils.deleteDirectory(extensionFolder.toFile()); } } } diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeWithTimeTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeWithTimeTest.java index dd32c550c69..08eca9cef86 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeWithTimeTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeWithTimeTest.java @@ -27,7 +27,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import org.apache.commons.compress.utils.IOUtils; +import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.test.junit.LoggerContextSource; @@ -69,8 +69,7 @@ public void testAppender(final Logger logger, final LoggerContext context) throw try { IOUtils.copy(fis, baos); } catch (final Exception ex) { - ex.printStackTrace(); - fail("Unable to read " + file.getAbsolutePath()); + fail("Unable to read " + file.getAbsolutePath(), ex); } } final String text = baos.toString(Charset.defaultCharset()); diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTempCompressedFilePatternTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTempCompressedFilePatternTest.java index 2a2152f2434..837f797bb07 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTempCompressedFilePatternTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTempCompressedFilePatternTest.java @@ -16,13 +16,12 @@ */ package org.apache.logging.log4j.core.appender.rolling; -import static org.apache.logging.log4j.util.Strings.toRootLowerCase; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.nio.charset.Charset; +import java.nio.file.DirectoryStream; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; @@ -33,10 +32,10 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; -import org.apache.commons.compress.compressors.CompressorStreamFactory; -import org.apache.commons.compress.utils.IOUtils; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; +import java.util.zip.GZIPInputStream; +import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.test.junit.LoggerContextSource; @@ -50,10 +49,10 @@ /** * LOG4J2-1766. */ -@UsingStatusListener -public class RollingAppenderTempCompressedFilePatternTest { +@UsingStatusListener // Disables status logger unless an error occurs +class RollingAppenderTempCompressedFilePatternTest { - private static Logger LOGGER = StatusLogger.getLogger(); + private static final Logger LOGGER = StatusLogger.getLogger(); @TempLoggingDir private static Path loggingPath; @@ -61,13 +60,13 @@ public class RollingAppenderTempCompressedFilePatternTest { @Test @DisabledOnOs(value = OS.MAC, disabledReason = "FileWatcher isn't fast enough to work properly.") @LoggerContextSource - public void testAppender(final LoggerContext context) throws Exception { + void testAppender(final LoggerContext context) throws Exception { final Logger logger = context.getLogger(getClass()); final Path logsDir = loggingPath.resolve("logs"); final Path tmpDir = loggingPath.resolve("tmp"); Files.createDirectories(tmpDir); try (final WatchService watcher = FileSystems.getDefault().newWatchService()) { - WatchKey key = tmpDir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE); + tmpDir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE); final List messages = new ArrayList<>(); for (int i = 0; i < 500; ++i) { @@ -82,49 +81,42 @@ public void testAppender(final LoggerContext context) throws Exception { getClass().getSimpleName()); } - int gzippedFiles = 0; - final List files = StreamSupport.stream( - Files.newDirectoryStream(logsDir).spliterator(), false) - .collect(Collectors.toList()); - for (final Path file : files) { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final FileExtension ext = - FileExtension.lookupForFile(file.getFileName().toString()); - if (ext != null) { - gzippedFiles++; - } - try (final InputStream fis = Files.newInputStream(file); - final InputStream in = ext != null - ? new CompressorStreamFactory() - .createCompressorInputStream(toRootLowerCase(ext.name()), fis) - : fis) { - assertThat(in).as("compressed input stream").isNotNull(); - assertDoesNotThrow(() -> IOUtils.copy(in, baos)); - } - final String text = baos.toString(Charset.defaultCharset()); - final String[] lines = text.split("[\\r\\n]+"); - for (final String line : lines) { - messages.remove(line); - } + AtomicInteger fileCount = new AtomicInteger(); + AtomicInteger gzippedFileCount = new AtomicInteger(); + try (final DirectoryStream files = Files.newDirectoryStream(logsDir)) { + files.forEach(file -> assertDoesNotThrow(() -> { + fileCount.incrementAndGet(); + final boolean isGzipped = file.getFileName().toString().endsWith(".gz"); + if (isGzipped) { + gzippedFileCount.incrementAndGet(); + try (InputStream fileInput = Files.newInputStream(file); + InputStream input = new GZIPInputStream(fileInput)) { + IOUtils.readLines(input, Charset.defaultCharset()).forEach(messages::remove); + } + } else { + try (Stream lines = Files.lines(file, Charset.defaultCharset())) { + lines.forEach(messages::remove); + } + } + })); } assertThat(messages).as("Lost messages").isEmpty(); - assertThat(files).as("Log files").hasSizeGreaterThan(16); - assertThat(gzippedFiles).as("Compressed log file count").isGreaterThan(16); + assertThat(fileCount).as("Log file file count").hasValueGreaterThan(16); + assertThat(gzippedFileCount).as("Compressed log file count").hasValueGreaterThan(16); - int temporaryFilesCreated = 0; - key = watcher.take(); + int temporaryFileCount = 0; + WatchKey key = watcher.take(); for (final WatchEvent event : key.pollEvents()) { - final WatchEvent ev = (WatchEvent) event; - final Path filename = ev.context(); + final Path filename = (Path) event.context(); if (filename.toString().endsWith(".tmp")) { - temporaryFilesCreated++; + temporaryFileCount++; } } - assertThat(temporaryFilesCreated) - .as("Temporary files created") + assertThat(temporaryFileCount) + .as("Temporary file count") .isGreaterThan(0) - .isEqualTo(gzippedFiles); + .isEqualTo(gzippedFileCount.get()); } } } diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderUpdateDataTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderUpdateDataTest.java index 872bd3fe7e8..e0d6c2aed6f 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderUpdateDataTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderUpdateDataTest.java @@ -16,6 +16,10 @@ */ package org.apache.logging.log4j.core.appender.rolling; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; + import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.LoggerContext; @@ -25,14 +29,15 @@ import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory; import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; -import org.junit.After; -import org.junit.Assert; -import org.junit.Test; +import org.apache.logging.log4j.test.junit.UsingStatusListener; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; /** * Tests LOG4J2-2009 Rolling appender managers broken on pattern/policy reconfiguration */ -public class RollingFileAppenderUpdateDataTest { +@UsingStatusListener // To disable the status logger unless an error occurs +class RollingFileAppenderUpdateDataTest { private ConfigurationBuilder buildConfigA() { return buildConfigurationBuilder("target/rolling-update-date/foo.log.%i"); @@ -64,8 +69,8 @@ private ConfigurationBuilder buildConfigurationBuilder(final private LoggerContext loggerContext1 = null; private LoggerContext loggerContext2 = null; - @After - public void after() { + @AfterEach + void after() { if (loggerContext1 != null) { loggerContext1.close(); loggerContext1 = null; @@ -77,7 +82,7 @@ public void after() { } @Test - public void testClosingLoggerContext() { + void testClosingLoggerContext() { // initial config with indexed rollover try (final LoggerContext loggerContext1 = Configurator.initialize(buildConfigA().build())) { @@ -92,20 +97,20 @@ public void testClosingLoggerContext() { } @Test - public void testNotClosingLoggerContext() { + void testNotClosingLoggerContext() { // initial config with indexed rollover loggerContext1 = Configurator.initialize(buildConfigA().build()); validateAppender(loggerContext1, "target/rolling-update-date/foo.log.%i"); // rebuild config with date based rollover loggerContext2 = Configurator.initialize(buildConfigB().build()); - Assert.assertNotNull("No LoggerContext", loggerContext2); - Assert.assertSame("Expected same logger context to be returned", loggerContext1, loggerContext2); + assertNotNull(loggerContext2, "No LoggerContext"); + assertSame(loggerContext1, loggerContext2, "Expected same logger context to be returned"); validateAppender(loggerContext1, "target/rolling-update-date/foo.log.%i"); } @Test - public void testReconfigure() { + void testReconfigure() { // initial config with indexed rollover loggerContext1 = Configurator.initialize(buildConfigA().build()); validateAppender(loggerContext1, "target/rolling-update-date/foo.log.%i"); @@ -117,8 +122,8 @@ public void testReconfigure() { private void validateAppender(final LoggerContext loggerContext, final String expectedFilePattern) { final RollingFileAppender appender = loggerContext.getConfiguration().getAppender("fooAppender"); - Assert.assertNotNull(appender); - Assert.assertEquals(expectedFilePattern, appender.getFilePattern()); + assertNotNull(appender); + assertEquals(expectedFilePattern, appender.getFilePattern()); LogManager.getLogger("root").info("just to show it works."); } } diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java index 51b22edfdb4..79d8d82e64f 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManagerTest.java @@ -29,6 +29,7 @@ import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.appender.RollingFileAppender; import org.apache.logging.log4j.core.appender.rolling.action.AbstractAction; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactoryProvider; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.NullConfiguration; import org.apache.logging.log4j.core.layout.PatternLayout; @@ -49,7 +50,7 @@ class CustomDirectFileRolloverStrategy extends AbstractRolloverStrategy implemen final File file; CustomDirectFileRolloverStrategy(final File file, final StrSubstitutor strSubstitutor) { - super(strSubstitutor); + super(CompressActionFactoryProvider.newInstance(null), strSubstitutor); this.file = file; } diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/Bzip2CompressActionTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/Bzip2CompressActionTest.java deleted file mode 100644 index a3119c8bd80..00000000000 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/Bzip2CompressActionTest.java +++ /dev/null @@ -1,233 +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.rolling.action; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileWriter; -import java.io.IOException; -import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -/** - * Tests Bzip2CompressAction. - */ -public class Bzip2CompressActionTest { - - @Test - public void testConstructorDisallowsNullSource() { - assertThrows(NullPointerException.class, () -> new CommonsCompressAction("bzip2", null, new File("any"), true)); - } - - @Test - public void testConstructorDisallowsNullDestination() { - assertThrows(NullPointerException.class, () -> new CommonsCompressAction("bzip2", new File("any"), null, true)); - } - - @Test - public void testExecuteReturnsFalseIfSourceDoesNotExist() throws IOException { - File source = new File("any"); - while (source.exists()) { - source = new File(source.getName() + Math.random()); - } - final boolean actual = CommonsCompressAction.execute("bzip2", source, new File("any2"), true); - assertFalse(actual, "Cannot compress non-existing file"); - } - - @Test - public void testExecuteCompressesSourceFileToDestinationFile(@TempDir final File tempDir) throws IOException { - final String LINE1 = "Here is line 1. Random text: ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"; - final String LINE2 = "Here is line 2. Random text: ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"; - final String LINE3 = "Here is line 3. Random text: ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"; - final File source = new File(tempDir, "compressme"); - try (final FileWriter fw = new FileWriter(source, false)) { - fw.write(LINE1); - fw.write(LINE2); - fw.write(LINE3); - fw.flush(); - } - final File destination = new File(tempDir, "compressme.bz2"); - assertFalse(destination.exists(), "Destination should not exist yet"); - - final boolean actual = CommonsCompressAction.execute("bzip2", source, destination, true); - assertTrue(actual, "Bzip2CompressAction should have succeeded"); - assertTrue(destination.exists(), "Destination should exist after Bzip2CompressAction"); - assertFalse(source.exists(), "Source should have been deleted"); - - final byte[] bz2 = new byte[] { - (byte) 0x42, - (byte) 0x5A, - (byte) 0x68, - (byte) 0x39, - (byte) 0x31, - (byte) 0x41, - (byte) 0x59, - (byte) 0x26, - (byte) 0x53, - (byte) 0x59, - (byte) 0x9C, - (byte) 0xE1, - (byte) 0xE8, - (byte) 0x2D, - (byte) 0x00, - (byte) 0x00, - (byte) 0x1C, - (byte) 0xDF, - (byte) 0x80, - (byte) 0x00, - (byte) 0x12, - (byte) 0x40, - (byte) 0x01, - (byte) 0x38, - (byte) 0x10, - (byte) 0x3F, - (byte) 0xFF, - (byte) 0xFF, - (byte) 0xF0, - (byte) 0x26, - (byte) 0x27, - (byte) 0x9C, - (byte) 0x40, - (byte) 0x20, - (byte) 0x00, - (byte) 0x70, - (byte) 0x63, - (byte) 0x4D, - (byte) 0x06, - (byte) 0x80, - (byte) 0x19, - (byte) 0x34, - (byte) 0x06, - (byte) 0x46, - (byte) 0x9A, - (byte) 0x18, - (byte) 0x9A, - (byte) 0x30, - (byte) 0xCF, - (byte) 0xFD, - (byte) 0x55, - (byte) 0x4D, - (byte) 0x0D, - (byte) 0x06, - (byte) 0x9A, - (byte) 0x0C, - (byte) 0x40, - (byte) 0x1A, - (byte) 0x1A, - (byte) 0x34, - (byte) 0x34, - (byte) 0xCD, - (byte) 0x46, - (byte) 0x05, - (byte) 0x6B, - (byte) 0x19, - (byte) 0x92, - (byte) 0x23, - (byte) 0x5E, - (byte) 0xB5, - (byte) 0x2E, - (byte) 0x79, - (byte) 0x65, - (byte) 0x41, - (byte) 0x81, - (byte) 0x33, - (byte) 0x4B, - (byte) 0x53, - (byte) 0x5B, - (byte) 0x62, - (byte) 0x75, - (byte) 0x0A, - (byte) 0x14, - (byte) 0xB6, - (byte) 0xB7, - (byte) 0x37, - (byte) 0xB8, - (byte) 0x38, - (byte) 0xB9, - (byte) 0x39, - (byte) 0xBA, - (byte) 0x2A, - (byte) 0x4E, - (byte) 0xEA, - (byte) 0xEC, - (byte) 0xEE, - (byte) 0xAD, - (byte) 0xE1, - (byte) 0xE5, - (byte) 0x63, - (byte) 0xD3, - (byte) 0x22, - (byte) 0xE8, - (byte) 0x90, - (byte) 0x52, - (byte) 0xA9, - (byte) 0x7A, - (byte) 0x68, - (byte) 0x90, - (byte) 0x5C, - (byte) 0x82, - (byte) 0x0B, - (byte) 0x51, - (byte) 0xBF, - (byte) 0x24, - (byte) 0x61, - (byte) 0x7F, - (byte) 0x17, - (byte) 0x72, - (byte) 0x45, - (byte) 0x38, - (byte) 0x50, - (byte) 0x90, - (byte) 0x9C, - (byte) 0xE1, - (byte) 0xE8, - (byte) 0x2D - }; - assertEquals(bz2.length, destination.length()); - - // check the compressed contents - try (final FileInputStream fis = new FileInputStream(destination)) { - final byte[] actualBz2 = new byte[bz2.length]; - int n = 0; - int offset = 0; - do { - n = fis.read(actualBz2, offset, actualBz2.length - offset); - offset += n; - } while (offset < actualBz2.length); - assertArrayEquals(bz2, actualBz2, "Compressed data corrupt"); - } - - // uncompress - try (final BZip2CompressorInputStream bzin = new BZip2CompressorInputStream(new ByteArrayInputStream(bz2))) { - final StringBuilder sb = new StringBuilder(); - final byte[] buf = new byte[1024]; - int n = 0; - while ((n = bzin.read(buf, 0, buf.length)) > -1) { - sb.append(new String(buf, 0, n)); - } - assertEquals(LINE1 + LINE2 + LINE3, sb.toString()); - } - } -} diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.1.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.1.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.1.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.10.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.10.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.10.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.11.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.11.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.11.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.12.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.12.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.12.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.13.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.13.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.13.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.14.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.14.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.14.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.15.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.15.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.15.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.16.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.16.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.16.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.17.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.17.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.17.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.18.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.18.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.18.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.19.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.19.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.19.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.2.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.2.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.2.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.20.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.20.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.20.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.21.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.21.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.21.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.22.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.22.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.22.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.23.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.23.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.23.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.24.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.24.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.24.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.25.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.25.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.25.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.26.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.26.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.26.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.27.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.27.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.27.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.28.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.28.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.28.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.29.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.29.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.29.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.3.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.3.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.3.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.30.log b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.30.log deleted file mode 100644 index 8d1c8b69c3f..00000000000 --- a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.30.log +++ /dev/null @@ -1 +0,0 @@ - diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.4.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.4.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.4.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.5.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.5.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.5.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.6.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.6.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.6.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.7.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.7.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.7.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.8.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.8.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.8.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.9.log.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.9.log.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.20211028T194500+0200.9.log.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_00-1.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_00-1.gz deleted file mode 100644 index 9273874779c..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_00-1.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_00-2.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_00-2.gz deleted file mode 100644 index 605ce252435..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_00-2.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_01-1.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_01-1.gz deleted file mode 100644 index bd3303ea9e0..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_01-1.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-1.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-1.gz deleted file mode 100644 index 411c7c6989b..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-1.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-2.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-2.gz deleted file mode 100644 index ac35e3b4364..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-2.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-3.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-3.gz deleted file mode 100644 index 4ebd274bd82..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-3.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-4.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-4.gz deleted file mode 100644 index ddd4f287829..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-4.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-5.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-5.gz deleted file mode 100644 index a69b1abe2f4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_02-5.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-1.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-1.gz deleted file mode 100644 index 8eded4e145c..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-1.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-2.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-2.gz deleted file mode 100644 index 9df313ca08d..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-2.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-3.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-3.gz deleted file mode 100644 index 6e4deb25a55..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-3.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-4.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-4.gz deleted file mode 100644 index eb38d1a026f..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-4.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-5.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-5.gz deleted file mode 100644 index eb33a0c4c5a..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_03-5.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-1.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-1.gz deleted file mode 100644 index f612cd6c1dc..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-1.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-2.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-2.gz deleted file mode 100644 index a0c9c7ae01d..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-2.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-3.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-3.gz deleted file mode 100644 index 5ac0a240150..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-3.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-4.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-4.gz deleted file mode 100644 index 8c4c56fe6b2..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-4.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-5.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-5.gz deleted file mode 100644 index 2586926cfc4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_04-5.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-1.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-1.gz deleted file mode 100644 index 2cb3dbe08c2..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-1.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-2.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-2.gz deleted file mode 100644 index df8eb5f1a95..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-2.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-3.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-3.gz deleted file mode 100644 index 595e822ff7a..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-3.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-4.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-4.gz deleted file mode 100644 index e23bfa7173f..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-4.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-5.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-5.gz deleted file mode 100644 index 2b62b60990e..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_05-5.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-1.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-1.gz deleted file mode 100644 index 4029d872eea..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-1.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-10.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-10.gz deleted file mode 100644 index 5e84491eda8..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-10.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-11.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-11.gz deleted file mode 100644 index 35e910634fc..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-11.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-12.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-12.gz deleted file mode 100644 index 8c6c8c9960c..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-12.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-13.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-13.gz deleted file mode 100644 index d57e4057488..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-13.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-14.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-14.gz deleted file mode 100644 index 3a51392d142..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-14.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-15.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-15.gz deleted file mode 100644 index 3665dcd5405..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-15.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-16.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-16.gz deleted file mode 100644 index 2082cfe304d..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-16.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-17.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-17.gz deleted file mode 100644 index e50158846db..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-17.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-18.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-18.gz deleted file mode 100644 index 94c617d8cf1..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-18.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-19.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-19.gz deleted file mode 100644 index 90b8ad5dc8d..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-19.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-2.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-2.gz deleted file mode 100644 index ae38614a091..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-2.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-20.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-20.gz deleted file mode 100644 index 084b35f2fb3..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-20.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-3.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-3.gz deleted file mode 100644 index 500fe483c04..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-3.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-4.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-4.gz deleted file mode 100644 index 69d2c598e7f..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-4.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-5.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-5.gz deleted file mode 100644 index 582ffbfe19a..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-5.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-6.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-6.gz deleted file mode 100644 index 6c495edbca3..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-6.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-7.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-7.gz deleted file mode 100644 index a0e74ab42b0..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-7.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-8.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-8.gz deleted file mode 100644 index eee5116be89..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-8.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-9.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-9.gz deleted file mode 100644 index 44db59a663e..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_06-9.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-1.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-1.gz deleted file mode 100644 index 84e8da87919..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-1.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-10.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-10.gz deleted file mode 100644 index f21f32ddaf7..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-10.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-11.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-11.gz deleted file mode 100644 index 2a5cf2cc71b..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-11.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-12.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-12.gz deleted file mode 100644 index 77bda429e29..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-12.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-13.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-13.gz deleted file mode 100644 index cd6efb0840d..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-13.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-14.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-14.gz deleted file mode 100644 index a77093658f5..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-14.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-15.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-15.gz deleted file mode 100644 index 8202f961b75..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-15.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-16.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-16.gz deleted file mode 100644 index b54b72bfbc2..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-16.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-17.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-17.gz deleted file mode 100644 index 09062f69144..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-17.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-18.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-18.gz deleted file mode 100644 index 0e92dd607cb..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-18.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-19.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-19.gz deleted file mode 100644 index d676180ddb1..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-19.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-2.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-2.gz deleted file mode 100644 index 325ec46b771..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-2.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-20.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-20.gz deleted file mode 100644 index 3bb918cc4dc..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-20.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-21.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-21.gz deleted file mode 100644 index eb9047ad7a6..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-21.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-22.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-22.gz deleted file mode 100644 index 4e8e476beb8..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-22.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-23.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-23.gz deleted file mode 100644 index 6628d1bfefb..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-23.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-24.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-24.gz deleted file mode 100644 index bfc9cfbbc0c..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-24.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-25.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-25.gz deleted file mode 100644 index 24cd8d078b6..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-25.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-26.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-26.gz deleted file mode 100644 index 910de6be57b..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-26.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-27.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-27.gz deleted file mode 100644 index ceca019b6a0..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-27.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-28.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-28.gz deleted file mode 100644 index efe0f3cb815..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-28.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-29.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-29.gz deleted file mode 100644 index b2f5a65595a..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-29.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-3.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-3.gz deleted file mode 100644 index ffd78fa2270..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-3.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-4.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-4.gz deleted file mode 100644 index e1b0df904a3..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-4.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-5.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-5.gz deleted file mode 100644 index 46d1e528178..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-5.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-6.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-6.gz deleted file mode 100644 index dc950fd50de..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-6.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-7.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-7.gz deleted file mode 100644 index 8179eef636a..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-7.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-8.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-8.gz deleted file mode 100644 index 7012113591e..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-8.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-9.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-9.gz deleted file mode 100644 index 8ede7e63fb3..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_07-9.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-1.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-1.gz deleted file mode 100644 index abc6970320c..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-1.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-10.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-10.gz deleted file mode 100644 index 286c4ad1d08..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-10.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-11.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-11.gz deleted file mode 100644 index a896d25e50f..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-11.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-12.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-12.gz deleted file mode 100644 index c6a7dc6500a..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-12.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-13.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-13.gz deleted file mode 100644 index 1b7f95e7135..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-13.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-14.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-14.gz deleted file mode 100644 index 3908509cbe0..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-14.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-15.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-15.gz deleted file mode 100644 index 4063ac4e710..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-15.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-16.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-16.gz deleted file mode 100644 index d68ffffa6e1..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-16.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-17.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-17.gz deleted file mode 100644 index d2b3c80e99d..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-17.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-18.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-18.gz deleted file mode 100644 index 1eb490fe1c1..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-18.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-19.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-19.gz deleted file mode 100644 index 00901ba0743..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-19.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-2.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-2.gz deleted file mode 100644 index e676105c4eb..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-2.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-20.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-20.gz deleted file mode 100644 index 5eca03fa280..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-20.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-21.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-21.gz deleted file mode 100644 index 9226c18a0dd..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-21.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-22.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-22.gz deleted file mode 100644 index 165f22bc189..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-22.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-23.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-23.gz deleted file mode 100644 index 079663cc98b..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-23.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-24.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-24.gz deleted file mode 100644 index 5ee9d98b806..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-24.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-25.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-25.gz deleted file mode 100644 index e6bcb1da7e7..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-25.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-26.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-26.gz deleted file mode 100644 index de7fef629db..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-26.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-27.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-27.gz deleted file mode 100644 index fb16a69c3fa..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-27.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-28.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-28.gz deleted file mode 100644 index eb7616b7e10..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-28.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-29.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-29.gz deleted file mode 100644 index 052d48f36ae..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-29.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-3.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-3.gz deleted file mode 100644 index 18dac25f64c..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-3.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-4.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-4.gz deleted file mode 100644 index e12a936c76b..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-4.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-5.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-5.gz deleted file mode 100644 index 660c8fa933e..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-5.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-6.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-6.gz deleted file mode 100644 index 60620e3c5bd..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-6.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-7.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-7.gz deleted file mode 100644 index 4061c2f12da..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-7.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-8.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-8.gz deleted file mode 100644 index 22633916969..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-8.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-9.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-9.gz deleted file mode 100644 index 7745f89256d..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_08-9.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-1.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-1.gz deleted file mode 100644 index a619cceb805..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-1.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-10.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-10.gz deleted file mode 100644 index 3ea73de625f..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-10.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-11.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-11.gz deleted file mode 100644 index 24d1a2c9951..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-11.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-12.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-12.gz deleted file mode 100644 index fa8c7c772f1..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-12.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-13.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-13.gz deleted file mode 100644 index 0be4d8ab89c..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-13.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-14.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-14.gz deleted file mode 100644 index f28ca6cf391..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-14.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-15.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-15.gz deleted file mode 100644 index 6f7f91865f2..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-15.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-16.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-16.gz deleted file mode 100644 index 0b4cf75593e..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-16.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-17.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-17.gz deleted file mode 100644 index 9e55730b855..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-17.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-18.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-18.gz deleted file mode 100644 index a69c3f593fe..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-18.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-19.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-19.gz deleted file mode 100644 index bc554f12b58..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-19.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-2.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-2.gz deleted file mode 100644 index 18b9ac753e7..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-2.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-20.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-20.gz deleted file mode 100644 index 2da4fedeb8a..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-20.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-21.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-21.gz deleted file mode 100644 index f4d6b3ecd7d..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-21.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-22.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-22.gz deleted file mode 100644 index 336e7cc504c..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-22.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-23.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-23.gz deleted file mode 100644 index cfda7ec248b..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-23.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-24.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-24.gz deleted file mode 100644 index c4e15c96dfd..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-24.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-25.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-25.gz deleted file mode 100644 index da0ea632bff..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-25.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-26.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-26.gz deleted file mode 100644 index ab275afd492..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-26.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-27.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-27.gz deleted file mode 100644 index 92273763235..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-27.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-28.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-28.gz deleted file mode 100644 index 3188962f225..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-28.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-29.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-29.gz deleted file mode 100644 index 8fa0ab8aac4..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-29.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-3.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-3.gz deleted file mode 100644 index e61a84ff96e..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-3.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-30 b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-30 deleted file mode 100644 index 8d1c8b69c3f..00000000000 --- a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-30 +++ /dev/null @@ -1 +0,0 @@ - diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-4.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-4.gz deleted file mode 100644 index 5b9f041bf2d..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-4.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-5.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-5.gz deleted file mode 100644 index 5b4d12339e3..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-5.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-6.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-6.gz deleted file mode 100644 index d88f76ca9e8..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-6.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-7.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-7.gz deleted file mode 100644 index ca0a93de2fc..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-7.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-8.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-8.gz deleted file mode 100644 index ae1fd86024a..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-8.gz and /dev/null differ diff --git a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-9.gz b/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-9.gz deleted file mode 100644 index 427327e7abf..00000000000 Binary files a/log4j-core-test/src/test/resources/rolloverPath/log4j.txt.20170112_09-9.gz and /dev/null differ diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml index b75b0f94f36..0062f543ff6 100644 --- a/log4j-core/pom.xml +++ b/log4j-core/pom.xml @@ -44,7 +44,6 @@ org.jspecify.*;resolution:=optional, - org.apache.commons.compress.*;resolution:=optional, org.fusesource.jansi;resolution:=optional, @@ -79,6 +78,7 @@ jspecify provided + org.osgi org.osgi.framework @@ -101,13 +101,6 @@ log4j-plugins - - - org.apache.commons - commons-compress - true - - org.fusesource.jansi diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java index ff44690a00f..0082a06d2e8 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java @@ -19,7 +19,6 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; -import java.util.zip.Deflater; import org.apache.logging.log4j.core.Appender; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.Layout; @@ -126,12 +125,10 @@ public RollingFileAppender build() { if (strategy == null) { if (fileName != null) { strategy = DefaultRolloverStrategy.newBuilder() - .setCompressionLevelStr(String.valueOf(Deflater.DEFAULT_COMPRESSION)) .setConfig(getConfiguration()) .build(); } else { strategy = DirectWriteRolloverStrategy.newBuilder() - .setCompressionLevelStr(String.valueOf(Deflater.DEFAULT_COMPRESSION)) .setConfig(getConfiguration()) .build(); } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java index 21ea6d29921..5957b9861d9 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java @@ -19,7 +19,6 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; -import java.util.zip.Deflater; import org.apache.logging.log4j.core.Appender; import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.Layout; @@ -97,12 +96,10 @@ public RollingRandomAccessFileAppender build() { if (strategy == null) { if (fileName != null) { strategy = DefaultRolloverStrategy.newBuilder() - .setCompressionLevelStr(String.valueOf(Deflater.DEFAULT_COMPRESSION)) .setConfig(getConfiguration()) .build(); } else { strategy = DirectWriteRolloverStrategy.newBuilder() - .setCompressionLevelStr(String.valueOf(Deflater.DEFAULT_COMPRESSION)) .setConfig(getConfiguration()) .build(); } @@ -157,7 +154,6 @@ public RollingRandomAccessFileAppender build() { filePattern, isIgnoreExceptions(), immediateFlush, - bufferSize, advertise ? getConfiguration().getAdvertiser() : null); } @@ -226,7 +222,6 @@ private RollingRandomAccessFileAppender( final String filePattern, final boolean ignoreExceptions, final boolean immediateFlush, - final int bufferSize, final Advertiser advertiser) { super(name, layout, filter, ignoreExceptions, immediateFlush, null, manager); if (advertiser != null) { diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/AbstractRolloverStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/AbstractRolloverStrategy.java index 406508c98f9..873f9f8fbad 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/AbstractRolloverStrategy.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/AbstractRolloverStrategy.java @@ -32,6 +32,8 @@ import org.apache.logging.log4j.LoggingException; import org.apache.logging.log4j.core.appender.rolling.action.Action; import org.apache.logging.log4j.core.appender.rolling.action.CompositeAction; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactory; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactoryProvider; import org.apache.logging.log4j.core.lookup.StrSubstitutor; import org.apache.logging.log4j.core.pattern.NotANumber; import org.apache.logging.log4j.status.StatusLogger; @@ -48,9 +50,12 @@ public abstract class AbstractRolloverStrategy implements RolloverStrategy { public static final Pattern PATTERN_COUNTER = Pattern.compile(".*%(?0)?(?\\d+)?i.*"); + private final CompressActionFactoryProvider compressActionFactoryProvider; protected final StrSubstitutor strSubstitutor; - protected AbstractRolloverStrategy(final StrSubstitutor strSubstitutor) { + protected AbstractRolloverStrategy( + CompressActionFactoryProvider compressActionFactoryProvider, final StrSubstitutor strSubstitutor) { + this.compressActionFactoryProvider = compressActionFactoryProvider; this.strSubstitutor = strSubstitutor; } @@ -71,13 +76,9 @@ protected Action merge(final Action compressAction, final List custom, f return new CompositeAction(all, stopOnError); } - protected int suffixLength(final String lowFilename) { - for (final FileExtension extension : FileExtension.values()) { - if (extension.isExtensionFor(lowFilename)) { - return extension.length(); - } - } - return 0; + protected int suffixLength(final String fileName) { + CompressActionFactory factory = compressActionFactoryProvider.createFactoryForFileName(fileName); + return factory != null ? factory.getExtension().length() : 0; } protected SortedMap getEligibleFiles(final RollingFileManager manager) { 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 24f415b56bf..eea3bdc77ff 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 @@ -27,9 +27,10 @@ import java.util.Map; import java.util.SortedMap; import java.util.concurrent.TimeUnit; -import java.util.zip.Deflater; import org.apache.logging.log4j.core.appender.rolling.action.Action; import org.apache.logging.log4j.core.appender.rolling.action.CompositeAction; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactory; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactoryProvider; import org.apache.logging.log4j.core.appender.rolling.action.FileRenameAction; import org.apache.logging.log4j.core.appender.rolling.action.PathCondition; import org.apache.logging.log4j.core.appender.rolling.action.PosixViewAttributeAction; @@ -37,7 +38,6 @@ import org.apache.logging.log4j.core.config.NullConfiguration; import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; import org.apache.logging.log4j.core.lookup.StrSubstitutor; -import org.apache.logging.log4j.core.util.Integers; import org.apache.logging.log4j.plugins.Configurable; import org.apache.logging.log4j.plugins.Plugin; import org.apache.logging.log4j.plugins.PluginBuilderAttribute; @@ -97,9 +97,6 @@ public static class Builder implements org.apache.logging.log4j.plugins.util.Bui @PluginBuilderAttribute("fileIndex") private String fileIndex; - @PluginBuilderAttribute("compressionLevel") - private String compressionLevelStr; - @PluginElement("Actions") private Action[] customActions; @@ -136,15 +133,13 @@ public DefaultRolloverStrategy build() { if (max != null) { maxIndex = Integer.parseInt(max.trim()); if (maxIndex < minIndex) { - maxIndex = minIndex < DEFAULT_WINDOW_SIZE ? DEFAULT_WINDOW_SIZE : minIndex; + maxIndex = Math.max(minIndex, DEFAULT_WINDOW_SIZE); LOGGER.error("Maximum window size must be greater than the minimum windows size. Set to " + maxIndex); } } } - final String trimmedCompressionLevelStr = - compressionLevelStr != null ? compressionLevelStr.trim() : compressionLevelStr; - final int compressionLevel = Integers.parseInt(trimmedCompressionLevelStr, Deflater.DEFAULT_COMPRESSION); + // The config object can be null only in tests final Configuration configuration = config != null ? config : new NullConfiguration(); final StrSubstitutor nonNullStrSubstitutor = configuration.getStrSubstitutor(); @@ -152,7 +147,6 @@ public DefaultRolloverStrategy build() { minIndex, maxIndex, useMax, - compressionLevel, nonNullStrSubstitutor, customActions, stopCustomActionsOnError, @@ -206,21 +200,6 @@ public Builder setFileIndex(final String fileIndex) { return this; } - public String getCompressionLevelStr() { - return compressionLevelStr; - } - - /** - * Defines compression level. - * - * @param compressionLevelStr The compression level, 0 (less) through 9 (more); applies only to ZIP files. - * @return This builder for chaining convenience - */ - public Builder setCompressionLevelStr(final String compressionLevelStr) { - this.compressionLevelStr = compressionLevelStr; - return this; - } - public Action[] getCustomActions() { return customActions; } @@ -298,7 +277,6 @@ public static Builder newBuilder() { private final int minIndex; private final boolean useMax; - private final int compressionLevel; private final List customActions; private final boolean stopCustomActionsOnError; private final PatternProcessor tempCompressedFilePattern; @@ -313,32 +291,26 @@ public static Builder newBuilder() { * @param tempCompressedFilePatternString File pattern of the working file * used during compression, if null no temporary file are used */ - protected DefaultRolloverStrategy( + private DefaultRolloverStrategy( final int minIndex, final int maxIndex, final boolean useMax, - final int compressionLevel, final StrSubstitutor strSubstitutor, final Action[] customActions, final boolean stopCustomActionsOnError, final String tempCompressedFilePatternString, final Configuration configuration) { - super(strSubstitutor); + super(CompressActionFactoryProvider.newInstance(configuration), strSubstitutor); this.minIndex = minIndex; this.maxIndex = maxIndex; this.useMax = useMax; - this.compressionLevel = compressionLevel; this.stopCustomActionsOnError = stopCustomActionsOnError; - this.customActions = customActions == null ? Collections.emptyList() : Arrays.asList(customActions); + this.customActions = customActions == null ? Collections.emptyList() : Arrays.asList(customActions); this.tempCompressedFilePattern = tempCompressedFilePatternString != null ? new PatternProcessor(configuration, tempCompressedFilePatternString) : null; } - public int getCompressionLevel() { - return this.compressionLevel; - } - public List getCustomActions() { return customActions; } @@ -423,9 +395,9 @@ private int purgeAscending(final int lowIndex, final int highIndex, final Rollin } } - return eligibleFiles.size() > 0 - ? (eligibleFiles.lastKey() < highIndex ? eligibleFiles.lastKey() + 1 : highIndex) - : lowIndex; + return eligibleFiles.isEmpty() + ? lowIndex + : (eligibleFiles.lastKey() < highIndex ? eligibleFiles.lastKey() + 1 : highIndex); } /** @@ -499,7 +471,7 @@ public RolloverDescription rollover(final RollingFileManager manager) throws Sec final StringBuilder buf = new StringBuilder(255); if (minIndex == Integer.MIN_VALUE) { final SortedMap eligibleFiles = getEligibleFiles(manager); - fileIndex = eligibleFiles.size() > 0 ? eligibleFiles.lastKey() + 1 : 1; + fileIndex = eligibleFiles.isEmpty() ? 1 : eligibleFiles.lastKey() + 1; manager.getPatternProcessor().formatFileName(strSubstitutor, buf, fileIndex); } else { if (maxIndex < 0) { @@ -523,10 +495,12 @@ public RolloverDescription rollover(final RollingFileManager manager) throws Sec final String compressedName = renameTo; Action compressAction = null; - final FileExtension fileExtension = manager.getFileExtension(); - if (fileExtension != null) { + final CompressActionFactory compressActionFactory = manager.getCompressActionFactory(); + if (compressActionFactory != null) { final File renameToFile = new File(renameTo); - renameTo = renameTo.substring(0, renameTo.length() - fileExtension.length()); + // Without dot + extension + renameTo = renameTo.substring( + 0, renameTo.length() - compressActionFactory.getExtension().length()); if (tempCompressedFilePattern != null) { buf.delete(0, buf.length()); tempCompressedFilePattern.formatFileName(strSubstitutor, buf, fileIndex); @@ -538,11 +512,11 @@ public RolloverDescription rollover(final RollingFileManager manager) throws Sec } compressAction = new CompositeAction( Arrays.asList( - fileExtension.createCompressAction(renameTo, tmpCompressedName, true, compressionLevel), + compressActionFactory.createCompressAction(renameTo, tmpCompressedName, Map.of()), new FileRenameAction(tmpCompressedNameFile, renameToFile, true)), true); } else { - compressAction = fileExtension.createCompressAction(renameTo, compressedName, true, compressionLevel); + compressAction = compressActionFactory.createCompressAction(renameTo, compressedName, Map.of()); } } 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 b95c802dcdd..82711b38085 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 @@ -24,18 +24,19 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.SortedMap; import java.util.concurrent.TimeUnit; -import java.util.zip.Deflater; import org.apache.logging.log4j.core.appender.rolling.action.Action; import org.apache.logging.log4j.core.appender.rolling.action.CompositeAction; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactory; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactoryProvider; import org.apache.logging.log4j.core.appender.rolling.action.FileRenameAction; import org.apache.logging.log4j.core.appender.rolling.action.PathCondition; import org.apache.logging.log4j.core.appender.rolling.action.PosixViewAttributeAction; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; import org.apache.logging.log4j.core.lookup.StrSubstitutor; -import org.apache.logging.log4j.core.util.Integers; import org.apache.logging.log4j.plugins.Configurable; import org.apache.logging.log4j.plugins.Plugin; import org.apache.logging.log4j.plugins.PluginBuilderAttribute; @@ -67,9 +68,6 @@ public static class Builder implements org.apache.logging.log4j.plugins.util.Bui @PluginBuilderAttribute("maxFiles") private String maxFiles; - @PluginBuilderAttribute("compressionLevel") - private String compressionLevelStr; - @PluginElement("Actions") private Action[] customActions; @@ -94,10 +92,8 @@ public DirectWriteRolloverStrategy build() { maxIndex = DEFAULT_MAX_FILES; } } - final int compressionLevel = Integers.parseInt(compressionLevelStr, Deflater.DEFAULT_COMPRESSION); return new DirectWriteRolloverStrategy( maxIndex, - compressionLevel, config.getStrSubstitutor(), customActions, stopCustomActionsOnError, @@ -120,21 +116,6 @@ public Builder setMaxFiles(final String maxFiles) { return this; } - public String getCompressionLevelStr() { - return compressionLevelStr; - } - - /** - * Defines compression level. - * - * @param compressionLevelStr The compression level, 0 (less) through 9 (more); applies only to ZIP files. - * @return This builder for chaining convenience - */ - public Builder setCompressionLevelStr(final String compressionLevelStr) { - this.compressionLevelStr = compressionLevelStr; - return this; - } - public Action[] getCustomActions() { return customActions; } @@ -206,7 +187,6 @@ public static Builder newBuilder() { */ private final int maxFiles; - private final int compressionLevel; private final List customActions; private final boolean stopCustomActionsOnError; private volatile String currentFileName; @@ -222,28 +202,22 @@ public static Builder newBuilder() { * @param tempCompressedFilePatternString File pattern of the working file * used during compression, if null no temporary file are used */ - protected DirectWriteRolloverStrategy( + private DirectWriteRolloverStrategy( final int maxFiles, - final int compressionLevel, final StrSubstitutor strSubstitutor, final Action[] customActions, final boolean stopCustomActionsOnError, final String tempCompressedFilePatternString, final Configuration configuration) { - super(strSubstitutor); + super(CompressActionFactoryProvider.newInstance(configuration), strSubstitutor); this.maxFiles = maxFiles; - this.compressionLevel = compressionLevel; this.stopCustomActionsOnError = stopCustomActionsOnError; - this.customActions = customActions == null ? Collections.emptyList() : Arrays.asList(customActions); + this.customActions = customActions == null ? Collections.emptyList() : Arrays.asList(customActions); this.tempCompressedFilePattern = tempCompressedFilePatternString != null ? new PatternProcessor(configuration, tempCompressedFilePatternString) : null; } - public int getCompressionLevel() { - return this.compressionLevel; - } - public List getCustomActions() { return customActions; } @@ -273,21 +247,20 @@ private int purge(final RollingFileManager manager) { break; } } - return eligibleFiles.size() > 0 ? eligibleFiles.lastKey() : 1; + return eligibleFiles.isEmpty() ? 1 : eligibleFiles.lastKey(); } @Override public String getCurrentFileName(final RollingFileManager manager) { if (currentFileName == null) { final SortedMap eligibleFiles = getEligibleFiles(manager); - final int fileIndex = eligibleFiles.size() > 0 ? (nextIndex > 0 ? nextIndex : eligibleFiles.lastKey()) : 1; + final int fileIndex = eligibleFiles.isEmpty() ? 1 : (nextIndex > 0 ? nextIndex : eligibleFiles.lastKey()); final StringBuilder buf = new StringBuilder(255); // LOG4J2-3339 - Always use the current time for new direct write files. manager.getPatternProcessor().setCurrentFileTime(System.currentTimeMillis()); manager.getPatternProcessor().formatFileName(strSubstitutor, buf, true, fileIndex); final int suffixLength = suffixLength(buf.toString()); - final String name = suffixLength > 0 ? buf.substring(0, buf.length() - suffixLength) : buf.toString(); - currentFileName = name; + currentFileName = suffixLength > 0 ? buf.substring(0, buf.length() - suffixLength) : buf.toString(); } return currentFileName; } @@ -324,9 +297,9 @@ public RolloverDescription rollover(final RollingFileManager manager) throws Sec String compressedName = sourceName; currentFileName = null; nextIndex = fileIndex + 1; - final FileExtension fileExtension = manager.getFileExtension(); - if (fileExtension != null) { - compressedName += fileExtension.getExtension(); + final CompressActionFactory compressActionFactory = manager.getCompressActionFactory(); + if (compressActionFactory != null) { + compressedName += compressActionFactory.getExtension(); if (tempCompressedFilePattern != null) { final StringBuilder buf = new StringBuilder(); tempCompressedFilePattern.formatFileName(strSubstitutor, buf, fileIndex); @@ -338,12 +311,11 @@ public RolloverDescription rollover(final RollingFileManager manager) throws Sec } compressAction = new CompositeAction( Arrays.asList( - fileExtension.createCompressAction( - sourceName, tmpCompressedName, true, compressionLevel), + compressActionFactory.createCompressAction(sourceName, tmpCompressedName, Map.of()), new FileRenameAction(tmpCompressedNameFile, new File(compressedName), true)), true); } else { - compressAction = fileExtension.createCompressAction(sourceName, compressedName, true, compressionLevel); + compressAction = compressActionFactory.createCompressAction(sourceName, compressedName, Map.of()); } } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/FileExtension.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/FileExtension.java deleted file mode 100644 index cefb88e5a21..00000000000 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/FileExtension.java +++ /dev/null @@ -1,149 +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.rolling; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import java.io.File; -import java.util.Objects; -import org.apache.logging.log4j.core.appender.rolling.action.Action; -import org.apache.logging.log4j.core.appender.rolling.action.CommonsCompressAction; -import org.apache.logging.log4j.core.appender.rolling.action.GzCompressAction; -import org.apache.logging.log4j.core.appender.rolling.action.ZipCompressAction; - -/** - * Enumerates over supported file extensions for compression. - */ -public enum FileExtension { - ZIP(".zip") { - @Override - Action createCompressAction( - final String renameTo, - final String compressedName, - final boolean deleteSource, - final int compressionLevel) { - return new ZipCompressAction(source(renameTo), target(compressedName), deleteSource, compressionLevel); - } - }, - GZ(".gz") { - @Override - Action createCompressAction( - final String renameTo, - final String compressedName, - final boolean deleteSource, - final int compressionLevel) { - return new GzCompressAction(source(renameTo), target(compressedName), deleteSource, compressionLevel); - } - }, - BZIP2(".bz2") { - @Override - Action createCompressAction( - final String renameTo, - final String compressedName, - final boolean deleteSource, - final int compressionLevel) { - // One of "gz", "bzip2", "xz", "pack200", or "deflate". - return new CommonsCompressAction("bzip2", source(renameTo), target(compressedName), deleteSource); - } - }, - DEFLATE(".deflate") { - @Override - Action createCompressAction( - final String renameTo, - final String compressedName, - final boolean deleteSource, - final int compressionLevel) { - // One of "gz", "bzip2", "xz", "pack200", or "deflate". - return new CommonsCompressAction("deflate", source(renameTo), target(compressedName), deleteSource); - } - }, - PACK200(".pack200") { - @Override - Action createCompressAction( - final String renameTo, - final String compressedName, - final boolean deleteSource, - final int compressionLevel) { - // One of "gz", "bzip2", "xz", "pack200", or "deflate". - return new CommonsCompressAction("pack200", source(renameTo), target(compressedName), deleteSource); - } - }, - XZ(".xz") { - @Override - Action createCompressAction( - final String renameTo, - final String compressedName, - final boolean deleteSource, - final int compressionLevel) { - // One of "gz", "bzip2", "xz", "pack200", or "deflate". - return new CommonsCompressAction("xz", source(renameTo), target(compressedName), deleteSource); - } - }; - - public static FileExtension lookup(final String fileExtension) { - for (final FileExtension ext : values()) { - if (ext.isExtensionFor(fileExtension)) { - return ext; - } - } - return null; - } - - public static FileExtension lookupForFile(final String fileName) { - for (final FileExtension ext : values()) { - if (fileName.endsWith(ext.extension)) { - return ext; - } - } - return null; - } - - private final String extension; - - FileExtension(final String extension) { - Objects.requireNonNull(extension, "extension"); - this.extension = extension; - } - - abstract Action createCompressAction( - String renameTo, String compressedName, boolean deleteSource, int compressionLevel); - - String getExtension() { - return extension; - } - - boolean isExtensionFor(final String s) { - return s.endsWith(this.extension); - } - - int length() { - return extension.length(); - } - - @SuppressFBWarnings( - value = "PATH_TRAVERSAL_IN", - justification = "The name of the accessed files is based on a configuration value.") - File source(final String fileName) { - return new File(fileName); - } - - @SuppressFBWarnings( - value = "PATH_TRAVERSAL_IN", - justification = "The name of the accessed files is based on a configuration value.") - File target(final String fileName) { - return new File(fileName); - } -} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java index 05dd3175c1c..47a529b82a6 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/PatternProcessor.java @@ -23,6 +23,8 @@ import java.util.List; import java.util.TimeZone; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactory; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactoryProvider; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.lookup.StrSubstitutor; import org.apache.logging.log4j.core.pattern.ArrayPatternConverter; @@ -52,7 +54,7 @@ public class PatternProcessor { private final ArrayPatternConverter[] patternConverters; private final FormattingInfo[] patternFields; - private final FileExtension fileExtension; + private final CompressActionFactory compressActionFactory; private long prevFileTime = 0; private long nextFileTime = 0; @@ -87,7 +89,8 @@ public PatternProcessor(final Configuration configuration, final String pattern) patternFields = fields.toArray(FormattingInfo[]::new); patternConverters = converters.stream().map(ArrayPatternConverter.class::cast).toArray(ArrayPatternConverter[]::new); - this.fileExtension = FileExtension.lookupForFile(pattern); + compressActionFactory = + CompressActionFactoryProvider.newInstance(configuration).createFactoryForFileName(pattern); for (final ArrayPatternConverter converter : patternConverters) { // TODO: extract common interface @@ -145,8 +148,8 @@ public void setPrevFileTime(final long prevFileTime) { this.prevFileTime = prevFileTime; } - public FileExtension getFileExtension() { - return fileExtension; + public CompressActionFactory getCompressActionFactory() { + return compressActionFactory; } /** diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java index c613fcf5b39..28da0d0c924 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/RollingFileManager.java @@ -43,6 +43,7 @@ import org.apache.logging.log4j.core.appender.ManagerFactory; import org.apache.logging.log4j.core.appender.rolling.action.AbstractAction; import org.apache.logging.log4j.core.appender.rolling.action.Action; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactory; import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.util.Constants; import org.apache.logging.log4j.core.util.FileUtils; @@ -266,8 +267,8 @@ public boolean isDirectWrite() { return directWrite; } - public FileExtension getFileExtension() { - return patternProcessor.getFileExtension(); + public CompressActionFactory getCompressActionFactory() { + return patternProcessor.getCompressActionFactory(); } // override to make visible for unit tests diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/AbstractCompressAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/AbstractCompressAction.java new file mode 100644 index 00000000000..8c58ee65ba1 --- /dev/null +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/AbstractCompressAction.java @@ -0,0 +1,93 @@ +/* + * 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.rolling.action; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; + +public abstract class AbstractCompressAction extends AbstractAction { + + protected static final int BUF_SIZE = 8192; + + /** + * Source file. + */ + private final Path source; + + /** + * Destination file. + */ + private final Path destination; + + public AbstractCompressAction(final Path source, final Path destination) { + this.source = Objects.requireNonNull(source, "source"); + this.destination = Objects.requireNonNull(destination, "destination"); + } + + /** + * The name of this compression algorithm. + *

+ * When applicable, it should correspond to the name used by Apache Commons Compress. + *

+ */ + protected abstract String getAlgorithmName(); + + /** + * Wraps an output stream into a compressing output stream. + * + * @param stream The stream to wrap. + * @return A compressing output stream. + */ + protected abstract OutputStream wrapOutputStream(final OutputStream stream) throws IOException; + + @Override + public boolean execute() throws IOException { + if (Files.exists(source)) { + LOGGER.debug("Starting {} compression from {} to {}.", getAlgorithmName(), source, destination); + try (final OutputStream output = wrapOutputStream(Files.newOutputStream(destination))) { + Files.copy(source, output); + } + LOGGER.debug("Finished {} compression from {} to {}.", getAlgorithmName(), source, destination); + try { + Files.delete(source); + LOGGER.debug("File {} deleted successfully.", source); + } catch (final IOException ioe) { + LOGGER.warn("Unable to delete {}.", source, ioe); + } + return true; + } + return false; + } + + /** + * Capture exception. + * + * @param ex exception. + */ + @Override + protected void reportException(final Exception ex) { + LOGGER.warn("Exception during compression of '{}'.", source, ex); + } + + @Override + public String toString() { + return getClass().getSimpleName() + '[' + source + " to " + destination + ']'; + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CommonsCompressAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CommonsCompressAction.java deleted file mode 100644 index 526e0b9e56d..00000000000 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CommonsCompressAction.java +++ /dev/null @@ -1,163 +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.rolling.action; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.util.Objects; -import org.apache.commons.compress.compressors.CompressorException; -import org.apache.commons.compress.compressors.CompressorStreamFactory; -import org.apache.commons.compress.utils.IOUtils; - -/** - * Compresses a file using bzip2 compression. - */ -public final class CommonsCompressAction extends AbstractAction { - - private static final int BUF_SIZE = 8192; - - /** - * Compressor name. One of "gz", "bzip2", "xz", "pack200" or "deflate". - */ - private final String name; - - /** - * Source file. - */ - private final File source; - - /** - * Destination file. - */ - private final File destination; - - /** - * If true, attempt to delete file on completion. - */ - private final boolean deleteSource; - - /** - * Creates new instance of Bzip2CompressAction. - * - * @param name the compressor name. One of "gz", "bzip2", "xz", "pack200", or "deflate". - * @param source file to compress, may not be null. - * @param destination compressed file, may not be null. - * @param deleteSource if true, attempt to delete file on completion. Failure to delete does not cause an exception - * to be thrown or affect return value. - */ - public CommonsCompressAction( - final String name, final File source, final File destination, final boolean deleteSource) { - Objects.requireNonNull(source, "source"); - Objects.requireNonNull(destination, "destination"); - this.name = name; - this.source = source; - this.destination = destination; - this.deleteSource = deleteSource; - } - - /** - * Compresses. - * - * @return true if successfully compressed. - * @throws IOException on IO exception. - */ - @Override - public boolean execute() throws IOException { - return execute(name, source, destination, deleteSource); - } - - /** - * Compresses a file. - * - * @param name the compressor name, i.e. "gz", "bzip2", "xz", "pack200", or "deflate". - * @param source file to compress, may not be null. - * @param destination compressed file, may not be null. - * @param deleteSource if true, attempt to delete file on completion. Failure to delete does not cause an exception - * to be thrown or affect return value. - * - * @return true if source file compressed. - * @throws IOException on IO exception. - */ - public static boolean execute( - final String name, final File source, final File destination, final boolean deleteSource) - throws IOException { - if (!source.exists()) { - return false; - } - LOGGER.debug("Starting {} compression of {}", name, source.getPath()); - try (final FileInputStream input = new FileInputStream(source); - final FileOutputStream fileOutput = new FileOutputStream(destination); - final BufferedOutputStream output = new BufferedOutputStream( - new CompressorStreamFactory().createCompressorOutputStream(name, fileOutput))) { - IOUtils.copy(input, output, BUF_SIZE); - LOGGER.debug("Finished {} compression of {}", name, source.getPath()); - } catch (final CompressorException e) { - throw new IOException(e); - } - - if (deleteSource) { - try { - if (Files.deleteIfExists(source.toPath())) { - LOGGER.debug("Deleted {}", source.toString()); - } else { - LOGGER.warn( - "Unable to delete {} after {} compression. File did not exist", source.toString(), name); - } - } catch (final Exception ex) { - LOGGER.warn("Unable to delete {} after {} compression, {}", source.toString(), name, ex.getMessage()); - } - } - - return true; - } - - /** - * Reports exception. - * - * @param ex exception. - */ - @Override - protected void reportException(final Exception ex) { - LOGGER.warn("Exception during " + name + " compression of '" + source.toString() + "'.", ex); - } - - @Override - public String toString() { - return CommonsCompressAction.class.getSimpleName() + '[' + source + " to " + destination + ", deleteSource=" - + deleteSource + ']'; - } - - public String getName() { - return name; - } - - public File getSource() { - return source; - } - - public File getDestination() { - return destination; - } - - public boolean isDeleteSource() { - return deleteSource; - } -} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CompressActionFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CompressActionFactory.java new file mode 100644 index 00000000000..3cc48d41e9e --- /dev/null +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CompressActionFactory.java @@ -0,0 +1,76 @@ +/* + * 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.rolling.action; + +import java.nio.file.Path; +import java.util.Map; +import java.util.Objects; +import org.apache.logging.log4j.core.util.FileUtils; +import org.apache.logging.log4j.core.util.NetUtils; +import org.jspecify.annotations.NullMarked; + +/** + * A factory to produce actions that compress log files. + */ +@NullMarked +public interface CompressActionFactory { + + /** + * Returns an action that compresses a file. + * + * @param source The location of the file to compress. + * @param destination The location of the compressed file. + * @param options Compression options to pass to the compression library. + * @return An action the compresses the source file. + */ + Action createCompressAction(Path source, Path destination, Map options); + + /** + * Returns an action that compresses a file. + * + * @param source The location of the file to compress. + * @param destination The location of the compressed file. + * @param options Compression options to pass to the compression library. + * @return An action the compresses the source file. + */ + default Action createCompressAction(String source, String destination, Map options) { + return createCompressAction(toPath(source), toPath(destination), options); + } + + private static Path toPath(final String path) { + return FileUtils.pathFromUri(NetUtils.toURI(Objects.requireNonNull(path))); + } + + /** + * The name of this compression algorithm. + *

+ * When applicable, it should correspond to the name used by Apache Commons Compress. + *

+ */ + String getAlgorithmName(); + + /** + * Returns the natural file extension for this compression algorithm. + *

+ * The extension must start with a dot. + *

+ * @return A file extension. + */ + default String getExtension() { + return "." + getAlgorithmName(); + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CompressActionFactoryProvider.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CompressActionFactoryProvider.java new file mode 100644 index 00000000000..d8118b586c0 --- /dev/null +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/CompressActionFactoryProvider.java @@ -0,0 +1,62 @@ +/* + * 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.rolling.action; + +import org.apache.logging.log4j.core.appender.rolling.action.internal.CompositeCompressActionFactoryProvider; +import org.apache.logging.log4j.core.config.Configuration; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +/** + * Interface for plugins that provide additional compression algorithms. + * + * @since 3.0.0 + */ +@NullMarked +public interface CompressActionFactoryProvider { + + String NAMESPACE = "compress"; + + /** + * Creates the appropriate {@link CompressActionFactory} for the given compression algorithm. + *

+ * When applicable the algorithm should correspond to the name used by Apache Commons Compress. + *

+ * @param algorithm The compression algorithm. + * @return A {@link CompressActionFactory} or {@code null} if the extension is not supported. + */ + @Nullable + CompressActionFactory createFactoryForAlgorithm(String algorithm); + + /** + * Creates the appropriate {@link CompressActionFactory} for the given file name. + * + * @param fileName The file name. + * @return A {@link CompressActionFactory} or {@code null} if the extension is not supported. + */ + default @Nullable CompressActionFactory createFactoryForFileName(String fileName) { + final int idx = fileName.lastIndexOf('.'); + if (idx != -1) { + return createFactoryForAlgorithm(fileName.substring(idx + 1)); + } + return null; + } + + static CompressActionFactoryProvider newInstance(final @Nullable Configuration configuration) { + return new CompositeCompressActionFactoryProvider(configuration); + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/GzCompressAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/GzCompressAction.java deleted file mode 100644 index ccf1898f4f7..00000000000 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/GzCompressAction.java +++ /dev/null @@ -1,166 +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.rolling.action; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Objects; -import java.util.zip.Deflater; -import java.util.zip.GZIPOutputStream; - -/** - * Compresses a file using GZ compression. - */ -public final class GzCompressAction extends AbstractAction { - - private static final int BUF_SIZE = 8192; - - /** - * Source file. - */ - private final File source; - - /** - * Destination file. - */ - private final File destination; - - /** - * If true, attempt to delete file on completion. - */ - private final boolean deleteSource; - - /** - * GZIP compression level to use. - * - * @see Deflater#setLevel(int) - */ - private final int compressionLevel; - - /** - * Create new instance of GzCompressAction. - * - * @param source file to compress, may not be null. - * @param destination compressed file, may not be null. - * @param deleteSource if true, attempt to delete file on completion. Failure to delete - * does not cause an exception to be thrown or affect return value. - * @param compressionLevel - * Gzip deflater compression level. - */ - public GzCompressAction( - final File source, final File destination, final boolean deleteSource, final int compressionLevel) { - Objects.requireNonNull(source, "source"); - Objects.requireNonNull(destination, "destination"); - - this.source = source; - this.destination = destination; - this.deleteSource = deleteSource; - this.compressionLevel = compressionLevel; - } - - /** - * Compress. - * - * @return true if successfully compressed. - * @throws IOException on IO exception. - */ - @Override - public boolean execute() throws IOException { - return execute(source, destination, deleteSource, compressionLevel); - } - - /** - * Compress a file. - * - * @param source file to compress, may not be null. - * @param destination compressed file, may not be null. - * @param deleteSource if true, attempt to delete file on completion. Failure to delete - * does not cause an exception to be thrown or affect return value. - * @param compressionLevel - * Gzip deflater compression level. - * @return true if source file compressed. - * @throws IOException on IO exception. - */ - public static boolean execute( - final File source, final File destination, final boolean deleteSource, final int compressionLevel) - throws IOException { - if (source.exists()) { - try (final FileInputStream fis = new FileInputStream(source); - final OutputStream fos = new FileOutputStream(destination); - final OutputStream gzipOut = - new ConfigurableLevelGZIPOutputStream(fos, BUF_SIZE, compressionLevel); - // Reduce native invocations by buffering data into GZIPOutputStream - final OutputStream os = new BufferedOutputStream(gzipOut, BUF_SIZE)) { - final byte[] inbuf = new byte[BUF_SIZE]; - int n; - - while ((n = fis.read(inbuf)) != -1) { - os.write(inbuf, 0, n); - } - } - - if (deleteSource && !source.delete()) { - LOGGER.warn("Unable to delete {}.", source); - } - - return true; - } - - return false; - } - - private static final class ConfigurableLevelGZIPOutputStream extends GZIPOutputStream { - - ConfigurableLevelGZIPOutputStream(final OutputStream out, final int bufSize, final int level) - throws IOException { - super(out, bufSize); - def.setLevel(level); - } - } - - /** - * Capture exception. - * - * @param ex exception. - */ - @Override - protected void reportException(final Exception ex) { - LOGGER.warn("Exception during compression of '" + source.toString() + "'.", ex); - } - - @Override - public String toString() { - return GzCompressAction.class.getSimpleName() + '[' + source + " to " + destination + ", deleteSource=" - + deleteSource + ']'; - } - - public File getSource() { - return source; - } - - public File getDestination() { - return destination; - } - - public boolean isDeleteSource() { - return deleteSource; - } -} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ZipCompressAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ZipCompressAction.java deleted file mode 100644 index f29a7391ceb..00000000000 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/ZipCompressAction.java +++ /dev/null @@ -1,154 +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.rolling.action; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Objects; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -/** - * Compresses a file using Zip compression. - */ -public final class ZipCompressAction extends AbstractAction { - - private static final int BUF_SIZE = 8192; - - /** - * Source file. - */ - private final File source; - - /** - * Destination file. - */ - private final File destination; - - /** - * If true, attempts to delete file on completion. - */ - private final boolean deleteSource; - - /** - * Compression level. - */ - private final int level; - - /** - * Creates new instance of GzCompressAction. - * - * @param source file to compress, may not be null. - * @param destination compressed file, may not be null. - * @param deleteSource if true, attempt to delete file on completion. Failure to delete does not cause an exception - * to be thrown or affect return value. - * @param level TODO - */ - public ZipCompressAction(final File source, final File destination, final boolean deleteSource, final int level) { - Objects.requireNonNull(source, "source"); - Objects.requireNonNull(destination, "destination"); - - this.source = source; - this.destination = destination; - this.deleteSource = deleteSource; - this.level = level; - } - - /** - * Compresses. - * - * @return true if successfully compressed. - * @throws IOException on IO exception. - */ - @Override - public boolean execute() throws IOException { - return execute(source, destination, deleteSource, level); - } - - /** - * Compresses a file. - * - * @param source file to compress, may not be null. - * @param destination compressed file, may not be null. - * @param deleteSource if true, attempt to delete file on completion. Failure to delete does not cause an exception - * to be thrown or affect return value. - * @param level the compression level - * @return true if source file compressed. - * @throws IOException on IO exception. - */ - public static boolean execute( - final File source, final File destination, final boolean deleteSource, final int level) throws IOException { - if (source.exists()) { - try (final FileInputStream fis = new FileInputStream(source); - final ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(destination))) { - zos.setLevel(level); - - final ZipEntry zipEntry = new ZipEntry(source.getName()); - zos.putNextEntry(zipEntry); - - final byte[] inbuf = new byte[BUF_SIZE]; - int n; - - while ((n = fis.read(inbuf)) != -1) { - zos.write(inbuf, 0, n); - } - } - - if (deleteSource && !source.delete()) { - LOGGER.warn("Unable to delete " + source.toString() + '.'); - } - - return true; - } - - return false; - } - - /** - * Captures exception. - * - * @param ex exception. - */ - @Override - protected void reportException(final Exception ex) { - LOGGER.warn("Exception during compression of '" + source.toString() + "'.", ex); - } - - @Override - public String toString() { - return ZipCompressAction.class.getSimpleName() + '[' + source + " to " + destination + ", level=" + level - + ", deleteSource=" + deleteSource + ']'; - } - - public File getSource() { - return source; - } - - public File getDestination() { - return destination; - } - - public boolean isDeleteSource() { - return deleteSource; - } - - public int getLevel() { - return level; - } -} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/internal/CompositeCompressActionFactoryProvider.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/internal/CompositeCompressActionFactoryProvider.java new file mode 100644 index 00000000000..ec4e7589061 --- /dev/null +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/internal/CompositeCompressActionFactoryProvider.java @@ -0,0 +1,50 @@ +/* + * 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.rolling.action.internal; + +import java.util.List; +import java.util.Objects; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactory; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactoryProvider; +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.plugins.Namespace; +import org.apache.logging.log4j.plugins.di.Key; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +@NullMarked +public class CompositeCompressActionFactoryProvider implements CompressActionFactoryProvider { + + private final List delegates; + + public CompositeCompressActionFactoryProvider(final @Nullable Configuration configuration) { + if (configuration != null) { + delegates = configuration.getComponent(new @Namespace(CompressActionFactoryProvider.NAMESPACE) Key<>() {}); + } else { + delegates = List.of(new JreCompressActionFactoryProvider()); + } + } + + @Override + public @Nullable CompressActionFactory createFactoryForAlgorithm(String extension) { + return delegates.stream() + .map(p -> p.createFactoryForAlgorithm(extension)) + .filter(Objects::nonNull) + .findFirst() + .orElse(null); + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/internal/GzCompressAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/internal/GzCompressAction.java new file mode 100644 index 00000000000..54dd5c1e65e --- /dev/null +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/internal/GzCompressAction.java @@ -0,0 +1,72 @@ +/* + * 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.rolling.action.internal; + +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Path; +import java.util.zip.Deflater; +import java.util.zip.GZIPOutputStream; +import org.apache.logging.log4j.core.appender.rolling.action.AbstractCompressAction; + +/** + * Compresses a file using GZ compression. + */ +public final class GzCompressAction extends AbstractCompressAction { + + /** + * GZIP compression level to use. + * + * @see Deflater#setLevel(int) + */ + private final int compressionLevel; + + /** + * Create new instance of GzCompressAction. + * + * @param source file to compress, may not be null. + * @param destination compressed file, may not be null. + * @param compressionLevel + * Gzip deflater compression level. + */ + public GzCompressAction(final Path source, final Path destination, final int compressionLevel) { + super(source, destination); + this.compressionLevel = compressionLevel; + } + + @Override + protected OutputStream wrapOutputStream(OutputStream stream) throws IOException { + final OutputStream gzipOut = new ConfigurableLevelGZIPOutputStream(stream, BUF_SIZE, compressionLevel); + // Reduce native invocations by buffering data into GZIPOutputStream + return new BufferedOutputStream(gzipOut, BUF_SIZE); + } + + @Override + protected String getAlgorithmName() { + return "GZ"; + } + + private static final class ConfigurableLevelGZIPOutputStream extends GZIPOutputStream { + + ConfigurableLevelGZIPOutputStream(final OutputStream out, final int bufSize, final int level) + throws IOException { + super(out, bufSize); + def.setLevel(level); + } + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/internal/JreCompressActionFactoryProvider.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/internal/JreCompressActionFactoryProvider.java new file mode 100644 index 00000000000..ff5d5c31bef --- /dev/null +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/internal/JreCompressActionFactoryProvider.java @@ -0,0 +1,75 @@ +/* + * 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.rolling.action.internal; + +import java.nio.file.Path; +import java.util.Map; +import java.util.zip.Deflater; +import org.apache.logging.log4j.core.appender.rolling.action.Action; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactory; +import org.apache.logging.log4j.core.appender.rolling.action.CompressActionFactoryProvider; +import org.apache.logging.log4j.plugins.Namespace; +import org.apache.logging.log4j.plugins.Ordered; +import org.apache.logging.log4j.plugins.Plugin; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +@Plugin +@Namespace(CompressActionFactoryProvider.NAMESPACE) +@Ordered(Ordered.LAST) +@NullMarked +public class JreCompressActionFactoryProvider implements CompressActionFactoryProvider { + + @Override + public @Nullable CompressActionFactory createFactoryForAlgorithm(String extension) { + return switch (extension) { + case GzCompressActionFactory.NAME -> new GzCompressActionFactory(); + case ZipCompressActionFactory.NAME -> new ZipCompressActionFactory(); + default -> null; + }; + } + + private static final class GzCompressActionFactory implements CompressActionFactory { + + static final String NAME = "gz"; + + @Override + public Action createCompressAction(Path source, Path destination, Map options) { + return new GzCompressAction(source, destination, Deflater.DEFAULT_COMPRESSION); + } + + @Override + public String getAlgorithmName() { + return NAME; + } + } + + private static final class ZipCompressActionFactory implements CompressActionFactory { + + static final String NAME = "zip"; + + @Override + public Action createCompressAction(Path source, Path destination, Map options) { + return new ZipCompressAction(source, destination, Deflater.DEFAULT_COMPRESSION); + } + + @Override + public String getAlgorithmName() { + return NAME; + } + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/internal/ZipCompressAction.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/internal/ZipCompressAction.java new file mode 100644 index 00000000000..8fef6be0f92 --- /dev/null +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/internal/ZipCompressAction.java @@ -0,0 +1,68 @@ +/* + * 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.rolling.action.internal; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Path; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; +import org.apache.logging.log4j.core.appender.rolling.action.AbstractCompressAction; + +/** + * Compresses a file using Zip compression. + */ +public final class ZipCompressAction extends AbstractCompressAction { + + /** + * The file being compressed. + */ + private final String fileName; + + /** + * Compression level. + */ + private final int compressionLevel; + + /** + * Creates new instance of ZipCompressAction. + * + * @param source file to compress, may not be null. + * @param destination compressed file, may not be null. + * @param compressionLevel + * ZIP deflater compression level + */ + public ZipCompressAction(final Path source, final Path destination, final int compressionLevel) { + super(source, destination); + this.fileName = source.getFileName().toString(); + this.compressionLevel = compressionLevel; + } + + @Override + protected OutputStream wrapOutputStream(OutputStream stream) throws IOException { + final ZipOutputStream zos = new ZipOutputStream(stream); + zos.setLevel(compressionLevel); + final ZipEntry zipEntry = new ZipEntry(fileName); + zos.putNextEntry(zipEntry); + return zos; + } + + @Override + protected String getAlgorithmName() { + return "ZIP"; + } +} 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 6395bab84a0..0d71e40d4c6 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 @@ -25,6 +25,7 @@ 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.GroupPrincipal; import java.nio.file.attribute.PosixFileAttributeView; import java.nio.file.attribute.PosixFilePermission; @@ -90,6 +91,23 @@ public static File fileFromUri(URI uri) { return null; } + /** + * Transforms an {@link URI} into a {@link Path}. + *

+ * + *

+ * @param uri The {@link URI} to transform, never {@code null} + * @return A {@link Path} or {@code null} if the URI does not use a valid {@link java.nio.file.FileSystem} scheme. + */ + public static Path pathFromUri(final URI uri) { + Objects.requireNonNull(uri, "uri"); + if (uri.isAbsolute()) { + return Paths.get(uri); + } else { + return Paths.get(uri.getPath()); + } + } + public static boolean isFile(final URL url) { return url != null && (url.getProtocol().equals(PROTOCOL_FILE) || url.getProtocol().equals(JBOSS_FILE)); diff --git a/log4j-parent/pom.xml b/log4j-parent/pom.xml index 8b020703f63..20022e32cb1 100644 --- a/log4j-parent/pom.xml +++ b/log4j-parent/pom.xml @@ -97,7 +97,6 @@ 4.2.2 2.0b6 1.17.1 - 1.27.1 1.11.0 2.12.0 2.17.0 @@ -147,8 +146,6 @@ 1.7 2.35.2 2.10.0 - 1.10 - 1.5.6-6 - - org.apache.commons - commons-compress - ${commons-compress.version} - - org.apache.commons commons-csv @@ -641,18 +631,6 @@ ${xmlunit.version} - - org.tukaani - xz - ${xz.version} - - - - com.github.luben - zstd-jni - ${zstd.version} - - diff --git a/pom.xml b/pom.xml index 3082f2a4ac5..bf4fa5cb91b 100644 --- a/pom.xml +++ b/pom.xml @@ -233,6 +233,7 @@ log4j-async-logger + log4j-compress log4j-config-jackson log4j-config-properties log4j-config-yaml @@ -338,7 +339,6 @@ true true - 1.27.1 1.11.0 1.3.4 1.2.21 @@ -392,6 +392,12 @@ ${project.version}
+ + org.apache.logging.log4j + log4j-compress + ${project.version} + + org.apache.logging.log4j log4j-config-jackson @@ -782,12 +788,6 @@ - - org.apache.commons - commons-compress - ${site-commons-compress.version} - - org.apache.commons commons-csv diff --git a/src/changelog/.3.x.x/move_commons_compress.xml b/src/changelog/.3.x.x/move_commons_compress.xml new file mode 100644 index 00000000000..79b0edebce9 --- /dev/null +++ b/src/changelog/.3.x.x/move_commons_compress.xml @@ -0,0 +1,7 @@ + + + Split extended compression algorithm support to new `log4j-compress` module. + diff --git a/src/site/antora/antora.tmpl.yml b/src/site/antora/antora.tmpl.yml index 2857611fce0..632124c8676 100644 --- a/src/site/antora/antora.tmpl.yml +++ b/src/site/antora/antora.tmpl.yml @@ -53,7 +53,6 @@ asciidoc: lmax-disruptor-url: "https://lmax-exchange.github.io/disruptor" slf4j-url: "https://www.slf4j.org" # Dependency versions - commons-compress-version: "${site-commons-compress.version}" commons-csv-version: "${site-commons-csv.version}" commons-logging-version: "${site-commons-logging.version}" conversant-version: "${site-conversant.version}" diff --git a/src/site/antora/antora.yml b/src/site/antora/antora.yml index 31a89762fe6..9fbdd43fcac 100644 --- a/src/site/antora/antora.yml +++ b/src/site/antora/antora.yml @@ -53,7 +53,6 @@ asciidoc: lmax-disruptor-url: "https://lmax-exchange.github.io/disruptor/" slf4j-url: "https://www.slf4j.org" # Dependency versions - commons-compress-version: "1.2.3-commons-compress" commons-csv-version: "1.2.3-commons-csv" commons-logging-version: "1.2.3-commons-logging" conversant-version: "1.2.3-conversant" diff --git a/src/site/antora/modules/ROOT/pages/components.adoc b/src/site/antora/modules/ROOT/pages/components.adoc index 97c1f8ccbce..4b99ac7335e 100644 --- a/src/site/antora/modules/ROOT/pages/components.adoc +++ b/src/site/antora/modules/ROOT/pages/components.adoc @@ -53,6 +53,23 @@ See xref:manual/async.adoc[asynchronous loggers] for more details. include::partial$components/log4j-async-logger.adoc[] +[#log4j-compress] +== `log4j-compress` + +[cols="1h,5"] +|=== +| JPMS module +| `org.apache.logging.log4j.compress` +|=== + +The `log4j-compress` artifact provides additional compression algorithms. +Having this artifact in the classpath makes these automatically accessible to +xref:manual/appenders/rolling-file.adoc[]. +See +xref:manual/appenders/rolling-file.adoc#RolloverStrategy-compress-commons[Compressing archived files] for more details. + +include::partial$components/log4j-compress.adoc[] + [#log4j-config-jackson] == `log4j-config-jackson` diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders/rolling-file.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders/rolling-file.adoc index 84a40f21da2..2c43d1457ae 100644 --- a/src/site/antora/modules/ROOT/pages/manual/appenders/rolling-file.adoc +++ b/src/site/antora/modules/ROOT/pages/manual/appenders/rolling-file.adoc @@ -644,13 +644,6 @@ Both rollover strategies support the following configuration parameters: |=== | Attribute | Type | Default value | Description -| [[RolloverStrategy-attr-compressionLevel]]compressionLevel -| `int` -| `7` -| Determine the compression level of archived log files. - -See <> for more details. - | [[RolloverStrategy-attr-tempCompressedFilePattern]]tempCompressedFilePattern | https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html[`Path`] | @@ -926,80 +919,52 @@ When the current log file is archived, the rolling file appender can compress it Compression is activated, based on the extension of the archived file name. The following extensions are recognized: -[cols="1,1,2"] -|=== -| Extension | Supports `compressionLevel` | Description - - -| [[RolloverStrategy-compress-zip]]`.zip` -| {check-mark} -| ZIP archive using the +`.zip`:: +ZIP archive using the https://docs.oracle.com/javase/8/docs/api/java/util/zip/DeflaterOutputStream.html[DEFLATE] -algorithm - -| [[RolloverStrategy-compress-gz]]`.gz` -| {check-mark} -| https://docs.oracle.com/javase/8/docs/api/java/util/zip/GZIPOutputStream.html[GZIP] archive using the DEFLATE algorithm +algorithm. -| [[RolloverStrategy-compress-bz2]]`.bz2`<> -| {x-mark} -|https://commons.apache.org/proper/commons-compress/apidocs/org/apache/commons/compress/compressors/bzip2/BZip2CompressorOutputStream.html[BZip2] algorithm +`.gz`:: +https://docs.oracle.com/javase/8/docs/api/java/util/zip/GZIPOutputStream.html[GZIP] +archive using the DEFLATE algorithm. -| [[RolloverStrategy-compress-deflate]]`.deflate`<> -| {x-mark} -| https://commons.apache.org/proper/commons-compress/apidocs/org/apache/commons/compress/compressors/deflate/DeflateCompressorOutputStream.html[DEFLATE] algorithm - -| [[RolloverStrategy-compress-pack200]]`.pack200`<> -| {x-mark} -| https://commons.apache.org/proper/commons-compress/apidocs/org/apache/commons/compress/compressors/pack200/package-summary.html[Pack200] algorithm +[#RolloverStrategy-compress-commons] +`.`:: ++ +Log4j Core supports all the compression algorithms available through +https://commons.apache.org/proper/commons-compress/index.html[Apache Commons Compress]. +To use these algorithms, an additional dependency is required: ++ +-- +include::partial$features/compression.adoc[] +-- ++ +[NOTE] +==== +Apache Commons Compress currently supports the following values of `algorithmName`: -| [[RolloverStrategy-compress-xz]]`.xz` <> -| {x-mark} -| https://commons.apache.org/proper/commons-compress/apidocs/org/apache/commons/compress/compressors/xz/package-summary.html[XZ] algorithm +* `gzip`, `bzip2`, `deflate`, `snappy-framed`, `lz4-block`, `lz4-framed` are supported without **any** external dependency. +* `lzma`, `.xz` and `.zst` extensions require **additional** dependencies. +See +https://commons.apache.org/proper/commons-compress/index.html[Commons Compress documentation] +for more details. -| [[RolloverStrategy-compress-zst]]`.zst` <> -| {x-mark} -| https://commons.apache.org/proper/commons-compress/apidocs/org/apache/commons/compress/compressors/zstandard/package-summary.html[ZStandard] algorithm +The `pack200` algorithm is not a general purpose compression algorithm and has been disabled. +==== ++ +[TIP] +==== +Support for additional compression algorithms can be obtained by extending Apache Commons Compress. -|=== +See +https://commons.apache.org/proper/commons-compress/examples.html#Extending_Commons_Compress_Compressors[Extending Commons Compress Compressors] for details. +==== If the <> attribute is set, the current log file: * will be compressed and stored in the location given by `tempCompressedFilePattern` * and then it will be moved to the location given by <>. -[[commons-compress-dep]] -^dep^:: -Additional dependencies are required to use these compression algorithms: -+ -[tabs] -==== -Maven:: -+ -[source,xml,subs=+attributes] ----- - - org.apache.commons - commons-compress - {commons-compress-version} - runtime - ----- - -Gradle:: -+ -[source,groovy,subs=+attributes] ----- -runtimeOnly 'org.apache.commons:commons-compress:{commons-compress-version}' ----- - -==== -+ -The `.xz` and `.zst` extensions require **additional** Commons Compress dependencies. -See -https://commons.apache.org/proper/commons-compress/index.html[Commons Compress documentation] -for more details. - [#AbstractPathAction] == Optional actions diff --git a/src/site/antora/modules/ROOT/partials/components/log4j-compress.adoc b/src/site/antora/modules/ROOT/partials/components/log4j-compress.adoc new file mode 100644 index 00000000000..9016f475ec1 --- /dev/null +++ b/src/site/antora/modules/ROOT/partials/components/log4j-compress.adoc @@ -0,0 +1,41 @@ +//// + 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. +//// + +[tabs] +==== +Maven:: ++ +We assume you use xref:components.adoc#log4j-bom[`log4j-bom`] for dependency management. ++ +[source,xml] +---- + + org.apache.logging.log4j + log4j-compress + runtime + +---- + +Gradle:: ++ +We assume you use xref:components.adoc#log4j-bom[`log4j-bom`] for dependency management. ++ +[source,groovy] +---- +runtimeOnly 'org.apache.logging.log4j:log4j-compress' +---- +==== \ No newline at end of file diff --git a/src/site/antora/modules/ROOT/partials/features/compression.adoc b/src/site/antora/modules/ROOT/partials/features/compression.adoc new file mode 100644 index 00000000000..5f3c426f1d9 --- /dev/null +++ b/src/site/antora/modules/ROOT/partials/features/compression.adoc @@ -0,0 +1,21 @@ +//// + 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. +//// + +// This file exists in both the 2.x and 3.x branches. +// It contains the dependencies required to enable advanced compression algorithms. + +include::partial$components/log4j-compress.adoc[] \ No newline at end of file