mirror of https://github.com/apache/lucene.git
SOLR-12154: Disallow explicit usage of Log4j2 logger via forbidden APIs
This commit is contained in:
parent
c0709f113d
commit
56f80c0dc7
|
@ -30,6 +30,7 @@ java.util.concurrent.ThreadPoolExecutor#<init>(int,int,long,java.util.concurrent
|
||||||
|
|
||||||
@defaultMessage Use slf4j classes instead
|
@defaultMessage Use slf4j classes instead
|
||||||
org.apache.log4j.**
|
org.apache.log4j.**
|
||||||
|
org.apache.logging.log4j.**
|
||||||
java.util.logging.**
|
java.util.logging.**
|
||||||
|
|
||||||
@defaultMessage Use RTimer/TimeOut/System.nanoTime for time comparisons, and `new Date()` output/debugging/stats of timestamps. If for some miscellaneous reason, you absolutely need to use this, use a SuppressForbidden.
|
@defaultMessage Use RTimer/TimeOut/System.nanoTime for time comparisons, and `new Date()` output/debugging/stats of timestamps. If for some miscellaneous reason, you absolutely need to use this, use a SuppressForbidden.
|
||||||
|
|
|
@ -161,6 +161,8 @@ Other Changes
|
||||||
|
|
||||||
* SOLR-12165: Ref Guide: DisMax default mm param value is improperly documented as 100%. (Steve Rowe)
|
* SOLR-12165: Ref Guide: DisMax default mm param value is improperly documented as 100%. (Steve Rowe)
|
||||||
|
|
||||||
|
* SOLR-12154: Disallow explicit usage of Log4j2 logger via forbidden APIs. (Varun Thacker, Tomás Fernández Löbbe)
|
||||||
|
|
||||||
================== 7.3.0 ==================
|
================== 7.3.0 ==================
|
||||||
|
|
||||||
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.
|
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.
|
||||||
|
|
|
@ -23,28 +23,31 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.core.Filter;
|
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.LoggerContext;
|
||||||
import org.apache.logging.log4j.core.appender.AbstractAppender;
|
import org.apache.logging.log4j.core.appender.AbstractAppender;
|
||||||
import org.apache.logging.log4j.core.config.Configuration;
|
import org.apache.logging.log4j.core.config.Configuration;
|
||||||
import org.apache.logging.log4j.core.config.LoggerConfig;
|
import org.apache.logging.log4j.core.config.LoggerConfig;
|
||||||
import org.apache.logging.log4j.core.LogEvent;
|
|
||||||
import org.apache.logging.log4j.core.filter.ThresholdFilter;
|
import org.apache.logging.log4j.core.filter.ThresholdFilter;
|
||||||
import org.apache.logging.log4j.message.Message;
|
import org.apache.logging.log4j.message.Message;
|
||||||
import org.apache.solr.common.SolrDocument;
|
import org.apache.solr.common.SolrDocument;
|
||||||
|
import org.apache.solr.common.util.SuppressForbidden;
|
||||||
import org.apache.solr.logging.CircularList;
|
import org.apache.solr.logging.CircularList;
|
||||||
import org.apache.solr.logging.ListenerConfig;
|
import org.apache.solr.logging.ListenerConfig;
|
||||||
import org.apache.solr.logging.LogWatcher;
|
import org.apache.solr.logging.LogWatcher;
|
||||||
import org.apache.solr.logging.LoggerInfo;
|
import org.apache.solr.logging.LoggerInfo;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
@SuppressForbidden(reason = "class is specific to log4j2")
|
||||||
|
|
||||||
public class Log4j2Watcher extends LogWatcher<LogEvent> {
|
public class Log4j2Watcher extends LogWatcher<LogEvent> {
|
||||||
|
|
||||||
private final static String LOG4J2_WATCHER_APPENDER = "Log4j2WatcherAppender";
|
private final static String LOG4J2_WATCHER_APPENDER = "Log4j2WatcherAppender";
|
||||||
|
|
||||||
|
@SuppressForbidden(reason = "class is specific to log4j2")
|
||||||
protected class Log4j2Appender extends AbstractAppender {
|
protected class Log4j2Appender extends AbstractAppender {
|
||||||
|
|
||||||
private Log4j2Watcher watcher;
|
private Log4j2Watcher watcher;
|
||||||
|
@ -74,6 +77,7 @@ public class Log4j2Watcher extends LogWatcher<LogEvent> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressForbidden(reason = "class is specific to log4j2")
|
||||||
protected class Log4j2Info extends LoggerInfo {
|
protected class Log4j2Info extends LoggerInfo {
|
||||||
final Level level;
|
final Level level;
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ import static org.apache.solr.common.cloud.ZkStateReader.NODE_NAME_PROP;
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.REPLICA_PROP;
|
import static org.apache.solr.common.cloud.ZkStateReader.REPLICA_PROP;
|
||||||
import static org.apache.solr.common.cloud.ZkStateReader.SHARD_ID_PROP;
|
import static org.apache.solr.common.cloud.ZkStateReader.SHARD_ID_PROP;
|
||||||
|
|
||||||
@SuppressForbidden(reason = "class is specific to log4j")
|
@SuppressForbidden(reason = "class is specific to log4j2")
|
||||||
@Plugin(name = "SolrLogLayout", category = "Core", elementType = "layout", printObject = true)
|
@Plugin(name = "SolrLogLayout", category = "Core", elementType = "layout", printObject = true)
|
||||||
public class SolrLogLayout extends AbstractStringLayout {
|
public class SolrLogLayout extends AbstractStringLayout {
|
||||||
|
|
||||||
|
@ -110,23 +110,9 @@ public class SolrLogLayout extends AbstractStringLayout {
|
||||||
|
|
||||||
Map<Integer,CoreInfo> coreInfoMap = new WeakHashMap<>();
|
Map<Integer,CoreInfo> coreInfoMap = new WeakHashMap<>();
|
||||||
|
|
||||||
public Map<String,String> classAliases = new HashMap<>();
|
public void appendThread(StringBuilder sb) {
|
||||||
|
|
||||||
public void appendThread(StringBuilder sb, LogEvent event) {
|
|
||||||
Thread th = Thread.currentThread();
|
Thread th = Thread.currentThread();
|
||||||
|
|
||||||
/******
|
|
||||||
* sb.append(" T="); sb.append(th.getName()).append(' ');
|
|
||||||
*
|
|
||||||
* // NOTE: tried creating a thread group around jetty but we seem to lose
|
|
||||||
* it and request // threads are in the normal "main" thread group
|
|
||||||
* ThreadGroup tg = th.getThreadGroup(); while (tg != null) {
|
|
||||||
* sb.append("(group_name=").append(tg.getName()).append(")");
|
|
||||||
*
|
|
||||||
* if (tg instanceof TG) { sb.append(((TG)tg).getTag()); sb.append('/'); }
|
|
||||||
* try { tg = tg.getParent(); } catch (Throwable e) { tg = null; } }
|
|
||||||
******/
|
|
||||||
|
|
||||||
// NOTE: LogRecord.getThreadID is *not* equal to Thread.getId()
|
// NOTE: LogRecord.getThreadID is *not* equal to Thread.getId()
|
||||||
sb.append(" T");
|
sb.append(" T");
|
||||||
sb.append(th.getId());
|
sb.append(th.getId());
|
||||||
|
@ -146,10 +132,8 @@ public class SolrLogLayout extends AbstractStringLayout {
|
||||||
|
|
||||||
long now = event.getTimeMillis();
|
long now = event.getTimeMillis();
|
||||||
long timeFromStart = now - startTime;
|
long timeFromStart = now - startTime;
|
||||||
long timeSinceLast = now - lastTime;
|
|
||||||
lastTime = now;
|
lastTime = now;
|
||||||
String shortClassName = getShortClassName(event.getSource().getClassName(),
|
String shortClassName = getShortClassName(event.getSource().getClassName(), event.getSource().getMethodName());
|
||||||
event.getSource().getMethodName());
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* sb.append(timeFromStart).append(' ').append(timeSinceLast);
|
* sb.append(timeFromStart).append(' ').append(timeSinceLast);
|
||||||
|
@ -165,7 +149,7 @@ public class SolrLogLayout extends AbstractStringLayout {
|
||||||
try (SolrQueryRequest req = (requestInfo == null) ? null : requestInfo.getReq()) {
|
try (SolrQueryRequest req = (requestInfo == null) ? null : requestInfo.getReq()) {
|
||||||
core = (req == null) ? null : req.getCore();
|
core = (req == null) ? null : req.getCore();
|
||||||
}
|
}
|
||||||
ZkController zkController = null;
|
ZkController zkController;
|
||||||
CoreInfo info = null;
|
CoreInfo info = null;
|
||||||
|
|
||||||
if (core != null) {
|
if (core != null) {
|
||||||
|
@ -206,7 +190,7 @@ public class SolrLogLayout extends AbstractStringLayout {
|
||||||
// sb.append("\nL").append(record.getSequenceNumber()); // log number is
|
// sb.append("\nL").append(record.getSequenceNumber()); // log number is
|
||||||
// useful for sequencing when looking at multiple parts of a log file, but
|
// useful for sequencing when looking at multiple parts of a log file, but
|
||||||
// ms since start should be fine.
|
// ms since start should be fine.
|
||||||
appendThread(sb, event);
|
appendThread(sb);
|
||||||
|
|
||||||
appendMDC(sb);
|
appendMDC(sb);
|
||||||
|
|
||||||
|
|
|
@ -57,11 +57,11 @@ public final class StartupLoggingUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables all log4j ConsoleAppender's by modifying log4j configuration dynamically.
|
* Disables all log4j2 ConsoleAppender's by modifying log4j configuration dynamically.
|
||||||
* Must only be used during early startup
|
* Must only be used during early startup
|
||||||
* @return true if ok or else false if something happened, e.g. log4j classes were not in classpath
|
* @return true if ok or else false if something happened, e.g. log4j2 classes were not in classpath
|
||||||
*/
|
*/
|
||||||
@SuppressForbidden(reason = "Legitimate log4j access")
|
@SuppressForbidden(reason = "Legitimate log4j2 access")
|
||||||
public static boolean muteConsole() {
|
public static boolean muteConsole() {
|
||||||
try {
|
try {
|
||||||
if (!isLog4jActive()) {
|
if (!isLog4jActive()) {
|
||||||
|
@ -90,7 +90,7 @@ public final class StartupLoggingUtils {
|
||||||
* @param logLevel String with level, should be one of the supported, e.g. TRACE, DEBUG, INFO, WARN, ERROR...
|
* @param logLevel String with level, should be one of the supported, e.g. TRACE, DEBUG, INFO, WARN, ERROR...
|
||||||
* @return true if ok or else false if something happened, e.g. log4j classes were not in classpath
|
* @return true if ok or else false if something happened, e.g. log4j classes were not in classpath
|
||||||
*/
|
*/
|
||||||
@SuppressForbidden(reason = "Legitimate log4j access")
|
@SuppressForbidden(reason = "Legitimate log4j2 access")
|
||||||
public static boolean changeLogLevel(String logLevel) {
|
public static boolean changeLogLevel(String logLevel) {
|
||||||
try {
|
try {
|
||||||
if (!isLog4jActive()) {
|
if (!isLog4jActive()) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@SuppressForbidden(reason = "test is specific to log4j")
|
@SuppressForbidden(reason = "test is specific to log4j2")
|
||||||
public class RequestLoggingTest extends SolrTestCaseJ4 {
|
public class RequestLoggingTest extends SolrTestCaseJ4 {
|
||||||
private StringWriter writer;
|
private StringWriter writer;
|
||||||
private Appender appender;
|
private Appender appender;
|
||||||
|
|
|
@ -25,12 +25,11 @@ import org.apache.logging.log4j.core.config.LoggerConfig;
|
||||||
import org.apache.solr.SolrTestCaseJ4;
|
import org.apache.solr.SolrTestCaseJ4;
|
||||||
import org.apache.solr.common.params.CommonParams;
|
import org.apache.solr.common.params.CommonParams;
|
||||||
import org.apache.solr.common.util.SuppressForbidden;
|
import org.apache.solr.common.util.SuppressForbidden;
|
||||||
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
@SuppressForbidden(reason = "test uses log4j because it tests output at a specific level")
|
@SuppressForbidden(reason = "test uses log4j2 because it tests output at a specific level")
|
||||||
public class LoggingHandlerTest extends SolrTestCaseJ4 {
|
public class LoggingHandlerTest extends SolrTestCaseJ4 {
|
||||||
|
|
||||||
// TODO: This only tests Log4j at the moment, as that's what's defined
|
// TODO: This only tests Log4j at the moment, as that's what's defined
|
||||||
|
|
|
@ -106,6 +106,7 @@ import org.apache.solr.common.params.UpdateParams;
|
||||||
import org.apache.solr.common.util.ContentStream;
|
import org.apache.solr.common.util.ContentStream;
|
||||||
import org.apache.solr.common.util.ContentStreamBase;
|
import org.apache.solr.common.util.ContentStreamBase;
|
||||||
import org.apache.solr.common.util.ObjectReleaseTracker;
|
import org.apache.solr.common.util.ObjectReleaseTracker;
|
||||||
|
import org.apache.solr.common.util.SuppressForbidden;
|
||||||
import org.apache.solr.common.util.XML;
|
import org.apache.solr.common.util.XML;
|
||||||
import org.apache.solr.core.CoreContainer;
|
import org.apache.solr.core.CoreContainer;
|
||||||
import org.apache.solr.core.CoresLocator;
|
import org.apache.solr.core.CoresLocator;
|
||||||
|
@ -397,6 +398,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressForbidden(reason = "Using the Level class from log4j2 directly")
|
||||||
private static Map<String, Level> savedClassLogLevels = new HashMap<>();
|
private static Map<String, Level> savedClassLogLevels = new HashMap<>();
|
||||||
|
|
||||||
public static void initClassLogLevels() {
|
public static void initClassLogLevels() {
|
||||||
|
|
|
@ -52,7 +52,7 @@ public @interface LogLevel {
|
||||||
*/
|
*/
|
||||||
public String value();
|
public String value();
|
||||||
|
|
||||||
@SuppressForbidden(reason="Specific to Log4J")
|
@SuppressForbidden(reason="Specific to Log4J2")
|
||||||
public static class Configurer {
|
public static class Configurer {
|
||||||
|
|
||||||
private static Map<String, Level> parseFrom(String input) {
|
private static Map<String, Level> parseFrom(String input) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import org.apache.solr.common.util.SuppressForbidden;
|
||||||
import org.apache.solr.util.LogLevel;
|
import org.apache.solr.util.LogLevel;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@SuppressForbidden(reason="We need to use log4J classes to access the log levels")
|
@SuppressForbidden(reason="We need to use log4J2 classes to access the log levels")
|
||||||
@LogLevel("org.apache.solr.ClassLogLevel=error;org.apache.solr.MethodLogLevel=warn")
|
@LogLevel("org.apache.solr.ClassLogLevel=error;org.apache.solr.MethodLogLevel=warn")
|
||||||
public class TestLogLevelAnnotations extends SolrTestCaseJ4 {
|
public class TestLogLevelAnnotations extends SolrTestCaseJ4 {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue