You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tika.apache.org by ta...@apache.org on 2021/12/14 20:28:43 UTC

[tika] branch branch_1x updated: TIKA-3618 -- upgrade to log4j2 in the 1.x branch

This is an automated email from the ASF dual-hosted git repository.

tallison pushed a commit to branch branch_1x
in repository https://gitbox.apache.org/repos/asf/tika.git


The following commit(s) were added to refs/heads/branch_1x by this push:
     new 705d06a  TIKA-3618 -- upgrade to log4j2 in the 1.x branch
705d06a is described below

commit 705d06a5742b02cd5aea87e49b2b811274d440d4
Author: tallison <ta...@apache.org>
AuthorDate: Tue Dec 14 15:28:25 2021 -0500

    TIKA-3618 -- upgrade to log4j2 in the 1.x branch
---
 CHANGES.txt                                        |   6 +-
 tika-app/pom.xml                                   |   8 +-
 .../apache/tika/cli/BatchCommandLineBuilder.java   |   6 +-
 .../src/main/java/org/apache/tika/cli/TikaCLI.java |  31 +--
 tika-app/src/main/resources/log4j2.xml             |  32 +++
 .../resources/log4j2_batch_process.properties}     |  23 +-
 .../tika/cli/TikaCLIBatchCommandLineTest.java      |   4 +-
 .../tika/cli/TikaCLIBatchIntegrationTest.java      |  27 +--
 .../log4j2_batch_process_test.properties}          |  23 +-
 tika-batch/pom.xml                                 |   4 +-
 .../org/apache/tika/batch/fs/BatchDriverTest.java  |   4 +-
 .../org/apache/tika/batch/fs/BatchProcessTest.java |  11 +-
 .../org/apache/tika/batch/fs/FSBatchTestBase.java  |   8 +-
 tika-batch/src/test/resources/log4j.properties     |  25 --
 .../{log4j-on.properties => log4j2-on.properties}  |  28 +--
 tika-batch/src/test/resources/log4j2.xml           |  32 +++
 .../src/test/resources/log4j2_process.properties   |  24 +-
 .../src/test/resources/log4j_process.properties    |  27 ---
 tika-bundle/pom.xml                                |   1 -
 tika-bundle/src/test/resources/log4j.properties    |  24 --
 tika-bundle/src/test/resources/log4j2.xml          |  32 +++
 tika-core/pom.xml                                  |   4 +-
 tika-core/src/test/resources/log4j.properties      |  24 --
 tika-core/src/test/resources/log4j2.xml            |  32 +++
 tika-dl/pom.xml                                    |   4 +-
 .../org/apache/tika/eval/XMLErrorLogUpdater.java   |   3 +-
 .../org/apache/tika/eval/io/XMLLogMsgHandler.java  |   3 +-
 .../java/org/apache/tika/eval/io/XMLLogReader.java |   4 +-
 tika-eval/src/main/resources/log4j.properties      |  21 --
 tika-eval/src/main/resources/log4j2.xml            |  32 +++
 tika-fuzzing/pom.xml                               |   4 +-
 tika-fuzzing/src/main/resources/log4j.properties   |  24 --
 tika-fuzzing/src/main/resources/log4j2.xml         |  32 +++
 tika-langdetect/pom.xml                            |   5 +-
 .../src/test/resources/log4j.properties            |  24 --
 tika-langdetect/src/test/resources/log4j2.xml      |  32 +++
 tika-nlp/pom.xml                                   |   5 +-
 tika-parent/pom.xml                                |  43 +++-
 tika-parsers/pom.xml                               |   4 +-
 .../tika/parser/microsoft/WordParserTest.java      |  15 +-
 .../org/apache/tika/parser/pdf/PDFParserTest.java  |   8 +-
 tika-parsers/src/test/resources/log4j.properties   |  24 --
 tika-parsers/src/test/resources/log4j2.xml         |  32 +++
 tika-server/bin/tika.in.sh                         |   4 +-
 tika-server/pom.xml                                |   9 +-
 .../apache/tika/server/metrics/Log4JMetrics.java   | 212 -----------------
 .../apache/tika/server/metrics/Log4j2Metrics.java  | 257 +++++++++++++++++++++
 .../apache/tika/server/metrics/MetricsHelper.java  |   2 +-
 tika-server/src/main/resources/log4j.properties    |  24 --
 tika-server/src/main/resources/log4j2.xml          |  32 +++
 .../apache/tika/server/MetricsResourceTest.java    |   7 +-
 .../tika/server/TikaServerIntegrationTest.java     |   2 +-
 tika-server/src/test/resources/log4j.properties    |  24 --
 tika-server/src/test/resources/log4j2.xml          |  32 +++
 54 files changed, 757 insertions(+), 607 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 414fc1f..75b71d8 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,8 @@
-Release 1.27.1 - ???
+Release 1.28 - ???
+
+   * Upgrade log4j 1.x to log4j2 2.16.0.  Users will likely
+     want to upgrade their logging configurations from log4j
+     to log4j2 (TIKA-3618).
 
    * General dependency upgrades (TIKA-3613).
 
diff --git a/tika-app/pom.xml b/tika-app/pom.xml
index 703c6a4..fac535f 100644
--- a/tika-app/pom.xml
+++ b/tika-app/pom.xml
@@ -66,8 +66,12 @@
 
     <!-- logging -->
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
     </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
