This is an automated email from the ASF dual-hosted git repository. vy pushed a commit to branch recycler-api-3.x in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit baf4a9bcb29b41422237495bcf7c1ab2db459520 Author: Volkan Yazıcı <[email protected]> AuthorDate: Thu Mar 23 18:14:19 2023 +0100 Merge changes from `main` --- .../logging/log4j/message/MapMessageTest.java | 9 + .../apache/logging/log4j/util/StringBuilders.java | 33 ++- .../log4j/core/filter/CompositeFilterTest.java | 97 ++++--- .../pattern/SimpleLiteralPatternConverterTest.java | 93 ++++--- .../logging/log4j/core/appender/WriterManager.java | 298 ++++++++++----------- .../appender/rolling/action/DeletingVisitor.java | 219 ++++++++------- .../core/appender/rolling/action/PathSorter.java | 53 ++-- .../rolling/action/PathWithAttributes.java | 117 ++++---- .../appender/rolling/action/SortingVisitor.java | 149 +++++------ .../core/async/AsyncLoggerConfigDelegate.java | 131 +++++---- .../async/BasicAsyncLoggerContextSelector.java | 88 +++--- .../log4j/core/config/ReliabilityStrategy.java | 189 +++++++------ .../DefaultComponentAndConfigurationBuilder.java | 94 +++---- .../log4j/core/selector/CoreContextSelectors.java | 62 ++--- .../log4j/core/util/CloseShieldOutputStream.java | 118 ++++---- .../logging/log4j/core/util/CloseShieldWriter.java | 92 +++---- .../apache/logging/log4j/core/util/IOUtils.java | 260 +++++++++--------- .../log4j/jeromq/appender/JeroMqAppender.java | 5 + .../log4j/jeromq/appender/JeroMqManager.java | 16 +- .../log4j/jeromq/appender/JeroMqAppenderTest.java | 21 +- .../log4j/layout/template/json/TestHelpers.java | 9 +- .../template/json/resolver/MarkerResolverTest.java | 94 +++++++ .../template/json/resolver/MarkerResolver.java | 41 ++- .../internal/util/HierarchicalCollections.java | 7 +- log4j-to-slf4j/pom.xml | 2 + pom.xml | 9 +- .../.2.x.x/1232_log4j-to-sfl4j-2-OSGiMetadata.xml | 29 ++ src/changelog/.2.x.x/1366_fix_java_sql_date.xml | 28 ++ .../asciidoc/manual/json-template-layout.adoc.vm | 54 ++++ 29 files changed, 1356 insertions(+), 1061 deletions(-) diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java index 106cce2c97..b4e67f3bc2 100644 --- a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java +++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java @@ -17,6 +17,7 @@ package org.apache.logging.log4j.message; import java.math.BigDecimal; +import java.sql.Date; import java.sql.Time; import java.util.Arrays; import java.util.Collections; @@ -320,6 +321,14 @@ public class MapMessageTest { message.getFormattedMessage(), "Incorrect time format"); } + @Test + public void testDate() { + final Date date = new Date(System.currentTimeMillis()); + final ObjectMapMessage message = new ObjectMapMessage().with("date", date); + assertEquals("date=\"" + date + "\"", + message.getFormattedMessage(), "Incorrect date format"); + } + private static final class FormattableTestType implements StringBuilderFormattable { @Override diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/StringBuilders.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/StringBuilders.java index d0c931d039..cc81a66105 100644 --- a/log4j-api/src/main/java/org/apache/logging/log4j/util/StringBuilders.java +++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/StringBuilders.java @@ -16,8 +16,6 @@ */ package org.apache.logging.log4j.util; -import java.lang.reflect.Array; -import java.util.Collections; import java.util.Map.Entry; import static java.lang.Character.toLowerCase; @@ -28,18 +26,28 @@ import static java.lang.Character.toLowerCase; @InternalApi public final class StringBuilders { - private static final Object timeClass; + private static final Object timeObj; + private static final Object dateObj; static { + Class<?> clazz; Object obj; + final long current = System.currentTimeMillis(); try { - Class<?> clazz = Class.forName("java.sql.Time"); - long current = System.currentTimeMillis(); + clazz = Class.forName("java.sql.Time"); obj = clazz.getDeclaredConstructor(Long.TYPE).newInstance(current); } catch(Exception ex) { obj = null; } - timeClass = obj; + timeObj = obj; + + try { + clazz = Class.forName("java.sql.Date"); + obj = clazz.getDeclaredConstructor(Long.TYPE).newInstance(current); + } catch(Exception ex) { + obj = null; + } + dateObj = obj; } private StringBuilders() { @@ -135,7 +143,7 @@ public final class StringBuilders { stringBuilder.append(((Float) obj).floatValue()); } else if (obj instanceof Byte) { stringBuilder.append(((Byte) obj).byteValue()); - } else if (isTime(obj) || obj instanceof java.time.temporal.Temporal) { + } else if (isTime(obj) || isDate(obj) || obj instanceof java.time.temporal.Temporal) { stringBuilder.append(obj); } else { return false; @@ -144,10 +152,17 @@ public final class StringBuilders { } /* - Check to see if obj is an instance of java.sql.time without requiring the java.sql module. + Check to see if obj is an instance of java.sql.Time without requiring the java.sql module. */ private static boolean isTime(final Object obj) { - return obj.getClass().isInstance(timeClass); + return obj.getClass().isInstance(timeObj); + } + + /* + Check to see if obj is an instance of java.sql.Date without requiring the java.sql module. + */ + private static boolean isDate(final Object obj) { + return obj.getClass().isInstance(dateObj); } /** diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/CompositeFilterTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/CompositeFilterTest.java index 0a5698b607..14d7f16d76 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/CompositeFilterTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/filter/CompositeFilterTest.java @@ -1,49 +1,48 @@ -/* 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.filter; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; - -import org.apache.logging.log4j.core.Filter; -import org.apache.logging.log4j.core.Filter.Result; -import org.junit.jupiter.api.Test; - -public class CompositeFilterTest { - - @Test - public void testConcatenation() { - final Filter a = DenyAllFilter.newBuilder().setOnMatch(Result.ACCEPT).build(); - final Filter b = DenyAllFilter.newBuilder().setOnMatch(Result.NEUTRAL).build(); - final Filter c = DenyAllFilter.newBuilder().setOnMatch(Result.DENY).build(); - // The three values need to be distinguishable - assertNotEquals(a, b); - assertNotEquals(a, c); - assertNotEquals(b, c); - final Filter[] expected = new Filter[] {a, b, c}; - final CompositeFilter singleA = CompositeFilter.createFilters(new Filter[] {a}); - final CompositeFilter singleB = CompositeFilter.createFilters(new Filter[] {b}); - final CompositeFilter singleC = CompositeFilter.createFilters(new Filter[] {c}); - // Concatenating one at a time - final CompositeFilter concat1 = singleA.addFilter(b).addFilter(c); - assertArrayEquals(expected, concat1.getFiltersArray()); - // In reverse order - final CompositeFilter concat2 = singleA.addFilter(singleB.addFilter(singleC)); - assertArrayEquals(expected, concat2.getFiltersArray()); - } -} +/* + * 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.filter; + +import org.apache.logging.log4j.core.Filter; +import org.apache.logging.log4j.core.Filter.Result; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +public class CompositeFilterTest { + + @Test + public void testConcatenation() { + final Filter a = DenyAllFilter.newBuilder().setOnMatch(Result.ACCEPT).build(); + final Filter b = DenyAllFilter.newBuilder().setOnMatch(Result.NEUTRAL).build(); + final Filter c = DenyAllFilter.newBuilder().setOnMatch(Result.DENY).build(); + // The three values need to be distinguishable + assertNotEquals(a, b); + assertNotEquals(a, c); + assertNotEquals(b, c); + final Filter[] expected = new Filter[] {a, b, c}; + final CompositeFilter singleA = CompositeFilter.createFilters(new Filter[] {a}); + final CompositeFilter singleB = CompositeFilter.createFilters(new Filter[] {b}); + final CompositeFilter singleC = CompositeFilter.createFilters(new Filter[] {c}); + // Concatenating one at a time + final CompositeFilter concat1 = singleA.addFilter(b).addFilter(c); + assertArrayEquals(expected, concat1.getFiltersArray()); + // In reverse order + final CompositeFilter concat2 = singleA.addFilter(singleB.addFilter(singleC)); + assertArrayEquals(expected, concat2.getFiltersArray()); + } +} diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/SimpleLiteralPatternConverterTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/SimpleLiteralPatternConverterTest.java index ba6b402447..4b46e42b32 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/SimpleLiteralPatternConverterTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/SimpleLiteralPatternConverterTest.java @@ -1,47 +1,46 @@ -/* - * 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.pattern; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class SimpleLiteralPatternConverterTest { - - @Test - public void testConvertBackslashes() { - String literal = "ABC\\tDEF\\nGHI\\rJKL\\'MNO\\f \\b \\\\DROPPED:\\x"; - LogEventPatternConverter converter = SimpleLiteralPatternConverter.of(literal, true); - String actual = literal(converter); - assertEquals("ABC\tDEF\nGHI\rJKL\'MNO\f \b \\DROPPED:x", actual); - } - - @Test - public void testDontConvertBackslashes() { - String literal = "ABC\\tDEF\\nGHI\\rJKL\\'MNO\\f \\b \\\\DROPPED:\\x"; - LogEventPatternConverter converter = SimpleLiteralPatternConverter.of(literal, false); - String actual = literal(converter); - assertEquals(literal, actual); - } - - private static String literal(LogEventPatternConverter converter) { - StringBuilder buffer = new StringBuilder(); - converter.format(null, buffer); - return buffer.toString(); - } -} +/* + * 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.pattern; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class SimpleLiteralPatternConverterTest { + + @Test + public void testConvertBackslashes() { + String literal = "ABC\\tDEF\\nGHI\\rJKL\\'MNO\\f \\b \\\\DROPPED:\\x"; + LogEventPatternConverter converter = SimpleLiteralPatternConverter.of(literal, true); + String actual = literal(converter); + assertEquals("ABC\tDEF\nGHI\rJKL\'MNO\f \b \\DROPPED:x", actual); + } + + @Test + public void testDontConvertBackslashes() { + String literal = "ABC\\tDEF\\nGHI\\rJKL\\'MNO\\f \\b \\\\DROPPED:\\x"; + LogEventPatternConverter converter = SimpleLiteralPatternConverter.of(literal, false); + String actual = literal(converter); + assertEquals(literal, actual); + } + + private static String literal(LogEventPatternConverter converter) { + StringBuilder buffer = new StringBuilder(); + converter.format(null, buffer); + return buffer.toString(); + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterManager.java index bf76e47b25..32c024fb0f 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterManager.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterManager.java @@ -1,149 +1,149 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache license, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the license for the specific language governing permissions and - * limitations under the license. - */ -package org.apache.logging.log4j.core.appender; - -import java.io.IOException; -import java.io.Writer; -import java.util.concurrent.TimeUnit; - -import org.apache.logging.log4j.core.StringLayout; - -/** - * Manages a Writer so that it can be shared by multiple Appenders and will - * allow appenders to reconfigure without requiring a new writer. - */ -public class WriterManager extends AbstractManager { - - /** - * Creates a Manager. - * - * @param name The name of the stream to manage. - * @param data The data to pass to the Manager. - * @param factory The factory to use to create the Manager. - * @param <T> The type of the WriterManager. - * @return A WriterManager. - */ - public static <T> WriterManager getManager(final String name, final T data, - final ManagerFactory<? extends WriterManager, T> factory) { - return AbstractManager.getManager(name, factory, data); - } - protected final StringLayout layout; - - private volatile Writer writer; - - public WriterManager(final Writer writer, final String streamName, final StringLayout layout, - final boolean writeHeader) { - super(null, streamName); - this.writer = writer; - this.layout = layout; - if (writeHeader && layout != null) { - final byte[] header = layout.getHeader(); - if (header != null) { - try { - this.writer.write(new String(header, layout.getCharset())); - } catch (final IOException e) { - logError("Unable to write header", e); - } - } - } - } - - protected synchronized void closeWriter() { - final Writer w = writer; // access volatile field only once per method - try { - w.close(); - } catch (final IOException ex) { - logError("Unable to close stream", ex); - } - } - - /** - * Flushes any buffers. - */ - public synchronized void flush() { - try { - writer.flush(); - } catch (final IOException ex) { - final String msg = "Error flushing stream " + getName(); - throw new AppenderLoggingException(msg, ex); - } - } - - protected Writer getWriter() { - return writer; - } - - /** - * Returns the status of the stream. - * @return true if the stream is open, false if it is not. - */ - public boolean isOpen() { - return getCount() > 0; - } - - /** - * Default hook to write footer during close. - */ - @Override - public boolean releaseSub(final long timeout, final TimeUnit timeUnit) { - writeFooter(); - closeWriter(); - return true; - } - - protected void setWriter(final Writer writer) { - final byte[] header = layout.getHeader(); - if (header != null) { - try { - writer.write(new String(header, layout.getCharset())); - this.writer = writer; // only update field if writer.write() succeeded - } catch (final IOException ioe) { - logError("Unable to write header", ioe); - } - } else { - this.writer = writer; - } - } - - /** - * Some output streams synchronize writes while others do not. Synchronizing here insures that - * log events won't be intertwined. - * @param str the string to write - * @throws AppenderLoggingException if an error occurs. - */ - protected synchronized void write(final String str) { - try { - writer.write(str); - } catch (final IOException ex) { - final String msg = "Error writing to stream " + getName(); - throw new AppenderLoggingException(msg, ex); - } - } - - /** - * Writes the footer. - */ - protected void writeFooter() { - if (layout == null) { - return; - } - final byte[] footer = layout.getFooter(); - if (footer != null && footer.length > 0) { - write(new String(footer, layout.getCharset())); - } - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.log4j.core.appender; + +import java.io.IOException; +import java.io.Writer; +import java.util.concurrent.TimeUnit; + +import org.apache.logging.log4j.core.StringLayout; + +/** + * Manages a Writer so that it can be shared by multiple Appenders and will + * allow appenders to reconfigure without requiring a new writer. + */ +public class WriterManager extends AbstractManager { + + /** + * Creates a Manager. + * + * @param name The name of the stream to manage. + * @param data The data to pass to the Manager. + * @param factory The factory to use to create the Manager. + * @param <T> The type of the WriterManager. + * @return A WriterManager. + */ + public static <T> WriterManager getManager(final String name, final T data, + final ManagerFactory<? extends WriterManager, T> factory) { + return AbstractManager.getManager(name, factory, data); + } + protected final StringLayout layout; + + private volatile Writer writer; + + public WriterManager(final Writer writer, final String streamName, final StringLayout layout, + final boolean writeHeader) { + super(null, streamName); + this.writer = writer; + this.layout = layout; + if (writeHeader && layout != null) { + final byte[] header = layout.getHeader(); + if (header != null) { + try { + this.writer.write(new String(header, layout.getCharset())); + } catch (final IOException e) { + logError("Unable to write header", e); + } + } + } + } + + protected synchronized void closeWriter() { + final Writer w = writer; // access volatile field only once per method + try { + w.close(); + } catch (final IOException ex) { + logError("Unable to close stream", ex); + } + } + + /** + * Flushes any buffers. + */ + public synchronized void flush() { + try { + writer.flush(); + } catch (final IOException ex) { + final String msg = "Error flushing stream " + getName(); + throw new AppenderLoggingException(msg, ex); + } + } + + protected Writer getWriter() { + return writer; + } + + /** + * Returns the status of the stream. + * @return true if the stream is open, false if it is not. + */ + public boolean isOpen() { + return getCount() > 0; + } + + /** + * Default hook to write footer during close. + */ + @Override + public boolean releaseSub(final long timeout, final TimeUnit timeUnit) { + writeFooter(); + closeWriter(); + return true; + } + + protected void setWriter(final Writer writer) { + final byte[] header = layout.getHeader(); + if (header != null) { + try { + writer.write(new String(header, layout.getCharset())); + this.writer = writer; // only update field if writer.write() succeeded + } catch (final IOException ioe) { + logError("Unable to write header", ioe); + } + } else { + this.writer = writer; + } + } + + /** + * Some output streams synchronize writes while others do not. Synchronizing here insures that + * log events won't be intertwined. + * @param str the string to write + * @throws AppenderLoggingException if an error occurs. + */ + protected synchronized void write(final String str) { + try { + writer.write(str); + } catch (final IOException ex) { + final String msg = "Error writing to stream " + getName(); + throw new AppenderLoggingException(msg, ex); + } + } + + /** + * Writes the footer. + */ + protected void writeFooter() { + if (layout == null) { + return; + } + final byte[] footer = layout.getFooter(); + if (footer != null && footer.length > 0) { + write(new String(footer, layout.getCharset())); + } + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitor.java index 69a59a7d8c..e433731cf2 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitor.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/DeletingVisitor.java @@ -1,110 +1,109 @@ -/* - * 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.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.List; -import java.util.Objects; - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.status.StatusLogger; - -/** - * FileVisitor that deletes files that are accepted by all PathFilters. Directories are ignored. - */ -public class DeletingVisitor extends SimpleFileVisitor<Path> { - private static final Logger LOGGER = StatusLogger.getLogger(); - - private final Path basePath; - private final boolean testMode; - private final List<? extends PathCondition> pathConditions; - - /** - * Constructs a new DeletingVisitor. - * - * @param basePath used to relativize paths - * @param pathConditions objects that need to confirm whether a file can be deleted - * @param testMode if true, files are not deleted but instead a message is printed to the <a - * href="http://logging.apache.org/log4j/2.x/manual/configuration.html#StatusMessages">status logger</a> - * at INFO level. Users can use this to do a dry run to test if their configuration works as expected. - */ - public DeletingVisitor(final Path basePath, final List<? extends PathCondition> pathConditions, - final boolean testMode) { - this.testMode = testMode; - this.basePath = Objects.requireNonNull(basePath, "basePath"); - this.pathConditions = Objects.requireNonNull(pathConditions, "pathConditions"); - for (final PathCondition condition : pathConditions) { - condition.beforeFileTreeWalk(); - } - } - - @Override - public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { - for (final PathCondition pathFilter : pathConditions) { - final Path relative = basePath.relativize(file); - if (!pathFilter.accept(basePath, relative, attrs)) { - LOGGER.trace("Not deleting base={}, relative={}", basePath, relative); - return FileVisitResult.CONTINUE; - } - } - if (isTestMode()) { - LOGGER.info("Deleting {} (TEST MODE: file not actually deleted)", file); - } else { - delete(file); - } - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFileFailed(final Path file, final IOException ioException) throws IOException { - // LOG4J2-2677: Appenders may rollover and purge in parallel. SimpleVisitor rethrows exceptions from - // failed attempts to load file attributes. - if (ioException instanceof NoSuchFileException) { - LOGGER.info("File {} could not be accessed, it has likely already been deleted", file, ioException); - return FileVisitResult.CONTINUE; - } else { - return super.visitFileFailed(file, ioException); - } - } - - /** - * Deletes the specified file. - * - * @param file the file to delete - * @throws IOException if a problem occurred deleting the file - */ - protected void delete(final Path file) throws IOException { - LOGGER.trace("Deleting {}", file); - Files.deleteIfExists(file); - } - - /** - * Returns {@code true} if files are not deleted even when all conditions accept a path, {@code false} otherwise. - * - * @return {@code true} if files are not deleted even when all conditions accept a path, {@code false} otherwise - */ - public boolean isTestMode() { - return testMode; - } -} +/* + * 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.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.List; +import java.util.Objects; + +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.status.StatusLogger; + +/** + * FileVisitor that deletes files that are accepted by all PathFilters. Directories are ignored. + */ +public class DeletingVisitor extends SimpleFileVisitor<Path> { + private static final Logger LOGGER = StatusLogger.getLogger(); + + private final Path basePath; + private final boolean testMode; + private final List<? extends PathCondition> pathConditions; + + /** + * Constructs a new DeletingVisitor. + * + * @param basePath used to relativize paths + * @param pathConditions objects that need to confirm whether a file can be deleted + * @param testMode if true, files are not deleted but instead a message is printed to the <a + * href="http://logging.apache.org/log4j/2.x/manual/configuration.html#StatusMessages">status logger</a> + * at INFO level. Users can use this to do a dry run to test if their configuration works as expected. + */ + public DeletingVisitor(final Path basePath, final List<? extends PathCondition> pathConditions, + final boolean testMode) { + this.testMode = testMode; + this.basePath = Objects.requireNonNull(basePath, "basePath"); + this.pathConditions = Objects.requireNonNull(pathConditions, "pathConditions"); + for (final PathCondition condition : pathConditions) { + condition.beforeFileTreeWalk(); + } + } + + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException { + for (final PathCondition pathFilter : pathConditions) { + final Path relative = basePath.relativize(file); + if (!pathFilter.accept(basePath, relative, attrs)) { + LOGGER.trace("Not deleting base={}, relative={}", basePath, relative); + return FileVisitResult.CONTINUE; + } + } + if (isTestMode()) { + LOGGER.info("Deleting {} (TEST MODE: file not actually deleted)", file); + } else { + delete(file); + } + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(final Path file, final IOException ioException) throws IOException { + // LOG4J2-2677: Appenders may rollover and purge in parallel. SimpleVisitor rethrows exceptions from + // failed attempts to load file attributes. + if (ioException instanceof NoSuchFileException) { + LOGGER.info("File {} could not be accessed, it has likely already been deleted", file, ioException); + return FileVisitResult.CONTINUE; + } else { + return super.visitFileFailed(file, ioException); + } + } + + /** + * Deletes the specified file. + * + * @param file the file to delete + * @throws IOException if a problem occurred deleting the file + */ + protected void delete(final Path file) throws IOException { + LOGGER.trace("Deleting {}", file); + Files.deleteIfExists(file); + } + + /** + * Returns {@code true} if files are not deleted even when all conditions accept a path, {@code false} otherwise. + * + * @return {@code true} if files are not deleted even when all conditions accept a path, {@code false} otherwise + */ + public boolean isTestMode() { + return testMode; + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathSorter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathSorter.java index 2e765ab0b8..d8ea3c2d22 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathSorter.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathSorter.java @@ -1,27 +1,26 @@ -/* - * 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.util.Comparator; - -/** - * Defines the interface of classes that can sort Paths. - */ -public interface PathSorter extends Comparator<PathWithAttributes>{ - -} +/* + * 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.util.Comparator; + +/** + * Defines the interface of classes that can sort Paths. + */ +public interface PathSorter extends Comparator<PathWithAttributes>{ + +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathWithAttributes.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathWithAttributes.java index d69835427b..674e784269 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathWithAttributes.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/PathWithAttributes.java @@ -1,59 +1,58 @@ -/* - * 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.nio.file.attribute.BasicFileAttributes; -import java.util.Objects; - -/** - * Tuple of a {@code Path} and {@code BasicFileAttributes}, used for sorting. - */ -public class PathWithAttributes { - - private final Path path; - private final BasicFileAttributes attributes; - - public PathWithAttributes(final Path path, final BasicFileAttributes attributes) { - this.path = Objects.requireNonNull(path, "path"); - this.attributes = Objects.requireNonNull(attributes, "attributes"); - } - - @Override - public String toString() { - return path + " (modified: " + attributes.lastModifiedTime() + ")"; - } - - /** - * Returns the path. - * - * @return the path - */ - public Path getPath() { - return path; - } - - /** - * Returns the attributes. - * - * @return the attributes - */ - public BasicFileAttributes getAttributes() { - return attributes; - } -} +/* + * 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.nio.file.attribute.BasicFileAttributes; +import java.util.Objects; + +/** + * Tuple of a {@code Path} and {@code BasicFileAttributes}, used for sorting. + */ +public class PathWithAttributes { + + private final Path path; + private final BasicFileAttributes attributes; + + public PathWithAttributes(final Path path, final BasicFileAttributes attributes) { + this.path = Objects.requireNonNull(path, "path"); + this.attributes = Objects.requireNonNull(attributes, "attributes"); + } + + @Override + public String toString() { + return path + " (modified: " + attributes.lastModifiedTime() + ")"; + } + + /** + * Returns the path. + * + * @return the path + */ + public Path getPath() { + return path; + } + + /** + * Returns the attributes. + * + * @return the attributes + */ + public BasicFileAttributes getAttributes() { + return attributes; + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/SortingVisitor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/SortingVisitor.java index ba7e00b601..c7ba94ec61 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/SortingVisitor.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/action/SortingVisitor.java @@ -1,75 +1,74 @@ -/* - * 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.Logger; -import org.apache.logging.log4j.status.StatusLogger; - -import java.io.IOException; -import java.nio.file.FileVisitResult; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -/** - * FileVisitor that sorts files. - */ -public class SortingVisitor extends SimpleFileVisitor<Path> { - - private static final Logger LOGGER = StatusLogger.getLogger(); - private final PathSorter sorter; - private final List<PathWithAttributes> collected = new ArrayList<>(); - - /** - * Constructs a new DeletingVisitor. - * - * @param basePath used to relativize paths - * @param pathFilters objects that need to confirm whether a file can be deleted - */ - public SortingVisitor(final PathSorter sorter) { - this.sorter = Objects.requireNonNull(sorter, "sorter"); - } - - @Override - public FileVisitResult visitFile(final Path path, final BasicFileAttributes attrs) throws IOException { - collected.add(new PathWithAttributes(path, attrs)); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFileFailed(final Path file, final IOException ioException) throws IOException { - // LOG4J2-2677: Appenders may rollover and purge in parallel. SimpleVisitor rethrows exceptions from - // failed attempts to load file attributes. - if (ioException instanceof NoSuchFileException) { - LOGGER.info("File {} could not be accessed, it has likely already been deleted", file, ioException); - return FileVisitResult.CONTINUE; - } else { - return super.visitFileFailed(file, ioException); - } - } - - public List<PathWithAttributes> getSortedPaths() { - Collections.sort(collected, sorter); - return collected; - } -} +/* + * 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.nio.file.FileVisitResult; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.status.StatusLogger; + +/** + * FileVisitor that sorts files. + */ +public class SortingVisitor extends SimpleFileVisitor<Path> { + + private static final Logger LOGGER = StatusLogger.getLogger(); + private final PathSorter sorter; + private final List<PathWithAttributes> collected = new ArrayList<>(); + + /** + * Constructs a new DeletingVisitor. + * + * @param basePath used to relativize paths + * @param pathFilters objects that need to confirm whether a file can be deleted + */ + public SortingVisitor(final PathSorter sorter) { + this.sorter = Objects.requireNonNull(sorter, "sorter"); + } + + @Override + public FileVisitResult visitFile(final Path path, final BasicFileAttributes attrs) throws IOException { + collected.add(new PathWithAttributes(path, attrs)); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(final Path file, final IOException ioException) throws IOException { + // LOG4J2-2677: Appenders may rollover and purge in parallel. SimpleVisitor rethrows exceptions from + // failed attempts to load file attributes. + if (ioException instanceof NoSuchFileException) { + LOGGER.info("File {} could not be accessed, it has likely already been deleted", file, ioException); + return FileVisitResult.CONTINUE; + } else { + return super.visitFileFailed(file, ioException); + } + } + + public List<PathWithAttributes> getSortedPaths() { + Collections.sort(collected, sorter); + return collected; + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDelegate.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDelegate.java index b791f0afe4..1cf0c8e66f 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDelegate.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigDelegate.java @@ -1,66 +1,65 @@ -/* - * 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.async; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.impl.LogEventFactory; -import org.apache.logging.log4j.core.jmx.RingBufferAdmin; - -/** - * Encapsulates the mechanism used to log asynchronously. There is one delegate per configuration, which is shared by - * all AsyncLoggerConfig objects in the configuration. - */ -public interface AsyncLoggerConfigDelegate { - - /** - * Creates and returns a new {@code RingBufferAdmin} that instruments the ringbuffer of this - * {@code AsyncLoggerConfig}. - * - * @param contextName name of the {@code LoggerContext} - * @param loggerConfigName name of the logger config - * @return the RingBufferAdmin that instruments the ringbuffer - */ - RingBufferAdmin createRingBufferAdmin(final String contextName, final String loggerConfigName); - - /** - * Returns the {@code EventRoute} for the event with the specified level. - * - * @param level the level of the event to log - * @return the {@code EventRoute} - */ - EventRoute getEventRoute(final Level level); - - /** - * Enqueues the {@link LogEvent} on the mixed configuration ringbuffer. - * This method must only be used after {@link #tryEnqueue(LogEvent, AsyncLoggerConfig)} returns <code>false</code> - * indicating that the ringbuffer is full, otherwise it may incur unnecessary synchronization. - */ - void enqueueEvent(LogEvent event, AsyncLoggerConfig asyncLoggerConfig); - - boolean tryEnqueue(LogEvent event, AsyncLoggerConfig asyncLoggerConfig); - - /** - * Notifies the delegate what LogEventFactory an AsyncLoggerConfig is using, so the delegate can determine - * whether to populate the ring buffer with mutable log events or not. This method may be invoked multiple times - * for all AsyncLoggerConfigs that use this delegate. - * - * @param logEventFactory the factory used - */ - void setLogEventFactory(LogEventFactory logEventFactory); -} +/* + * 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.async; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.impl.LogEventFactory; +import org.apache.logging.log4j.core.jmx.RingBufferAdmin; + +/** + * Encapsulates the mechanism used to log asynchronously. There is one delegate per configuration, which is shared by + * all AsyncLoggerConfig objects in the configuration. + */ +public interface AsyncLoggerConfigDelegate { + + /** + * Creates and returns a new {@code RingBufferAdmin} that instruments the ringbuffer of this + * {@code AsyncLoggerConfig}. + * + * @param contextName name of the {@code LoggerContext} + * @param loggerConfigName name of the logger config + * @return the RingBufferAdmin that instruments the ringbuffer + */ + RingBufferAdmin createRingBufferAdmin(final String contextName, final String loggerConfigName); + + /** + * Returns the {@code EventRoute} for the event with the specified level. + * + * @param level the level of the event to log + * @return the {@code EventRoute} + */ + EventRoute getEventRoute(final Level level); + + /** + * Enqueues the {@link LogEvent} on the mixed configuration ringbuffer. + * This method must only be used after {@link #tryEnqueue(LogEvent, AsyncLoggerConfig)} returns <code>false</code> + * indicating that the ringbuffer is full, otherwise it may incur unnecessary synchronization. + */ + void enqueueEvent(LogEvent event, AsyncLoggerConfig asyncLoggerConfig); + + boolean tryEnqueue(LogEvent event, AsyncLoggerConfig asyncLoggerConfig); + + /** + * Notifies the delegate what LogEventFactory an AsyncLoggerConfig is using, so the delegate can determine + * whether to populate the ring buffer with mutable log events or not. This method may be invoked multiple times + * for all AsyncLoggerConfigs that use this delegate. + * + * @param logEventFactory the factory used + */ + void setLogEventFactory(LogEventFactory logEventFactory); +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelector.java index 9658f0302f..70f90ca3b6 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelector.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelector.java @@ -1,44 +1,44 @@ -/* - * 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.async; - -import java.net.URI; - -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.selector.BasicContextSelector; -import org.apache.logging.log4j.plugins.Inject; -import org.apache.logging.log4j.plugins.Singleton; -import org.apache.logging.log4j.plugins.di.Injector; - -/** - * Returns either this Thread's context or the default {@link AsyncLoggerContext}. - * Single-application instances should prefer this implementation over the {@link AsyncLoggerContextSelector} - * due to the reduced overhead avoiding classloader lookups. - */ -@Singleton -public class BasicAsyncLoggerContextSelector extends BasicContextSelector { - - @Inject - public BasicAsyncLoggerContextSelector(Injector injector) { - super(injector); - } - - @Override - protected LoggerContext createContext() { - return new AsyncLoggerContext("AsyncDefault", null, (URI) null, injector); - } -} +/* + * 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.async; + +import java.net.URI; + +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.selector.BasicContextSelector; +import org.apache.logging.log4j.plugins.Inject; +import org.apache.logging.log4j.plugins.Singleton; +import org.apache.logging.log4j.plugins.di.Injector; + +/** + * Returns either this Thread's context or the default {@link AsyncLoggerContext}. + * Single-application instances should prefer this implementation over the {@link AsyncLoggerContextSelector} + * due to the reduced overhead avoiding classloader lookups. + */ +@Singleton +public class BasicAsyncLoggerContextSelector extends BasicContextSelector { + + @Inject + public BasicAsyncLoggerContextSelector(Injector injector) { + super(injector); + } + + @Override + protected LoggerContext createContext() { + return new AsyncLoggerContext("AsyncDefault", null, (URI) null, injector); + } +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ReliabilityStrategy.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ReliabilityStrategy.java index 1ccb74a6b1..b469a73b1d 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ReliabilityStrategy.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ReliabilityStrategy.java @@ -1,95 +1,94 @@ -/* - * 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.config; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.Marker; -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.message.Message; -import org.apache.logging.log4j.util.Supplier; - -/** - * Interface for objects that know how to ensure delivery of log events to the appropriate appenders, even during and - * after the configuration has been modified while the system is actively used. - */ -public interface ReliabilityStrategy { - - /** - * Logs an event. - * - * @param reconfigured supplies the next LoggerConfig if the strategy's LoggerConfig is no longer active - * @param loggerName The name of the Logger. - * @param fqcn The fully qualified class name of the caller. - * @param marker A Marker or null if none is present. - * @param level The event Level. - * @param data The Message. - * @param t A Throwable or null. - */ - void log(Supplier<LoggerConfig> reconfigured, String loggerName, String fqcn, Marker marker, Level level, - Message data, Throwable t); - /** - * Logs an event. - * - * @param reconfigured supplies the next LoggerConfig if the strategy's LoggerConfig is no longer active - * @param loggerName The name of the Logger. - * @param fqcn The fully qualified class name of the caller. - * @param location The location of the caller or null. - * @param marker A Marker or null if none is present. - * @param level The event Level. - * @param data The Message. - * @param t A Throwable or null. - * @since 3.0 - */ - default void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn, final StackTraceElement location, - final Marker marker, final Level level, final Message data, final Throwable t) { - } - - /** - * Logs an event. - * - * @param reconfigured supplies the next LoggerConfig if the strategy's LoggerConfig is no longer active - * @param event The log event. - */ - void log(Supplier<LoggerConfig> reconfigured, LogEvent event); - - /** - * For internal use by the ReliabilityStrategy; returns the LoggerConfig to use. - * - * @param next supplies the next LoggerConfig if the strategy's LoggerConfig is no longer active - * @return the currently active LoggerConfig - */ - LoggerConfig getActiveLoggerConfig(Supplier<LoggerConfig> next); - - /** - * Called after a log event was logged. - */ - void afterLogEvent(); - - /** - * Called before all appenders are stopped. - */ - void beforeStopAppenders(); - - /** - * Called before the configuration is stopped. - * - * @param configuration the configuration that will be stopped - */ - void beforeStopConfiguration(Configuration configuration); - -} +/* + * 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.config; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.message.Message; +import org.apache.logging.log4j.util.Supplier; + +/** + * Interface for objects that know how to ensure delivery of log events to the appropriate appenders, even during and + * after the configuration has been modified while the system is actively used. + */ +public interface ReliabilityStrategy { + + /** + * Logs an event. + * + * @param reconfigured supplies the next LoggerConfig if the strategy's LoggerConfig is no longer active + * @param loggerName The name of the Logger. + * @param fqcn The fully qualified class name of the caller. + * @param marker A Marker or null if none is present. + * @param level The event Level. + * @param data The Message. + * @param t A Throwable or null. + */ + void log(Supplier<LoggerConfig> reconfigured, String loggerName, String fqcn, Marker marker, Level level, + Message data, Throwable t); + /** + * Logs an event. + * + * @param reconfigured supplies the next LoggerConfig if the strategy's LoggerConfig is no longer active + * @param loggerName The name of the Logger. + * @param fqcn The fully qualified class name of the caller. + * @param location The location of the caller or null. + * @param marker A Marker or null if none is present. + * @param level The event Level. + * @param data The Message. + * @param t A Throwable or null. + * @since 3.0 + */ + default void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn, final StackTraceElement location, + final Marker marker, final Level level, final Message data, final Throwable t) { + } + + /** + * Logs an event. + * + * @param reconfigured supplies the next LoggerConfig if the strategy's LoggerConfig is no longer active + * @param event The log event. + */ + void log(Supplier<LoggerConfig> reconfigured, LogEvent event); + + /** + * For internal use by the ReliabilityStrategy; returns the LoggerConfig to use. + * + * @param next supplies the next LoggerConfig if the strategy's LoggerConfig is no longer active + * @return the currently active LoggerConfig + */ + LoggerConfig getActiveLoggerConfig(Supplier<LoggerConfig> next); + + /** + * Called after a log event was logged. + */ + void afterLogEvent(); + + /** + * Called before all appenders are stopped. + */ + void beforeStopAppenders(); + + /** + * Called before the configuration is stopped. + * + * @param configuration the configuration that will be stopped + */ + void beforeStopConfiguration(Configuration configuration); + +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultComponentAndConfigurationBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultComponentAndConfigurationBuilder.java index f6e7e1e6bb..2ca603dabe 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultComponentAndConfigurationBuilder.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/DefaultComponentAndConfigurationBuilder.java @@ -1,47 +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.core.config.builder.impl; - -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder; - -/** - * Extends {@code DefaultComponentBuilder} to specify - * {@code DefaultConfigurationBuilder<? extends Configuration>} as the - * {@code ConfigurationBuilder} type. - * - * @since 2.4 - */ -class DefaultComponentAndConfigurationBuilder<T extends ComponentBuilder<T>> - extends DefaultComponentBuilder<T, DefaultConfigurationBuilder<? extends Configuration>> { - - DefaultComponentAndConfigurationBuilder(final DefaultConfigurationBuilder<? extends Configuration> builder, final String name, - final String type, final String value) { - super(builder, name, type, value); - } - - DefaultComponentAndConfigurationBuilder(final DefaultConfigurationBuilder<? extends Configuration> builder, final String name, - final String type) { - super(builder, name, type); - } - - public DefaultComponentAndConfigurationBuilder(final DefaultConfigurationBuilder<? extends Configuration> builder, - final String type) { - super(builder, type); - } - -} +/* + * 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.config.builder.impl; + +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder; + +/** + * Extends {@code DefaultComponentBuilder} to specify + * {@code DefaultConfigurationBuilder<? extends Configuration>} as the + * {@code ConfigurationBuilder} type. + * + * @since 2.4 + */ +class DefaultComponentAndConfigurationBuilder<T extends ComponentBuilder<T>> + extends DefaultComponentBuilder<T, DefaultConfigurationBuilder<? extends Configuration>> { + + DefaultComponentAndConfigurationBuilder(final DefaultConfigurationBuilder<? extends Configuration> builder, final String name, + final String type, final String value) { + super(builder, name, type, value); + } + + DefaultComponentAndConfigurationBuilder(final DefaultConfigurationBuilder<? extends Configuration> builder, final String name, + final String type) { + super(builder, name, type); + } + + public DefaultComponentAndConfigurationBuilder(final DefaultConfigurationBuilder<? extends Configuration> builder, + final String type) { + super(builder, type); + } + +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/CoreContextSelectors.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/CoreContextSelectors.java index 2ee6b0d4f6..1588d2999d 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/CoreContextSelectors.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/CoreContextSelectors.java @@ -1,31 +1,31 @@ -/* - * 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.selector; - -import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector; -import org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector; - -public class CoreContextSelectors { - - public static final Class<?>[] CLASSES = new Class<?>[] { - ClassLoaderContextSelector.class, - BasicContextSelector.class, - AsyncLoggerContextSelector.class, - BasicAsyncLoggerContextSelector.class - }; - -} +/* + * 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.selector; + +import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector; +import org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector; + +public class CoreContextSelectors { + + public static final Class<?>[] CLASSES = new Class<?>[] { + ClassLoaderContextSelector.class, + BasicContextSelector.class, + AsyncLoggerContextSelector.class, + BasicAsyncLoggerContextSelector.class + }; + +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/CloseShieldOutputStream.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/CloseShieldOutputStream.java index 1139bd20f9..946e0c29b4 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/CloseShieldOutputStream.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/CloseShieldOutputStream.java @@ -1,60 +1,60 @@ -/* - * 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.util; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * A delegating OutputStream that does not close its delegate. - */ -public class CloseShieldOutputStream extends OutputStream { - - private final OutputStream delegate; - - public CloseShieldOutputStream(final OutputStream delegate) { - this.delegate = delegate; - } - - /** - * Does nothing. - */ - @Override - public void close() { - // do not close delegate - } - - @Override - public void flush() throws IOException { - delegate.flush(); - } - - @Override - public void write(final byte[] b) throws IOException { - delegate.write(b); - } - - @Override - public void write(final byte[] b, final int off, final int len) throws IOException { - delegate.write(b, off, len); - } - - @Override - public void write(final int b) throws IOException { - delegate.write(b); - } +/* + * 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.util; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * A delegating OutputStream that does not close its delegate. + */ +public class CloseShieldOutputStream extends OutputStream { + + private final OutputStream delegate; + + public CloseShieldOutputStream(final OutputStream delegate) { + this.delegate = delegate; + } + + /** + * Does nothing. + */ + @Override + public void close() { + // do not close delegate + } + + @Override + public void flush() throws IOException { + delegate.flush(); + } + + @Override + public void write(final byte[] b) throws IOException { + delegate.write(b); + } + + @Override + public void write(final byte[] b, final int off, final int len) throws IOException { + delegate.write(b, off, len); + } + + @Override + public void write(final int b) throws IOException { + delegate.write(b); + } } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/CloseShieldWriter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/CloseShieldWriter.java index c29cdf624e..b2f6fdcd9d 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/CloseShieldWriter.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/CloseShieldWriter.java @@ -1,46 +1,46 @@ -/* - * 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.util; - -import java.io.IOException; -import java.io.Writer; - -public class CloseShieldWriter extends Writer { - - private final Writer delegate; - - public CloseShieldWriter(final Writer delegate) { - this.delegate = delegate; - } - - @Override - public void close() throws IOException { - // do not close delegate - } - - @Override - public void flush() throws IOException { - delegate.flush(); - - } - - @Override - public void write(final char[] cbuf, final int off, final int len) throws IOException { - delegate.write(cbuf, off, len); - } - -} +/* + * 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.util; + +import java.io.IOException; +import java.io.Writer; + +public class CloseShieldWriter extends Writer { + + private final Writer delegate; + + public CloseShieldWriter(final Writer delegate) { + this.delegate = delegate; + } + + @Override + public void close() throws IOException { + // do not close delegate + } + + @Override + public void flush() throws IOException { + delegate.flush(); + + } + + @Override + public void write(final char[] cbuf, final int off, final int len) throws IOException { + delegate.write(cbuf, off, len); + } + +} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/IOUtils.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/IOUtils.java index ffb8615cd3..07e5c79316 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/IOUtils.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/IOUtils.java @@ -1,130 +1,130 @@ -/* - * 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.util; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.Writer; - -/** - * Copied from Apache Commons IO revision 1686747. - */ -public class IOUtils { - - /** - * The default buffer size ({@value}) to use for - * {@link #copyLarge(InputStream, OutputStream)} - * and - * {@link #copyLarge(Reader, Writer)} - */ - private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; - - /** - * Represents the end-of-file (or stream). - */ - public static final int EOF = -1; - - /** - * Copies chars from a <code>Reader</code> to a <code>Writer</code>. - * <p/> - * This method buffers the input internally, so there is no need to use a - * <code>BufferedReader</code>. - * <p/> - * Large streams (over 2GB) will return a chars copied value of - * <code>-1</code> after the copy has completed since the correct - * number of chars cannot be returned as an int. For large streams - * use the <code>copyLarge(Reader, Writer)</code> method. - * - * @param input the <code>Reader</code> to read from - * @param output the <code>Writer</code> to write to - * @return the number of characters copied, or -1 if > Integer.MAX_VALUE - * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs - * @since 1.1 - */ - public static int copy(final Reader input, final Writer output) throws IOException { - final long count = copyLarge(input, output); - if (count > Integer.MAX_VALUE) { - return -1; - } - return (int) count; - } - - /** - * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>. - * <p/> - * This method buffers the input internally, so there is no need to use a - * <code>BufferedReader</code>. - * <p/> - * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. - * - * @param input the <code>Reader</code> to read from - * @param output the <code>Writer</code> to write to - * @return the number of characters copied - * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs - * @since 1.3 - */ - public static long copyLarge(final Reader input, final Writer output) throws IOException { - return copyLarge(input, output, new char[DEFAULT_BUFFER_SIZE]); - } - - /** - * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>. - * <p/> - * This method uses the provided buffer, so there is no need to use a - * <code>BufferedReader</code>. - * <p/> - * - * @param input the <code>Reader</code> to read from - * @param output the <code>Writer</code> to write to - * @param buffer the buffer to be used for the copy - * @return the number of characters copied - * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs - * @since 2.2 - */ - public static long copyLarge(final Reader input, final Writer output, final char[] buffer) throws IOException { - long count = 0; - int n; - while (EOF != (n = input.read(buffer))) { - output.write(buffer, 0, n); - count += n; - } - return count; - } - - /** - * Gets the contents of a <code>Reader</code> as a String. - * <p/> - * This method buffers the input internally, so there is no need to use a - * <code>BufferedReader</code>. - * - * @param input the <code>Reader</code> to read from - * @return the requested String - * @throws NullPointerException if the input is null - * @throws IOException if an I/O error occurs - */ - public static String toString(final Reader input) throws IOException { - final StringBuilderWriter sw = new StringBuilderWriter(); - copy(input, sw); - return sw.toString(); - } - -} +/* + * 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.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; + +/** + * Copied from Apache Commons IO revision 1686747. + */ +public class IOUtils { + + /** + * The default buffer size ({@value}) to use for + * {@link #copyLarge(InputStream, OutputStream)} + * and + * {@link #copyLarge(Reader, Writer)} + */ + private static final int DEFAULT_BUFFER_SIZE = 1024 * 4; + + /** + * Represents the end-of-file (or stream). + */ + public static final int EOF = -1; + + /** + * Copies chars from a <code>Reader</code> to a <code>Writer</code>. + * <p/> + * This method buffers the input internally, so there is no need to use a + * <code>BufferedReader</code>. + * <p/> + * Large streams (over 2GB) will return a chars copied value of + * <code>-1</code> after the copy has completed since the correct + * number of chars cannot be returned as an int. For large streams + * use the <code>copyLarge(Reader, Writer)</code> method. + * + * @param input the <code>Reader</code> to read from + * @param output the <code>Writer</code> to write to + * @return the number of characters copied, or -1 if > Integer.MAX_VALUE + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since 1.1 + */ + public static int copy(final Reader input, final Writer output) throws IOException { + final long count = copyLarge(input, output); + if (count > Integer.MAX_VALUE) { + return -1; + } + return (int) count; + } + + /** + * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>. + * <p/> + * This method buffers the input internally, so there is no need to use a + * <code>BufferedReader</code>. + * <p/> + * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. + * + * @param input the <code>Reader</code> to read from + * @param output the <code>Writer</code> to write to + * @return the number of characters copied + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since 1.3 + */ + public static long copyLarge(final Reader input, final Writer output) throws IOException { + return copyLarge(input, output, new char[DEFAULT_BUFFER_SIZE]); + } + + /** + * Copies chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>. + * <p/> + * This method uses the provided buffer, so there is no need to use a + * <code>BufferedReader</code>. + * <p/> + * + * @param input the <code>Reader</code> to read from + * @param output the <code>Writer</code> to write to + * @param buffer the buffer to be used for the copy + * @return the number of characters copied + * @throws NullPointerException if the input or output is null + * @throws IOException if an I/O error occurs + * @since 2.2 + */ + public static long copyLarge(final Reader input, final Writer output, final char[] buffer) throws IOException { + long count = 0; + int n; + while (EOF != (n = input.read(buffer))) { + output.write(buffer, 0, n); + count += n; + } + return count; + } + + /** + * Gets the contents of a <code>Reader</code> as a String. + * <p/> + * This method buffers the input internally, so there is no need to use a + * <code>BufferedReader</code>. + * + * @param input the <code>Reader</code> to read from + * @return the requested String + * @throws NullPointerException if the input is null + * @throws IOException if an I/O error occurs + */ + public static String toString(final Reader input) throws IOException { + final StringBuilderWriter sw = new StringBuilderWriter(); + copy(input, sw); + return sw.toString(); + } + +} diff --git a/log4j-jeromq/src/main/java/org/apache/logging/log4j/jeromq/appender/JeroMqAppender.java b/log4j-jeromq/src/main/java/org/apache/logging/log4j/jeromq/appender/JeroMqAppender.java index c28021a82f..98047a0cff 100644 --- a/log4j-jeromq/src/main/java/org/apache/logging/log4j/jeromq/appender/JeroMqAppender.java +++ b/log4j-jeromq/src/main/java/org/apache/logging/log4j/jeromq/appender/JeroMqAppender.java @@ -172,6 +172,11 @@ public final class JeroMqAppender extends AbstractAppender { sendRcTrue = sendRcFalse = 0; } + // not public, handy for testing + byte[] recv(int timeoutMs) { + return manager.recv(timeoutMs); + } + @Override public String toString() { return "JeroMqAppender{" + diff --git a/log4j-jeromq/src/main/java/org/apache/logging/log4j/jeromq/appender/JeroMqManager.java b/log4j-jeromq/src/main/java/org/apache/logging/log4j/jeromq/appender/JeroMqManager.java index e50972df03..51aaf1b840 100644 --- a/log4j-jeromq/src/main/java/org/apache/logging/log4j/jeromq/appender/JeroMqManager.java +++ b/log4j-jeromq/src/main/java/org/apache/logging/log4j/jeromq/appender/JeroMqManager.java @@ -26,6 +26,7 @@ import org.apache.logging.log4j.core.appender.ManagerFactory; import org.apache.logging.log4j.core.util.Cancellable; import org.apache.logging.log4j.core.util.ShutdownCallbackRegistry; import org.apache.logging.log4j.util.PropertiesUtil; +import org.zeromq.SocketType; import org.zeromq.ZMQ; /** @@ -60,7 +61,7 @@ public class JeroMqManager extends AbstractManager { final boolean enableShutdownHook = PropertiesUtil.getProperties().getBooleanProperty( SYS_PROPERTY_ENABLE_SHUTDOWN_HOOK, true); - if (enableShutdownHook) { + if (enableShutdownHook && LogManager.getFactory() instanceof ShutdownCallbackRegistry) { SHUTDOWN_HOOK = ((ShutdownCallbackRegistry) LogManager.getFactory()).addShutdownCallback(CONTEXT::close); } else { SHUTDOWN_HOOK = null; @@ -71,7 +72,7 @@ public class JeroMqManager extends AbstractManager { private JeroMqManager(final String name, final JeroMqConfiguration config) { super(null, name); - publisher = CONTEXT.socket(ZMQ.PUB); + publisher = CONTEXT.socket(SocketType.XPUB); publisher.setAffinity(config.affinity); publisher.setBacklog(config.backlog); publisher.setDelayAttachOnConnect(config.delayAttachOnConnect); @@ -104,6 +105,17 @@ public class JeroMqManager extends AbstractManager { return publisher.send(data); } + // not public, handy for testing + byte[] recv(int timeoutMs) { + int oldTimeoutMs = publisher.getReceiveTimeOut(); + try { + publisher.setReceiveTimeOut(timeoutMs); + return publisher.recv(); + } finally { + publisher.setReceiveTimeOut(oldTimeoutMs); + } + } + @Override protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) { publisher.close(); diff --git a/log4j-jeromq/src/test/java/org/apache/logging/log4j/jeromq/appender/JeroMqAppenderTest.java b/log4j-jeromq/src/test/java/org/apache/logging/log4j/jeromq/appender/JeroMqAppenderTest.java index e582559281..aafe354a5d 100644 --- a/log4j-jeromq/src/test/java/org/apache/logging/log4j/jeromq/appender/JeroMqAppenderTest.java +++ b/log4j-jeromq/src/test/java/org/apache/logging/log4j/jeromq/appender/JeroMqAppenderTest.java @@ -21,6 +21,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import org.apache.logging.log4j.ThreadContext; import org.apache.logging.log4j.core.Logger; @@ -31,13 +32,12 @@ import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; +import static org.assertj.core.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.fail; @Tag("zeromq") -@Tag("sleepy") -@Timeout(value = 200) +@Timeout(value = 10, unit = TimeUnit.SECONDS) @LoggerContextSource(value = "JeroMqAppenderTest.xml", timeout = 60) public class JeroMqAppenderTest { @@ -61,7 +61,7 @@ public class JeroMqAppenderTest { final ExecutorService executor = Executors.newSingleThreadExecutor(); try { final Future<List<String>> future = executor.submit(client); - Thread.sleep(100); + waitForSubscription(appender, 1000); appender.resetSendRcs(); logger.info("Hello"); logger.info("Again"); @@ -87,7 +87,7 @@ public class JeroMqAppenderTest { final ExecutorService executor = Executors.newSingleThreadExecutor(); try { final Future<List<String>> future = executor.submit(client); - Thread.sleep(100); + waitForSubscription(appender, 1000); appender.resetSendRcs(); final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(nThreads); for (int i = 0; i < 10.; i++) { @@ -129,4 +129,15 @@ public class JeroMqAppenderTest { assertEquals(2, appender.getSendRcTrue()); assertEquals(0, appender.getSendRcFalse()); } + + private void waitForSubscription(JeroMqAppender appender, int timeoutMs) throws Exception { + final long start = System.currentTimeMillis(); + while (System.currentTimeMillis() - start < timeoutMs) { + byte[] msg = appender.recv(timeoutMs); + if (msg != null && msg.length > 0 && msg[0] == 1) { + return; + } + } + throw new TimeoutException(); + } } diff --git a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/TestHelpers.java b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/TestHelpers.java index 07f3234060..6a8a4a90e9 100644 --- a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/TestHelpers.java +++ b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/TestHelpers.java @@ -75,14 +75,17 @@ public final class TestHelpers { final Consumer<MapAccessor> accessorConsumer) { final String serializedLogEventJson = layout.toSerializable(logEvent); @SuppressWarnings("unchecked") - final Map<String, Object> deserializedLogEvent = - (Map<String, Object>) readJson(serializedLogEventJson); + final Map<String, Object> deserializedLogEvent = (Map<String, Object>) readJson(serializedLogEventJson); final MapAccessor serializedLogEventAccessor = new MapAccessor(deserializedLogEvent); accessorConsumer.accept(serializedLogEventAccessor); } public static Object readJson(final String json) { - return JsonReader.read(json); + try { + return JsonReader.read(json); + } catch (final Exception error) { + throw new RuntimeException("failed to deserialize the JSON: " + json, error); + } } public static Map<String, Object> asMap(final Object... pairs) { diff --git a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/MarkerResolverTest.java b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/MarkerResolverTest.java new file mode 100644 index 0000000000..8eeb6f7f4a --- /dev/null +++ b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/MarkerResolverTest.java @@ -0,0 +1,94 @@ +/* + * 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.layout.template.json.resolver; + +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.impl.Log4jLogEvent; +import org.apache.logging.log4j.layout.template.json.JsonTemplateLayout; +import org.junit.jupiter.api.Test; + +import static org.apache.logging.log4j.layout.template.json.TestHelpers.*; +import static org.assertj.core.api.Assertions.assertThat; + +class MarkerResolverTest { + + @Test + void should_have_a_marker_name() { + + // Create the event template + final String eventTemplate = writeJson(asMap( + "marker", asMap( + "$resolver", "marker", + "field", "name"))); + + // Create the layout. + final JsonTemplateLayout layout = JsonTemplateLayout + .newBuilder() + .setConfiguration(CONFIGURATION) + .setEventTemplate(eventTemplate) + .build(); + + // Create the log event. + final Marker marker = MarkerManager.getMarker("MARKER"); + final LogEvent logEvent = Log4jLogEvent + .newBuilder() + .setMarker(marker) + .build(); + + // Check the serialized event. + usingSerializedLogEventAccessor(layout, logEvent, accessor -> + assertThat(accessor.getString("marker")).isEqualTo("MARKER")); + + } + + @Test + void should_list_parents_as_array() { + + // Create the event template + final String eventTemplate = writeJson(asMap( + "parents", asMap( + "$resolver", "marker", + "field", "parents"))); + + // Create the layout. + final JsonTemplateLayout layout = JsonTemplateLayout + .newBuilder() + .setConfiguration(CONFIGURATION) + .setEventTemplate(eventTemplate) + .build(); + + // Create the log event. + final Marker parentMarker1 = MarkerManager.getMarker("PARENT_MARKER_NAME_1"); + final Marker parentMarker2 = MarkerManager.getMarker("PARENT_MARKER_NAME_2"); + final Marker childMarker = MarkerManager.getMarker("CHILD_MARKER_NAME"); + childMarker.setParents(parentMarker1, parentMarker2); + + final LogEvent logEvent = Log4jLogEvent + .newBuilder() + .setMarker(childMarker) + .build(); + + // Check the serialized event. + usingSerializedLogEventAccessor(layout, logEvent, accessor -> + assertThat(accessor.getList("parents", String.class)) + .containsOnly(parentMarker1.getName(), parentMarker2.getName())); + + } + +} diff --git a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/MarkerResolver.java b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/MarkerResolver.java index fc1c30c9bc..4975fd2a15 100644 --- a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/MarkerResolver.java +++ b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/MarkerResolver.java @@ -26,7 +26,7 @@ import org.apache.logging.log4j.layout.template.json.util.JsonWriter; * <h3>Configuration</h3> * * <pre> - * config = "field" -> "name" + * config = "field" -> ( "name" | "parents" ) * </pre> * * <h3>Examples</h3> @@ -39,6 +39,15 @@ import org.apache.logging.log4j.layout.template.json.util.JsonWriter; * "field": "name" * } * </pre> + * + * Resolve the names of the marker's parents: + * + * <pre> + * { + * "$resolver": "marker", + * "field": "parents" + * } + * </pre> */ public final class MarkerResolver implements EventResolver { @@ -52,6 +61,30 @@ public final class MarkerResolver implements EventResolver { } }; + private static final TemplateResolver<LogEvent> PARENTS_RESOLVER = + (final LogEvent logEvent, final JsonWriter jsonWriter) -> { + + // Short-circuit if there are no parents + final Marker marker = logEvent.getMarker(); + if (marker == null || !marker.hasParents()) { + jsonWriter.writeNull(); + return; + } + + // Write parents + final Marker[] parents = marker.getParents(); + jsonWriter.writeArrayStart(); + for (int parentIndex = 0; parentIndex < parents.length; parentIndex++) { + if (parentIndex > 0) { + jsonWriter.writeSeparator(); + } + final Marker parentMarker = parents[parentIndex]; + jsonWriter.writeString(parentMarker.getName()); + } + jsonWriter.writeArrayEnd(); + + }; + private final TemplateResolver<LogEvent> internalResolver; MarkerResolver(final TemplateResolverConfig config) { @@ -61,9 +94,15 @@ public final class MarkerResolver implements EventResolver { private TemplateResolver<LogEvent> createInternalResolver( final TemplateResolverConfig config) { final String fieldName = config.getString("field"); + if ("name".equals(fieldName)) { return NAME_RESOLVER; } + + if ("parents".equals(fieldName)) { + return PARENTS_RESOLVER; + } + throw new IllegalArgumentException("unknown field: " + config); } diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/internal/util/HierarchicalCollections.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/internal/util/HierarchicalCollections.java index dbeb78232d..18d0093b88 100644 --- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/internal/util/HierarchicalCollections.java +++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/internal/util/HierarchicalCollections.java @@ -16,12 +16,7 @@ */ package org.apache.logging.log4j.plugins.internal.util; -import java.util.AbstractMap; -import java.util.AbstractSet; -import java.util.Iterator; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; class HierarchicalCollections { diff --git a/log4j-to-slf4j/pom.xml b/log4j-to-slf4j/pom.xml index 66fe3e4a8d..f7543705b0 100644 --- a/log4j-to-slf4j/pom.xml +++ b/log4j-to-slf4j/pom.xml @@ -31,6 +31,7 @@ <docLabel>SLF4J Documentation</docLabel> <projectDir>/log4j-to-slf4j</projectDir> <module.name>org.apache.logging.slf4j</module.name> + <slf4j.support.bound>3</slf4j.support.bound> </properties> <dependencies> <dependency> @@ -91,6 +92,7 @@ <configuration> <instructions> <Export-Package>org.apache.logging.slf4j</Export-Package> + <Import-Package>org.slf4j*;version="${range;[==,${slf4j.support.bound})}",*</Import-Package> </instructions> </configuration> </plugin> diff --git a/pom.xml b/pom.xml index 786d2c52aa..9f6cb8412f 100644 --- a/pom.xml +++ b/pom.xml @@ -434,6 +434,7 @@ <jetty.version>9.4.50.v20221201</jetty.version> <jmdns.version>3.5.8</jmdns.version> <jmh.version>1.36</jmh.version> + <jna.version>5.12.1</jna.version> <json-unit.version>2.36.0</json-unit.version> <junit.version>4.13.2</junit.version> <junit-jupiter.version>5.9.1</junit-jupiter.version> @@ -982,6 +983,12 @@ <version>${jmh.version}</version> </dependency> + <dependency> + <groupId>net.java.dev.jna</groupId> + <artifactId>jna</artifactId> + <version>${jna.version}</version> + </dependency> + <dependency> <groupId>net.javacrumbs.json-unit</groupId> <artifactId>json-unit</artifactId> @@ -1353,7 +1360,7 @@ </plugin> <plugin> - <groupId>org.apache.felix</groupId> + <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-artifact-plugin</artifactId> <version>${maven-artifact-plugin.version}</version> </plugin> diff --git a/src/changelog/.2.x.x/1232_log4j-to-sfl4j-2-OSGiMetadata.xml b/src/changelog/.2.x.x/1232_log4j-to-sfl4j-2-OSGiMetadata.xml new file mode 100644 index 0000000000..b166412c83 --- /dev/null +++ b/src/changelog/.2.x.x/1232_log4j-to-sfl4j-2-OSGiMetadata.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://logging.apache.org/log4j/changelog" + xsi:schemaLocation="http://logging.apache.org/log4j/changelog https://logging.apache.org/log4j/changelog-0.1.0.xsd" + type="fixed"> + <issue id="1232" link="https://github.com/apache/logging-log4j2/issues/1232"/> + <author id="hanneswell"/> + <author name="Hannes Wellmann"/> + <description format="asciidoc"> + Adapt the OSGi metadata of log4j-to-slf4j to work with slf4j 1 and 2. + To achieve that use a version range of `[1.7,3)` for the imported slf4j packages. + </description> +</entry> diff --git a/src/changelog/.2.x.x/1366_fix_java_sql_date.xml b/src/changelog/.2.x.x/1366_fix_java_sql_date.xml new file mode 100644 index 0000000000..8a28a5bd2e --- /dev/null +++ b/src/changelog/.2.x.x/1366_fix_java_sql_date.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://logging.apache.org/log4j/changelog" + xsi:schemaLocation="http://logging.apache.org/log4j/changelog https://logging.apache.org/log4j/changelog-0.1.1.xsd" + type="fixed"> + <issue id="1366" link="https://github.com/apache/logging-log4j2/pull/1366"/> + <author id="Hikarikun92"/> + <author name="Lucas Souza"/> + <description format="asciidoc"> + Fixed logging of java.sql.Date objects by appending it before Log4J tries to call java.util.Date.toInstant() on it. + </description> +</entry> diff --git a/src/site/asciidoc/manual/json-template-layout.adoc.vm b/src/site/asciidoc/manual/json-template-layout.adoc.vm index f1bb103a21..ad61105033 100644 --- a/src/site/asciidoc/manual/json-template-layout.adoc.vm +++ b/src/site/asciidoc/manual/json-template-layout.adoc.vm @@ -743,6 +743,8 @@ Each `pointMatcherRegexes` item triggers a `Pattern#matcher()` call, which is not garbage-free either. ==== +====== Examples + Resolve `logEvent.getThrown().getClass().getCanonicalName()`: [source,json] @@ -849,6 +851,8 @@ severity-field = "field" -> ( "keyword" | "code" ) Resolves the fields of the `logEvent.getLevel()`. +====== Examples + Resolve the level name: [source,json] @@ -897,6 +901,8 @@ config = "field" -> ( "name" | "fqcn" ) Resolves `logEvent.getLoggerFqcn()` and `logEvent.getLoggerName()`. +====== Examples + Resolve the logger name: [source,json] @@ -930,6 +936,8 @@ key = "key" -> string Performs link:lookups.html#AppMainArgsLookup[Main Argument Lookup] for the given `index` or `key`. +====== Examples + Resolve the 1st `main()` method argument: [source,json] @@ -956,6 +964,38 @@ Resolve the argument coming right after `--userId`: Resolves ``MapMessage``s. See link:#map-resolver-template[Map Resolver Template] for details. +[#event-template-resolver-marker] +===== `marker` + +[source] +---- +config = "field" -> ( "name" | "parents" ) +---- + +Resolves `logEvent.getMarker()`. + +====== Examples + +Resolve the marker name: + +[source,json] +---- +{ + "$resolver": "marker", + "field": "name" +} +---- + +Resolve the names of the marker's parents: + +[source,json] +---- +{ + "$resolver": "marker", + "field": "parents" +} +---- + [#event-template-resolver-mdc] ===== `mdc` @@ -986,6 +1026,8 @@ For simple string messages, the resolution is performed without allocations. For ``ObjectMessage``s and ``MultiformatMessage``s, it depends. ==== +====== Examples + Resolve the message into a string: [source,json] @@ -1047,6 +1089,8 @@ Regarding garbage footprint, `stringified` flag translates to which is the case if `log4j2.enableThreadLocals` property set to true. ==== +====== Examples + Resolve the message parameters into an array: [source,json] @@ -1099,6 +1143,8 @@ pattern = "pattern" -> string Resolves the Nested Diagnostic Context (NDC), aka. Thread Context Stack, `String[]` returned by `logEvent.getContextStack()`. +====== Examples + Resolve all NDC values into a list: [source,json] @@ -1133,6 +1179,8 @@ Resolver delegating to link:layouts.html#PatternLayout[`PatternLayout`]. The default value of `stackTraceEnabled` is inherited from the parent `JsonTemplateLayout`. +====== Examples + Resolve the string produced by `%p %c{1.} [%t] %X{userId} %X %m%ex` pattern: [source,json] @@ -1161,6 +1209,8 @@ Resolves the fields of the `StackTraceElement` returned by Note that this resolver is toggled by `log4j.layout.jsonTemplate.locationInfoEnabled` property. +====== Examples + Resolve the line number: [source,json] @@ -1182,6 +1232,8 @@ config = "field" -> ( "name" | "id" | "priority" ) Resolves `logEvent.getThreadId()`, `logEvent.getThreadName()`, `logEvent.getThreadPriority()`. +====== Examples + Resolve the thread name: [source,json] @@ -1221,6 +1273,8 @@ rounded = "rounded" -> boolean Resolves `logEvent.getInstant()` in various forms. +====== Examples + .`timestamp` template resolver examples [cols="5,2m"] |===