diff --git a/tika-app/src/main/java/org/apache/tika/cli/BatchCommandLineBuilder.java b/tika-app/src/main/java/org/apache/tika/cli/BatchCommandLineBuilder.java
index f953db3..7c2ba56 100644
--- a/tika-app/src/main/java/org/apache/tika/cli/BatchCommandLineBuilder.java
+++ b/tika-app/src/main/java/org/apache/tika/cli/BatchCommandLineBuilder.java
@@ -62,14 +62,14 @@ class BatchCommandLineBuilder {
 
         boolean hasLog4j = false;
         for (String k : jvmOpts.keySet()) {
-            if (k.startsWith("-Dlog4j.configuration=")) {
+            if (k.startsWith("-Dlog4j.configurationFile=")) {
                 hasLog4j = true;
                 break;
             }
         }
-        //use the log4j config file inside the app /resources/log4j_batch_process.properties
+        //use the log4j config file inside the app /resources/log4j2_batch_process.properties
         if (! hasLog4j) {
-            jvmOpts.put("-Dlog4j.configuration=log4j_batch_process.properties", "");
+            jvmOpts.put("-Dlog4j.configurationFile=log4j2_batch_process.properties", "");
         }
         //now build the full command line
         List<String> fullCommand = new ArrayList<String>();
diff --git a/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java b/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
index b115ef2..ce7e65a 100644
--- a/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
+++ b/tika-app/src/main/java/org/apache/tika/cli/TikaCLI.java
@@ -48,7 +48,6 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.Comparator;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -62,9 +61,7 @@ import java.util.UUID;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.input.CloseShieldInputStream;
-import org.apache.log4j.Level;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.PropertyConfigurator;
+import org.apache.logging.log4j.Level;
 import org.apache.poi.poifs.filesystem.DirectoryEntry;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
 import org.apache.poi.poifs.filesystem.DocumentInputStream;
@@ -82,7 +79,6 @@ import org.apache.tika.gui.TikaGUI;
 import org.apache.tika.io.TikaInputStream;
 import org.apache.tika.language.detect.LanguageHandler;
 import org.apache.tika.metadata.Metadata;
-import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.metadata.serialization.JsonMetadata;
 import org.apache.tika.metadata.serialization.JsonMetadataList;
 import org.apache.tika.mime.MediaType;
@@ -131,10 +127,6 @@ public class TikaCLI {
     public static void main(String[] args) throws Exception {
         TikaCLI cli = new TikaCLI();
 
-        if (!isConfigured()) {
-            PropertyConfigurator.configure(cli.getClass().getResourceAsStream("/log4j.properties"));
-        }
-
         if (cli.testForHelp(args)) {
             cli.usage();
             return;
@@ -167,23 +159,6 @@ public class TikaCLI {
         }
     }
 
-    private static boolean isConfigured() {
-        //Borrowed from: http://wiki.apache.org/logging-log4j/UsefulCode
-        Enumeration appenders = LogManager.getRootLogger().getAllAppenders();
-        if (appenders.hasMoreElements()) {
-            return true;
-        }
-        else {
-            Enumeration loggers = LogManager.getCurrentLoggers() ;
-            while (loggers.hasMoreElements()) {
-                org.apache.log4j.Logger c = (org.apache.log4j.Logger) loggers.nextElement();
-                if (c.getAllAppenders().hasMoreElements())
-                    return true;
-            }
-        }
-        return false;
-    }
-
     private void extractInlineImagesFromPDFs() {
         if (configFilePath == null && context.get(PDFParserConfig.class) == null) {
             PDFParserConfig pdfParserConfig = new PDFParserConfig();
@@ -376,7 +351,7 @@ public class TikaCLI {
             pipeMode = false;
             version();
         } else if (arg.equals("-v") || arg.equals("--verbose")) {
-            org.apache.log4j.Logger.getRootLogger().setLevel(Level.DEBUG);
+            org.apache.logging.log4j.core.config.Configurator.setRootLevel(Level.DEBUG);
         } else if (arg.equals("-g") || arg.equals("--gui")) {
             pipeMode = false;
             if (configFilePath != null){
@@ -664,7 +639,7 @@ public class TikaCLI {
         out.println("    Control the type of output with -x, -h, -t and/or -J.");
         out.println();
         out.println("    To modify child process jvm args, prepend \"J\" as in:");
-        out.println("    -JXmx4g or -JDlog4j.configuration=file:log4j.xml.");
+        out.println("    -JXmx4g or -JDlog4j.configurationFile=log4j.xml.");
     }
 
     private void version() {
diff --git a/tika-app/src/main/resources/log4j2.xml b/tika-app/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..c88e66e
--- /dev/null
+++ b/tika-app/src/main/resources/log4j2.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+
+<!--
+  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.
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_ERR">
+      <PatternLayout pattern="%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/tika-app/src/test/resources/log4j_batch_process_test.properties b/tika-app/src/main/resources/log4j2_batch_process.properties
similarity index 66%
rename from tika-app/src/test/resources/log4j_batch_process_test.properties
rename to tika-app/src/main/resources/log4j2_batch_process.properties
index 6404cc9..8715133 100644
--- a/tika-app/src/test/resources/log4j_batch_process_test.properties
+++ b/tika-app/src/main/resources/log4j2_batch_process.properties
@@ -1,3 +1,4 @@
+#
 # 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.
@@ -12,13 +13,17 @@
 # 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.
-
 #info,debug, error,fatal ...
-log4j.rootLogger=trace,stdout
-
-#console
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-
-
-log4j.appender.stdout.layout.ConversionPattern=MY_CUSTOM_LOG_CONFIG %m%n
+status=info
+name=PropertiesConfig
+filters=threshold
+filter.threshold.type=ThresholdFilter
+filter.threshold.level=info
+appenders=console
+appender.console.type=Console
+appender.console.name=STDOUT
+appender.console.layout.type=PatternLayout
+appender.console.layout.pattern=%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n
+rootLogger.level=info
+rootLogger.appenderRefs=stdout
+rootLogger.appenderRef.stdout.ref=STDOUT
diff --git a/tika-app/src/test/java/org/apache/tika/cli/TikaCLIBatchCommandLineTest.java b/tika-app/src/test/java/org/apache/tika/cli/TikaCLIBatchCommandLineTest.java
index a5f95ea..1a047c1 100644
--- a/tika-app/src/test/java/org/apache/tika/cli/TikaCLIBatchCommandLineTest.java
+++ b/tika-app/src/test/java/org/apache/tika/cli/TikaCLIBatchCommandLineTest.java
@@ -82,7 +82,7 @@ public class TikaCLIBatchCommandLineTest {
 
     @Test
     public void testJVMOpts() throws Exception {
-        String[] params = {"-JXmx1g", "-JDlog4j.configuration=batch_process_log4j.xml", "-inputDir",
+        String[] params = {"-JXmx1g", "-JDlog4j.configurationFile=log4j2_batch_process_test.properties", "-inputDir",
                 testInputPathForCommandLine, "-outputDir", "testout-output"};
 
 
@@ -108,7 +108,7 @@ public class TikaCLIBatchCommandLineTest {
     
     @Test
     public void testBasicMappingOfArgs() throws Exception {
-        String[] params = {"-JXmx1g", "-JDlog4j.configuration=batch_process_log4j.xml",
+        String[] params = {"-JXmx1g", "-JDlog4j.configurationFile=log4j2_batch_process_test.properties",
                 "-bc", "batch-config.xml",
                 "-J", "-h", "-inputDir", testInputPathForCommandLine};
 
diff --git a/tika-app/src/test/java/org/apache/tika/cli/TikaCLIBatchIntegrationTest.java b/tika-app/src/test/java/org/apache/tika/cli/TikaCLIBatchIntegrationTest.java
index 0d22b36..b744d0a 100644
--- a/tika-app/src/test/java/org/apache/tika/cli/TikaCLIBatchIntegrationTest.java
+++ b/tika-app/src/test/java/org/apache/tika/cli/TikaCLIBatchIntegrationTest.java
@@ -23,45 +23,31 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import java.io.BufferedWriter;
 import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.OutputStreamWriter;
 import java.io.PrintStream;
 import java.io.Reader;
-import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.List;
-import java.util.logging.Handler;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.serialization.JsonMetadataList;
-import org.apache.tika.metadata.serialization.JsonStreamingSerializer;
-import org.apache.tika.parser.AutoDetectParser;
-import org.apache.tika.parser.ParseContext;
-import org.apache.tika.parser.Parser;
-import org.apache.tika.parser.RecursiveParserWrapper;
 import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
-import org.apache.tika.sax.BasicContentHandlerFactory;
-import org.apache.tika.sax.ContentHandlerFactory;
-import org.apache.tika.sax.RecursiveParserWrapperHandler;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXException;
 
 public class TikaCLIBatchIntegrationTest {
 
+    private final String propsFileName = "log4j2_batch_process_test.properties";
     private Path testInputDir = Paths.get("src/test/resources/test-data");
     private String testInputDirForCommandLine;
     private Path tempOutputDir;
     private String tempOutputDirForCommandLine;
+    private Path customBatchLogging;
     private OutputStream out = null;
     private OutputStream err = null;
     private ByteArrayOutputStream outBuffer = null;
@@ -79,6 +65,9 @@ public class TikaCLIBatchIntegrationTest {
         System.setErr(errWriter);
         testInputDirForCommandLine = testInputDir.toAbsolutePath().toString();
         tempOutputDirForCommandLine = tempOutputDir.toAbsolutePath().toString();
+        customBatchLogging = tempOutputDir.resolve(propsFileName);
+        Files.copy(this.getClass().getResourceAsStream("/" + propsFileName), customBatchLogging);
+
     }
 
     @After
@@ -152,10 +141,8 @@ public class TikaCLIBatchIntegrationTest {
 
     @Test
     public void testProcessLogFileConfig() throws Exception {
-        String[] params = {"-i", testInputDirForCommandLine,
-                "-o", tempOutputDirForCommandLine,
-                "-numConsumers", "2",
-                "-JDlog4j.configuration=log4j_batch_process_test.properties"};
+        String[] params = {"-i", testInputDirForCommandLine, "-o", tempOutputDirForCommandLine,
+                "-numConsumers", "2", "-JDlog4j.configurationFile=" + customBatchLogging.toUri()};
         TikaCLI.main(params);
 
         assertFileExists(tempOutputDir.resolve("bad_xml.xml.xml"));
diff --git a/tika-app/src/main/resources/log4j_batch_process.properties b/tika-app/src/test/resources/log4j2_batch_process_test.properties
similarity index 67%
rename from tika-app/src/main/resources/log4j_batch_process.properties
rename to tika-app/src/test/resources/log4j2_batch_process_test.properties
index 9fc74fd..ce40c70 100644
--- a/tika-app/src/main/resources/log4j_batch_process.properties
+++ b/tika-app/src/test/resources/log4j2_batch_process_test.properties
@@ -1,3 +1,4 @@
+#
 # 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.
@@ -12,13 +13,17 @@
 # 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.
-
 #info,debug, error,fatal ...
-log4j.rootLogger=info,stdout
-
-#console
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-
-
-log4j.appender.stdout.layout.ConversionPattern=%m%n
+status=trace
+name=PropertiesConfig
+filters=threshold
+filter.threshold.type=ThresholdFilter
+filter.threshold.level=trace
+appenders=console
+appender.console.type=Console
+appender.console.name=STDOUT
+appender.console.layout.type=PatternLayout
+appender.console.layout.pattern=MY_CUSTOM_LOG_CONFIG %m%n
+rootLogger.level=trace
+rootLogger.appenderRefs=stdout
+rootLogger.appenderRef.stdout.ref=STDOUT
diff --git a/tika-batch/pom.xml b/tika-batch/pom.xml
index ba9fce1..640debe 100644
--- a/tika-batch/pom.xml
+++ b/tika-batch/pom.xml
@@ -79,8 +79,8 @@
 
     <!-- logging -->
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
     </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
diff --git a/tika-batch/src/test/java/org/apache/tika/batch/fs/BatchDriverTest.java b/tika-batch/src/test/java/org/apache/tika/batch/fs/BatchDriverTest.java
index 643e7cb..3e0a79e 100644
--- a/tika-batch/src/test/java/org/apache/tika/batch/fs/BatchDriverTest.java
+++ b/tika-batch/src/test/java/org/apache/tika/batch/fs/BatchDriverTest.java
@@ -34,8 +34,8 @@ import org.junit.Test;
 
 public class BatchDriverTest extends FSBatchTestBase {
 
-    //for debugging, turn logging off/on via resources/log4j.properties for the driver
-    //and log4j_process.properties for the process.
+    //for debugging, turn logging off/on via resources/log4j2.properties for the driver
+    //and log4j2_process.properties for the process.
 
     @Test(timeout = 15000)
     public void oneHeavyHangTest() throws Exception {
diff --git a/tika-batch/src/test/java/org/apache/tika/batch/fs/BatchProcessTest.java b/tika-batch/src/test/java/org/apache/tika/batch/fs/BatchProcessTest.java
index 2dcc15e..6ba843a 100644
--- a/tika-batch/src/test/java/org/apache/tika/batch/fs/BatchProcessTest.java
+++ b/tika-batch/src/test/java/org/apache/tika/batch/fs/BatchProcessTest.java
@@ -301,12 +301,13 @@ public class BatchProcessTest extends FSBatchTestBase {
         args.put("recursiveParserWrapper", "true");
         args.put("basicHandlerType", "text");
 
-        BatchProcessTestExecutor ex = new BatchProcessTestExecutor(args,
-                "/tika-batch-config-MockConsumersBuilder.xml",
-                "/log4j-on.properties");
+        BatchProcessTestExecutor ex =
+                new BatchProcessTestExecutor(args, "/tika-batch-config-MockConsumersBuilder.xml",
+                        "/log4j2-on.properties");
         StreamStrings ss = ex.execute();
         assertFalse(ss.getOutString().contains("error writing xml stream for"));
         assertContains("parse_ex resourceId=\"test0_bad_chars.xml\"", ss.getOutString());
+
     }
 
     @Test
@@ -320,7 +321,7 @@ public class BatchProcessTest extends FSBatchTestBase {
 
         BatchProcessTestExecutor ex = new BatchProcessTestExecutor(args,
                 "/tika-batch-config-test-suffix-override.xml",
-                "/log4j-on.properties");
+                "/log4j2-on.properties");
         ex.execute();
         Path targ = outputDir.resolve("test0.xml.mysuffix");
         assertTrue(Files.isRegularFile(targ));
@@ -339,7 +340,7 @@ public class BatchProcessTest extends FSBatchTestBase {
 
 
         public BatchProcessTestExecutor(Map<String, String> args, String configPath) {
-            this(args, configPath, "/log4j_process.properties");
+            this(args, configPath, "/log4j2_process.properties");
         }
 
         public BatchProcessTestExecutor(Map<String, String> args, String configPath, String loggerProps) {
diff --git a/tika-batch/src/test/java/org/apache/tika/batch/fs/FSBatchTestBase.java b/tika-batch/src/test/java/org/apache/tika/batch/fs/FSBatchTestBase.java
index ec0c3d9..06050c6 100644
--- a/tika-batch/src/test/java/org/apache/tika/batch/fs/FSBatchTestBase.java
+++ b/tika-batch/src/test/java/org/apache/tika/batch/fs/FSBatchTestBase.java
@@ -21,6 +21,7 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URISyntaxException;
+import java.net.URL;
 import java.nio.charset.Charset;
 import java.nio.file.DirectoryStream;
 import java.nio.file.FileVisitResult;
@@ -171,8 +172,7 @@ public abstract class FSBatchTestBase extends TikaTest {
         List<String> commandLine = new ArrayList<>();
         commandLine.add("java");
         commandLine.add("-Djava.awt.headless=true");
-        commandLine.add("-Dlog4j.configuration=file:"+
-            this.getClass().getResource(loggerProps).getFile());
+        commandLine.add("-Dlog4j.configurationFile=" + getResourceAsUrl(loggerProps).getFile());
         commandLine.add("-Xmx128m");
         commandLine.add("-cp");
         String cp = System.getProperty("java.class.path");
@@ -281,4 +281,8 @@ public abstract class FSBatchTestBase extends TikaTest {
         }
         return list;
     }
+
+    public URL getResourceAsUrl(String name) {
+        return this.getClass().getResource(name);
+    }
 }
diff --git a/tika-batch/src/test/resources/log4j.properties b/tika-batch/src/test/resources/log4j.properties
deleted file mode 100644
index a4901bd..0000000
--- a/tika-batch/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,25 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-log4j.rootLogger=OFF
-
-#for debugging
-#log4j.rootLogger=TRACE,A1
-
-log4j.appender.A1=org.apache.log4j.ConsoleAppender
-
-# A1 uses PatternLayout.
-log4j.appender.A1.layout=org.apache.log4j.PatternLayout
-log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
diff --git a/tika-batch/src/test/resources/log4j-on.properties b/tika-batch/src/test/resources/log4j2-on.properties
similarity index 63%
rename from tika-batch/src/test/resources/log4j-on.properties
rename to tika-batch/src/test/resources/log4j2-on.properties
index 60a0be3..3b8c00e 100644
--- a/tika-batch/src/test/resources/log4j-on.properties
+++ b/tika-batch/src/test/resources/log4j2-on.properties
@@ -1,3 +1,4 @@
+#
 # 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.
@@ -12,16 +13,17 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-
-#This is used by the batch process; see log4j.properties for the driver
-
-log4j.rootLogger=WARN,A1
-
-#for debugging
-#log4j.rootLogger=TRACE,A1
-
-log4j.appender.A1=org.apache.log4j.ConsoleAppender
-
-# A1 uses PatternLayout.
-log4j.appender.A1.layout=org.apache.log4j.PatternLayout
-log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+#This is used by the batch process; see log4j2.properties for the driver
+status=warn
+name=PropertiesConfig
+filters=threshold
+filter.threshold.type=ThresholdFilter
+filter.threshold.level=warn
+appenders=console
+appender.console.type=Console
+appender.console.name=STDERR
+appender.console.layout.type=PatternLayout
+appender.console.layout.pattern=%-5p %m%n
+rootLogger.level=warn
+rootLogger.appenderRefs=stderr
+rootLogger.appenderRef.stderr.ref=STDERR
diff --git a/tika-batch/src/test/resources/log4j2.xml b/tika-batch/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..c88e66e
--- /dev/null
+++ b/tika-batch/src/test/resources/log4j2.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+
+<!--
+  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.
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_ERR">
+      <PatternLayout pattern="%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/tika-app/src/main/resources/log4j.properties b/tika-batch/src/test/resources/log4j2_process.properties
similarity index 67%
rename from tika-app/src/main/resources/log4j.properties
rename to tika-batch/src/test/resources/log4j2_process.properties
index 7d3b372..dca624f 100644
--- a/tika-app/src/main/resources/log4j.properties
+++ b/tika-batch/src/test/resources/log4j2_process.properties
@@ -1,3 +1,4 @@
+#
 # 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.
@@ -12,13 +13,16 @@
 # 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.
-
-#info,debug, error,fatal ...
-log4j.rootLogger=info,stderr
-
-#console
-log4j.appender.stderr=org.apache.log4j.ConsoleAppender
-log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
-log4j.appender.stderr.Target=System.err
-
-log4j.appender.stderr.layout.ConversionPattern= %-5p %m%n
+status=error
+name=PropertiesConfig
+filters=threshold
+filter.threshold.type=ThresholdFilter
+filter.threshold.level=error
+appenders=console
+appender.console.type=Console
+appender.console.name=STDERR
+appender.console.layout.type=PatternLayout
+appender.console.layout.pattern=%-5p %m%n
+rootLogger.level=ERROR
+rootLogger.appenderRefs=stderr
+rootLogger.appenderRef.stderr.ref=STDERR
diff --git a/tika-batch/src/test/resources/log4j_process.properties b/tika-batch/src/test/resources/log4j_process.properties
deleted file mode 100644
index 9b598a1..0000000
--- a/tika-batch/src/test/resources/log4j_process.properties
+++ /dev/null
@@ -1,27 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#This is used by the batch process; see log4j.properties for the driver
-
-log4j.rootLogger=OFF
-
-#for debugging
-#log4j.rootLogger=TRACE,A1
-
-log4j.appender.A1=org.apache.log4j.ConsoleAppender
-
-# A1 uses PatternLayout.
-log4j.appender.A1.layout=org.apache.log4j.PatternLayout
-log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
diff --git a/tika-bundle/pom.xml b/tika-bundle/pom.xml
index 09c7610..d874ee3 100644
--- a/tika-bundle/pom.xml
+++ b/tika-bundle/pom.xml
@@ -544,7 +544,6 @@
               org.apache.http.protocol;resolution:=optional,
               org.apache.http.util;resolution:=optional,
               org.apache.commons.logging;resolution:=optional,
-              org.apache.log4j;resolution:=optional,
               *
             </Import-Package>
           </instructions>
diff --git a/tika-bundle/src/test/resources/log4j.properties b/tika-bundle/src/test/resources/log4j.properties
deleted file mode 100644
index 7d3b372..0000000
--- a/tika-bundle/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#info,debug, error,fatal ...
-log4j.rootLogger=info,stderr
-
-#console
-log4j.appender.stderr=org.apache.log4j.ConsoleAppender
-log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
-log4j.appender.stderr.Target=System.err
-
-log4j.appender.stderr.layout.ConversionPattern= %-5p %m%n
diff --git a/tika-bundle/src/test/resources/log4j2.xml b/tika-bundle/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..c88e66e
--- /dev/null
+++ b/tika-bundle/src/test/resources/log4j2.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+
+<!--
+  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.
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_ERR">
+      <PatternLayout pattern="%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/tika-core/pom.xml b/tika-core/pom.xml
index 3ef49e9..11aa4c3 100644
--- a/tika-core/pom.xml
+++ b/tika-core/pom.xml
@@ -69,8 +69,8 @@
 
         <!-- Test dependencies -->
         <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/tika-core/src/test/resources/log4j.properties b/tika-core/src/test/resources/log4j.properties
deleted file mode 100644
index f2c0b92..0000000
--- a/tika-core/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#info,debug, error,fatal ...
-log4j.rootLogger=info,stdout
-
-#console
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-
-# Pattern to output the caller's file name and line number.
-log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
diff --git a/tika-core/src/test/resources/log4j2.xml b/tika-core/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..c88e66e
--- /dev/null
+++ b/tika-core/src/test/resources/log4j2.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+
+<!--
+  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.
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_ERR">
+      <PatternLayout pattern="%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/tika-dl/pom.xml b/tika-dl/pom.xml
index 527891b..4a93f19 100644
--- a/tika-dl/pom.xml
+++ b/tika-dl/pom.xml
@@ -383,8 +383,8 @@
       <version>2.8.0</version>
     </dependency>
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
       <scope>test</scope>
     </dependency>
   </dependencies>
diff --git a/tika-eval/src/main/java/org/apache/tika/eval/XMLErrorLogUpdater.java b/tika-eval/src/main/java/org/apache/tika/eval/XMLErrorLogUpdater.java
index 4260c1a..1b10f95 100644
--- a/tika-eval/src/main/java/org/apache/tika/eval/XMLErrorLogUpdater.java
+++ b/tika-eval/src/main/java/org/apache/tika/eval/XMLErrorLogUpdater.java
@@ -32,7 +32,6 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 
-import org.apache.log4j.Level;
 import org.apache.tika.eval.db.Cols;
 import org.apache.tika.eval.db.H2Util;
 import org.apache.tika.eval.db.JDBCUtil;
@@ -41,6 +40,8 @@ import org.apache.tika.eval.io.XMLLogMsgHandler;
 import org.apache.tika.eval.io.XMLLogReader;
 import org.apache.tika.eval.reports.ResultsReporter;
 import org.apache.tika.io.IOExceptionWithCause;
+
+import org.apache.logging.log4j.Level;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/tika-eval/src/main/java/org/apache/tika/eval/io/XMLLogMsgHandler.java b/tika-eval/src/main/java/org/apache/tika/eval/io/XMLLogMsgHandler.java
index 2d509f7..66ed662 100644
--- a/tika-eval/src/main/java/org/apache/tika/eval/io/XMLLogMsgHandler.java
+++ b/tika-eval/src/main/java/org/apache/tika/eval/io/XMLLogMsgHandler.java
@@ -19,7 +19,8 @@ package org.apache.tika.eval.io;
 import java.io.IOException;
 import java.sql.SQLException;
 
-import org.apache.log4j.Level;
+import org.apache.logging.log4j.Level;
+
 
 public interface XMLLogMsgHandler {
     public void handleMsg(Level level, String xml) throws IOException, SQLException;
diff --git a/tika-eval/src/main/java/org/apache/tika/eval/io/XMLLogReader.java b/tika-eval/src/main/java/org/apache/tika/eval/io/XMLLogReader.java
index 87e4c40..479c8cb 100644
--- a/tika-eval/src/main/java/org/apache/tika/eval/io/XMLLogReader.java
+++ b/tika-eval/src/main/java/org/apache/tika/eval/io/XMLLogReader.java
@@ -25,10 +25,10 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.sql.SQLException;
 
-import org.apache.log4j.Level;
 import org.apache.tika.io.IOUtils;
-import org.apache.tika.parser.ParseContext;
 import org.apache.tika.utils.XMLReaderUtils;
+
+import org.apache.logging.log4j.Level;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/tika-eval/src/main/resources/log4j.properties b/tika-eval/src/main/resources/log4j.properties
deleted file mode 100644
index 474f528..0000000
--- a/tika-eval/src/main/resources/log4j.properties
+++ /dev/null
@@ -1,21 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-log4j.rootLogger=INFO,A1
-
-log4j.appender.A1=org.apache.log4j.ConsoleAppender
-
-# A1 uses PatternLayout.
-log4j.appender.A1.layout=org.apache.log4j.PatternLayout
-log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
diff --git a/tika-eval/src/main/resources/log4j2.xml b/tika-eval/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..c88e66e
--- /dev/null
+++ b/tika-eval/src/main/resources/log4j2.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+
+<!--
+  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.
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_ERR">
+      <PatternLayout pattern="%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/tika-fuzzing/pom.xml b/tika-fuzzing/pom.xml
index 2b50e7e..4022ecd 100644
--- a/tika-fuzzing/pom.xml
+++ b/tika-fuzzing/pom.xml
@@ -45,8 +45,8 @@
         </dependency>
         <!-- logging -->
         <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
diff --git a/tika-fuzzing/src/main/resources/log4j.properties b/tika-fuzzing/src/main/resources/log4j.properties
deleted file mode 100644
index 7d3b372..0000000
--- a/tika-fuzzing/src/main/resources/log4j.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#info,debug, error,fatal ...
-log4j.rootLogger=info,stderr
-
-#console
-log4j.appender.stderr=org.apache.log4j.ConsoleAppender
-log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
-log4j.appender.stderr.Target=System.err
-
-log4j.appender.stderr.layout.ConversionPattern= %-5p %m%n
diff --git a/tika-fuzzing/src/main/resources/log4j2.xml b/tika-fuzzing/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..c88e66e
--- /dev/null
+++ b/tika-fuzzing/src/main/resources/log4j2.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+
+<!--
+  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.
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_ERR">
+      <PatternLayout pattern="%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/tika-langdetect/pom.xml b/tika-langdetect/pom.xml
index ea48ea5..97fa3fe 100644
--- a/tika-langdetect/pom.xml
+++ b/tika-langdetect/pom.xml
@@ -95,10 +95,11 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
       <scope>test</scope>
     </dependency>
+
   </dependencies>
   
   <build>
diff --git a/tika-langdetect/src/test/resources/log4j.properties b/tika-langdetect/src/test/resources/log4j.properties
deleted file mode 100644
index f2c0b92..0000000
--- a/tika-langdetect/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#info,debug, error,fatal ...
-log4j.rootLogger=info,stdout
-
-#console
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-
-# Pattern to output the caller's file name and line number.
-log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
diff --git a/tika-langdetect/src/test/resources/log4j2.xml b/tika-langdetect/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..c88e66e
--- /dev/null
+++ b/tika-langdetect/src/test/resources/log4j2.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+
+<!--
+  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.
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_ERR">
+      <PatternLayout pattern="%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/tika-nlp/pom.xml b/tika-nlp/pom.xml
index ef70437..13cad9c 100644
--- a/tika-nlp/pom.xml
+++ b/tika-nlp/pom.xml
@@ -224,10 +224,11 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
       <scope>test</scope>
     </dependency>
+
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
diff --git a/tika-parent/pom.xml b/tika-parent/pom.xml
index 2878ff9..22778c6 100644
--- a/tika-parent/pom.xml
+++ b/tika-parent/pom.xml
@@ -283,7 +283,7 @@
 
     <cxf.version>3.4.5</cxf.version>
     <slf4j.version>1.7.30</slf4j.version>
-    <log4j.version>1.2.17</log4j.version>
+    <log4j2.version>2.16.0</log4j2.version>
     <jackson.version>2.13.0</jackson.version>
     <!-- when this is next upgraded, see if we can get rid of
          javax.activation dependency in tika-server.
@@ -308,7 +308,21 @@
         <artifactId>jaxb-runtime</artifactId>
         <version>${jaxb.version}</version>
       </dependency>
-
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-core</artifactId>
+        <version>${log4j2.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-api</artifactId>
+        <version>${log4j2.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-slf4j-impl</artifactId>
+        <version>${log4j2.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.felix</groupId>
         <artifactId>org.apache.felix.scr.annotations</artifactId>
@@ -327,18 +341,18 @@
       </dependency>
       <dependency>
         <groupId>org.slf4j</groupId>
-        <artifactId>slf4j-log4j12</artifactId>
+        <artifactId>slf4j-simple</artifactId>
         <version>${slf4j.version}</version>
       </dependency>
       <dependency>
         <groupId>org.slf4j</groupId>
-        <artifactId>slf4j-simple</artifactId>
+        <artifactId>jcl-over-slf4j</artifactId>
         <version>${slf4j.version}</version>
       </dependency>
       <dependency>
         <groupId>org.slf4j</groupId>
-        <artifactId>jcl-over-slf4j</artifactId>
-        <version>${slf4j.version}</version>
+        <artifactId>slf4j-log4j12</artifactId>
+        <version>1.7.32</version>
       </dependency>
       <dependency>
         <groupId>org.slf4j</groupId>
@@ -516,6 +530,23 @@
               <goal>enforce</goal>
             </goals>
           </execution>
+          <execution>
+            <id>ban-bad-log4j-versions</id>
+            <phase>validate</phase>
+            <goals>
+              <goal>enforce</goal>
+            </goals>
+            <configuration>
+              <rules>
+                <bannedDependencies>
+                  <excludes>
+                    <exclude>org.apache.logging.log4j:log4j-core:(,2.16.0)</exclude>
+                  </excludes>
+                </bannedDependencies>
+              </rules>
+              <fail>true</fail>
+            </configuration>
+          </execution>
         </executions>
       </plugin>
     </plugins>
diff --git a/tika-parsers/pom.xml b/tika-parsers/pom.xml
index 08ae2f1..9988177 100644
--- a/tika-parsers/pom.xml
+++ b/tika-parsers/pom.xml
@@ -493,8 +493,8 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
       <scope>test</scope>
     </dependency>
 
diff --git a/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/WordParserTest.java b/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/WordParserTest.java
index 73aa1b8..9b57579 100644
--- a/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/WordParserTest.java
+++ b/tika-parsers/src/test/java/org/apache/tika/parser/microsoft/WordParserTest.java
@@ -26,8 +26,6 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
 
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
 import org.apache.tika.TikaTest;
 
 import org.apache.tika.config.TikaConfig;
@@ -41,6 +39,11 @@ import org.apache.tika.parser.ParseContext;
 import org.apache.tika.parser.RecursiveParserWrapper;
 import org.apache.tika.sax.AbstractRecursiveParserWrapperHandler;
 import org.apache.tika.sax.BodyContentHandler;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.xml.sax.ContentHandler;
@@ -370,15 +373,17 @@ public class WordParserTest extends TikaTest {
     @Test
     public void testExceptions1() throws Exception {
         XMLResult xml;
-        Level logLevelStart = Logger.getRootLogger().getLevel();
-        Logger.getRootLogger().setLevel(Level.ERROR);
+        LoggerContext ctx = (LoggerContext) LogManager.getContext();
+        LoggerConfig lc = ctx.getConfiguration().getRootLogger();
+        Level originalLevel = lc.getLevel();
+        lc.setLevel(Level.ERROR);
         try {
             xml = getXML("testException1.doc");
             assertContains("total population", xml.xml);
             xml = getXML("testException2.doc");
             assertContains("electric charge", xml.xml);
         } finally {
-            Logger.getRootLogger().setLevel(logLevelStart);
+            lc.setLevel(originalLevel);
         }
     }
 
diff --git a/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java b/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
index c3e110b..1952939 100644
--- a/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
+++ b/tika-parsers/src/test/java/org/apache/tika/parser/pdf/PDFParserTest.java
@@ -25,23 +25,19 @@ import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
 
-import java.io.File;
 import java.io.InputStream;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
 import org.apache.pdfbox.rendering.ImageType;
 import org.apache.tika.Tika;
 import org.apache.tika.TikaTest;
diff --git a/tika-parsers/src/test/resources/log4j.properties b/tika-parsers/src/test/resources/log4j.properties
deleted file mode 100644
index f2c0b92..0000000
--- a/tika-parsers/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#info,debug, error,fatal ...
-log4j.rootLogger=info,stdout
-
-#console
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-
-# Pattern to output the caller's file name and line number.
-log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
diff --git a/tika-parsers/src/test/resources/log4j2.xml b/tika-parsers/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..c88e66e
--- /dev/null
+++ b/tika-parsers/src/test/resources/log4j2.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+
+<!--
+  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.
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_ERR">
+      <PatternLayout pattern="%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/tika-server/bin/tika.in.sh b/tika-server/bin/tika.in.sh
index 687ceae..7dcf4b8 100755
--- a/tika-server/bin/tika.in.sh
+++ b/tika-server/bin/tika.in.sh
@@ -64,8 +64,8 @@
 
 # Tika provides a default Log4J configuration properties file in tika-server.jar
 # however, you may want to customize the log settings and file appender location
-# so you can point the script to use a different log4j.properties file
-#LOG4J_PROPS=/var/tika/log4j.properties
+# so you can point the script to use a different log4j2.xml file
+#LOG4J_PROPS=/var/tika/log4j2.xml
 
 # Location where Tika should write logs to.
 #TIKA_LOGS_DIR=/var/tika/logs
diff --git a/tika-server/pom.xml b/tika-server/pom.xml
index 3e5d66e..0e8c025 100644
--- a/tika-server/pom.xml
+++ b/tika-server/pom.xml
@@ -122,13 +122,12 @@
 
     <!-- logging -->
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
     </dependency>
     <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>apache-log4j-extras</artifactId>
-      <version>${log4j.version}</version>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
     </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
diff --git a/tika-server/src/main/java/org/apache/tika/server/metrics/Log4JMetrics.java b/tika-server/src/main/java/org/apache/tika/server/metrics/Log4JMetrics.java
deleted file mode 100644
index bb2e1eb..0000000
--- a/tika-server/src/main/java/org/apache/tika/server/metrics/Log4JMetrics.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.tika.server.metrics;
-
-import io.micrometer.core.instrument.Counter;
-import io.micrometer.core.instrument.MeterRegistry;
-import io.micrometer.core.instrument.Tag;
-import io.micrometer.core.instrument.binder.BaseUnits;
-import io.micrometer.core.instrument.binder.MeterBinder;
-import io.micrometer.core.lang.NonNullApi;
-import io.micrometer.core.lang.NonNullFields;
-import org.apache.commons.collections4.EnumerationUtils;
-import org.apache.cxf.helpers.CastUtils;
-import org.apache.log4j.Appender;
-import org.apache.log4j.AsyncAppender;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.Logger;
-import org.apache.log4j.spi.Filter;
-import org.apache.log4j.spi.LoggingEvent;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.stream.Stream;
-
-/**
- * Log4J metrics meter binder.
- */
-public class Log4JMetrics implements MeterBinder, AutoCloseable {
-
-    /**
-     * Te meter name.
-     */
-    private static final String METER_NAME = "log4j.events";
-
-    /**
-     * Additional tags.
-     */
-    private final Iterable<Tag> tags;
-
-    /**
-     * List of appenders that has the metrics filter attached.
-     */
-    private List<Appender> attachedAppenders = new ArrayList<>();
-
-    /**
-     * Initializes metrics with no additional tags.
-     */
-    public Log4JMetrics() {
-        this(Collections.emptyList());
-    }
-
-    /**
-     * Initializes metrics with additional tags.
-     * @param tags the additional tags.
-     */
-    public Log4JMetrics(Iterable<Tag> tags) {
-        this.tags = tags;
-    }
-
-    /**
-     * Binds the metrics to registry.
-     * @param meterRegistry the meter registry to bind to.
-     */
-    @Override
-    public void bindTo(@NotNull MeterRegistry meterRegistry) {
-        Logger rootLogger = LogManager.getRootLogger();
-        attachToAppenders(CastUtils.cast(rootLogger.getAllAppenders(), Appender.class), meterRegistry);
-
-        EnumerationUtils.toList(CastUtils.cast(LogManager.getCurrentLoggers(), Logger.class)).stream()
-                .filter(logger -> !logger.getAdditivity())
-                .forEach(logger -> {
-                    if (logger == rootLogger) {
-                        return;
-                    }
-
-                    attachToAppenders(CastUtils.cast(logger.getAllAppenders(), Appender.class), meterRegistry);
-                });
-    }
-
-    /**
-     * Attaches metrics filter to enumeration of appender.
-     * @param appenderEnumeration the appender enumeration.
-     * @param meterRegistry the meter registry to attach to.
-     */
-    private void attachToAppenders(Enumeration<Appender> appenderEnumeration, MeterRegistry meterRegistry) {
-        while (appenderEnumeration.hasMoreElements()) {
-            Appender appender = appenderEnumeration.nextElement();
-
-            if (appender instanceof AsyncAppender) {
-                AsyncAppender asyncAppender = (AsyncAppender) appender;
-                attachToAppenders(CastUtils.cast(asyncAppender.getAllAppenders(), Appender.class), meterRegistry);
-            } else {
-                if (!(appender.getFilter() instanceof MetricsFilter)) {
-                    attachMetricsFilter(appender, meterRegistry);
-                }
-            }
-        }
-    }
-
-    /**
-     * Clears all metrics filters.
-     * @throws Exception if an issue.
-     */
-    @Override
-    public void close() throws Exception {
-        for (Appender appender : attachedAppenders) {
-            MetricsFilter metricsFilter = (MetricsFilter) appender.getFilter();
-            appender.clearFilters();
-            appender.addFilter(metricsFilter.getNext());
-        }
-        attachedAppenders.clear();
-    }
-
-    /**
-     * Attaches metrics filter to appender.
-     * @param appender the appender to attach to.
-     * @param meterRegistry the meter registry to bind to.
-     */
-    private void attachMetricsFilter(Appender appender, MeterRegistry meterRegistry) {
-        MetricsFilter metricsFilter = new MetricsFilter(meterRegistry, tags);
-        attachedAppenders.add(appender);
-
-        metricsFilter.setNext(appender.getFilter());
-        appender.clearFilters();
-        appender.addFilter(metricsFilter);
-    }
-
-    /**
-     * Monitors all logging through log4j and keeps count of
-     * all logs for all levels.
-     */
-    @NonNullApi
-    @NonNullFields
-    private class MetricsFilter extends Filter {
-
-        /**
-         * Map of log level string to counter.
-         */
-        private final Map<String, Counter> LEVEL_COUNTER_MAP =
-                new HashMap<>();
-
-        /**
-         * Initializes metrics filter with registry and tags.
-         * @param registry the meter registry to bind to.
-         * @param tags the additional tags.
-         */
-        MetricsFilter(MeterRegistry registry, Iterable<Tag> tags) {
-            Stream.of("fatal", "error", "warn", "info", "debug", "trace")
-                    .forEach(levelStr -> LEVEL_COUNTER_MAP.put(levelStr,
-                            Counter.builder(METER_NAME)
-                            .tags(tags)
-                            .tags("level", levelStr)
-                            .description("Number of " + levelStr + " level log events")
-                            .baseUnit(BaseUnits.EVENTS)
-                            .register(registry)));
-        }
-
-        /**
-         * Internally calls the filter chain, and increments based on final decision.
-         * @param event the logging event.
-         * @return the final decision.
-         */
-        @Override
-        public int decide(LoggingEvent event) {
-            int decision = NEUTRAL;
-
-                Filter filter = getNext();
-                while (filter != null) {
-                    decision = filter.decide(event);
-                    if (decision != NEUTRAL) break;
-                    filter = filter.getNext();
-                }
-
-                if (decision != DENY) {
-                    incrementCounter(event);
-                }
-
-            return decision;
-        }
-
-        /**
-         * Increments the appropriate counter.
-         * @param event the logging event.
-         */
-        private void incrementCounter(LoggingEvent event) {
-            LEVEL_COUNTER_MAP.get(event.getLevel().toString().toLowerCase(Locale.ROOT))
-                    .increment();
-        }
-    }
-
-}
diff --git a/tika-server/src/main/java/org/apache/tika/server/metrics/Log4j2Metrics.java b/tika-server/src/main/java/org/apache/tika/server/metrics/Log4j2Metrics.java
new file mode 100644
index 0000000..0950c2a
--- /dev/null
+++ b/tika-server/src/main/java/org/apache/tika/server/metrics/Log4j2Metrics.java
@@ -0,0 +1,257 @@
+/*
+ * 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.tika.server.metrics;
+
+import io.micrometer.core.instrument.Counter;
+import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.Tag;
+import io.micrometer.core.instrument.binder.BaseUnits;
+import io.micrometer.core.instrument.binder.MeterBinder;
+import io.micrometer.core.lang.NonNullApi;
+import io.micrometer.core.lang.NonNullFields;
+import org.apache.commons.collections4.EnumerationUtils;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.AsyncAppender;
+import org.apache.logging.log4j.core.async.AsyncLoggerConfig;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+import org.apache.logging.log4j.core.filter.AbstractFilter;
+import org.apache.logging.log4j.core.filter.CompositeFilter;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.stream.Stream;
+
+/**
+ * Log4J metrics meter binder.
+ * Largely inspired by: https://github.com/micrometer-metrics/micrometer/blob/main/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/logging/Log4j2Metrics.java
+ */
+public class Log4j2Metrics implements MeterBinder, AutoCloseable {
+
+    /**
+     * Te meter name.
+     */
+    private static final String METER_NAME = "log4j2.events";
+
+    /**
+     * Additional tags.
+     */
+    private final Iterable<Tag> tags;
+
+    /**
+     * List of metrics filters
+     */
+    private final List<MetricsFilter> metricsFilters = new ArrayList<>();
+
+    private final LoggerContext loggerContext;
+
+    /**
+     * Initializes metrics with no additional tags.
+     */
+    public Log4j2Metrics() {
+        this(Collections.emptyList());
+    }
+
+    /**
+     * Initializes metrics with additional tags.
+     * @param tags the additional tags.
+     */
+    public Log4j2Metrics(Iterable<Tag> tags) {
+        this(tags, (LoggerContext) LogManager.getContext(false));
+    }
+
+    public Log4j2Metrics(Iterable<Tag> tags, LoggerContext loggerContext) {
+        this.tags = tags;
+        this.loggerContext = loggerContext;
+    }
+    /**
+     * Binds the metrics to registry.
+     * @param meterRegistry the meter registry to bind to.
+     */
+    @Override
+    public void bindTo(@NotNull MeterRegistry meterRegistry) {
+        Configuration configuration = loggerContext.getConfiguration();
+        LoggerConfig rootLoggerConfig = configuration.getRootLogger();
+        rootLoggerConfig.addFilter(createMetricsFilterAndStart(meterRegistry, rootLoggerConfig));
+
+        loggerContext.getConfiguration().getLoggers().values().stream()
+                .filter(loggerConfig -> !loggerConfig.isAdditive())
+                .forEach(loggerConfig -> {
+                    if (loggerConfig == rootLoggerConfig) {
+                        return;
+                    }
+                    Filter logFilter = loggerConfig.getFilter();
+
+                    if ((logFilter instanceof CompositeFilter && Arrays.stream(((CompositeFilter) logFilter).getFiltersArray())
+                            .anyMatch(innerFilter -> innerFilter instanceof MetricsFilter))) {
+                        return;
+                    }
+
+                    if (logFilter instanceof MetricsFilter) {
+                        return;
+                    }
+                    loggerConfig.addFilter(createMetricsFilterAndStart(meterRegistry, loggerConfig));
+                });
+
+        loggerContext.updateLoggers(configuration);
+    }
+
+
+    private MetricsFilter createMetricsFilterAndStart(MeterRegistry registry, LoggerConfig loggerConfig) {
+        MetricsFilter metricsFilter = new MetricsFilter(registry, tags, loggerConfig);
+        metricsFilter.start();
+        metricsFilters.add(metricsFilter);
+        return metricsFilter;
+    }
+
+
+    /**
+     * Clears all metrics filters.
+     * @throws Exception if an issue.
+     */
+    @Override
+    public void close() throws Exception {
+        if (!metricsFilters.isEmpty()) {
+            Configuration configuration = loggerContext.getConfiguration();
+            LoggerConfig rootLoggerConfig = configuration.getRootLogger();
+            metricsFilters.forEach(rootLoggerConfig::removeFilter);
+
+            loggerContext.getConfiguration().getLoggers().values().stream()
+                    .filter(loggerConfig -> !loggerConfig.isAdditive())
+                    .forEach(loggerConfig -> {
+                        if (loggerConfig != rootLoggerConfig) {
+                            metricsFilters.forEach(loggerConfig::removeFilter);
+                        }
+                    });
+
+            loggerContext.updateLoggers(configuration);
+            metricsFilters.forEach(MetricsFilter::stop);
+        }
+    }
+
+
+    /**
+     * Monitors all logging through log4j2 and keeps count of
+     * all logs for all levels.
+     */
+    @NonNullApi
+    @NonNullFields
+    private class MetricsFilter extends AbstractFilter {
+
+        /**
+         * Map of log level string to counter.
+         */
+        private final Map<String, Counter> LEVEL_COUNTER_MAP =
+                new HashMap<>();
+
+        private final boolean isAsyncLogger;
+
+        //this is a list of non-MetricsFilters associated with the loggerConfig
+        //these are used to determine whether or not to filter this through
+        //MetricsFilter
+        private final List<Filter> filters;
+
+        /**
+         * Initializes metrics filter with registry and tags.
+         * @param registry the meter registry to bind to.
+         * @param tags the additional tags.
+         */
+        MetricsFilter(MeterRegistry registry, Iterable<Tag> tags, LoggerConfig loggerConfig) {
+            this.isAsyncLogger = (loggerConfig instanceof AsyncLoggerConfig);
+            this.filters = getNonMetricsFilterFilters(loggerConfig);
+            Stream.of("fatal", "error", "warn", "info", "debug", "trace")
+                    .forEach(levelStr -> LEVEL_COUNTER_MAP.put(levelStr,
+                            Counter.builder(METER_NAME)
+                            .tags(tags)
+                            .tags("level", levelStr)
+                            .description("Number of " + levelStr + " level log events")
+                            .baseUnit(BaseUnits.EVENTS)
+                            .register(registry)));
+        }
+
+        private List<Filter> getNonMetricsFilterFilters(LoggerConfig loggerConfig) {
+            List<Filter> filters = new ArrayList<>();
+            Filter filter = loggerConfig.getFilter();
+            addFilters(filter, filters);
+            return filters;
+        }
+
+        private void addFilters(Filter filter, List<Filter> filters) {
+            if (filter == null) {
+                return;
+            }
+            if (filter instanceof CompositeFilter) {
+                for (Filter f : ((CompositeFilter)filter).getFiltersArray()) {
+                    addFilters(f, filters);
+                }
+                return;
+            }
+            if (filter instanceof MetricsFilter) {
+                return;
+            }
+            filters.add(filter);
+        }
+
+        /**
+         * Internally calls the filter chain, and increments based on final decision.
+         * @param event the logging event.
+         * @return the final decision.
+         */
+        @Override
+        public Result filter(LogEvent event) {
+            Result result = Result.NEUTRAL;
+            for (Filter filter : filters) {
+                result = filter.filter(event);
+                if (result != Result.NEUTRAL) break;
+            }
+            if (result != Result.DENY) {
+                if (!isAsyncLogger || isAsyncLoggerAndEndOfBatch(event)) {
+                    incrementCounter(event);
+                }
+            }
+            return result;
+        }
+
+        private boolean isAsyncLoggerAndEndOfBatch(LogEvent event) {
+            return isAsyncLogger && event.isEndOfBatch();
+        }
+
+        /**
+         * Increments the appropriate counter.
+         * @param event the logging event.
+         */
+        private void incrementCounter(LogEvent event) {
+            LEVEL_COUNTER_MAP.get(event.getLevel().toString().toLowerCase(Locale.ROOT))
+                    .increment();
+        }
+    }
+
+}
diff --git a/tika-server/src/main/java/org/apache/tika/server/metrics/MetricsHelper.java b/tika-server/src/main/java/org/apache/tika/server/metrics/MetricsHelper.java
index 0ba0ea7..80f42ce 100644
--- a/tika-server/src/main/java/org/apache/tika/server/metrics/MetricsHelper.java
+++ b/tika-server/src/main/java/org/apache/tika/server/metrics/MetricsHelper.java
@@ -179,7 +179,7 @@ public class MetricsHelper {
      * Sets up logging metrics.
      */
     private static void setUpLoggingMetrics() {
-        new Log4JMetrics().bindTo(REGISTRY);
+        new Log4j2Metrics().bindTo(REGISTRY);
     }
 
     /**
diff --git a/tika-server/src/main/resources/log4j.properties b/tika-server/src/main/resources/log4j.properties
deleted file mode 100644
index 7d3b372..0000000
--- a/tika-server/src/main/resources/log4j.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#info,debug, error,fatal ...
-log4j.rootLogger=info,stderr
-
-#console
-log4j.appender.stderr=org.apache.log4j.ConsoleAppender
-log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
-log4j.appender.stderr.Target=System.err
-
-log4j.appender.stderr.layout.ConversionPattern= %-5p %m%n
diff --git a/tika-server/src/main/resources/log4j2.xml b/tika-server/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..c88e66e
--- /dev/null
+++ b/tika-server/src/main/resources/log4j2.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+
+<!--
+  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.
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_ERR">
+      <PatternLayout pattern="%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/tika-server/src/test/java/org/apache/tika/server/MetricsResourceTest.java b/tika-server/src/test/java/org/apache/tika/server/MetricsResourceTest.java
index eacc805..f095f60 100644
--- a/tika-server/src/test/java/org/apache/tika/server/MetricsResourceTest.java
+++ b/tika-server/src/test/java/org/apache/tika/server/MetricsResourceTest.java
@@ -89,10 +89,11 @@ public class MetricsResourceTest extends CXFTestBase {
     }
 
     @Test
-    public void testPrometheusContainsLog4j() throws IOException {
+    public void testPrometheusContainsLog4j2() throws IOException {
         String response = getPrometheusResponse();
-        assertContains("log4j_events_total", response);
-        assertTrue(getMetricValue(response, "log4j_events_total{application=\"tika-server\",level=\"info\",}") > 1.0);
+        assertContains("log4j2_events_total", response);
+        assertTrue(getMetricValue(response,
+                "log4j2_events_total{application=\"tika-server\",level=\"info\",}") > 1.0);
     }
 
     private String getPrometheusResponse() throws IOException {
diff --git a/tika-server/src/test/java/org/apache/tika/server/TikaServerIntegrationTest.java b/tika-server/src/test/java/org/apache/tika/server/TikaServerIntegrationTest.java
index 78ea1fd..cb6ffbf 100644
--- a/tika-server/src/test/java/org/apache/tika/server/TikaServerIntegrationTest.java
+++ b/tika-server/src/test/java/org/apache/tika/server/TikaServerIntegrationTest.java
@@ -509,7 +509,7 @@ public class TikaServerIntegrationTest extends TikaTest {
                                 "-p", INTEGRATION_TEST_PORT,
                                 "-taskTimeoutMillis", "10000", "-taskPulseMillis", "500",
                                 "-pingPulseMillis", "100", "-maxRestarts", "0",
-                                "-JDlog4j.configuration=file:"+ LOG_FILE.toAbsolutePath(),
+                                "-JDlog4j.configurationFile="+ LOG_FILE.toAbsolutePath(),
                                 "-tmpFilePrefix", "tika-server-stderrlogging"
                         });
             }
diff --git a/tika-server/src/test/resources/log4j.properties b/tika-server/src/test/resources/log4j.properties
deleted file mode 100644
index 6aa860a..0000000
--- a/tika-server/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#info,debug, error,fatal ...
-log4j.rootLogger=info,stderr
-
-#console
-log4j.appender.stderr=org.apache.log4j.ConsoleAppender
-log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
-log4j.appender.stderr.Target=System.err
-
-log4j.appender.stderr.layout.ConversionPattern= %-5p %d [%t] (%F:%L) - %m%n
diff --git a/tika-server/src/test/resources/log4j2.xml b/tika-server/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..c88e66e
--- /dev/null
+++ b/tika-server/src/test/resources/log4j2.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+
+<!--
+  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.
+-->
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_ERR">
+      <PatternLayout pattern="%-5p [%t] %d{HH:mm:ss,SSS} %c %m%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file