diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index f0ec0dabdc2..1e513c863a8 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -92,6 +92,9 @@ New Features * SOLR-8487: Adds CommitStream to support sending commits to a collection being updated. (Dennis Gove) +* SOLR-9534: You can now set Solr's log level through environment variable SOLR_LOG_LEVEL + Also adds conveience arguments -q (quiet: WARN) and -v (verbose: DEBUG) to bin/solr (janhoy) + Bug Fixes ---------------------- diff --git a/solr/bin/solr b/solr/bin/solr index d3c6530722e..bd8118b8669 100755 --- a/solr/bin/solr +++ b/solr/bin/solr @@ -258,7 +258,9 @@ function print_usage() { echo "" echo " -noprompt Don't prompt for input; accept all defaults when running examples that accept user input" echo "" - echo " -V Verbose messages from this script" + echo " -v and -q Verbose (-v) or quiet (-q) logging. Sets default log level to DEBUG or WARN instead of INFO" + echo "" + echo " -V or -version Verbose messages from this script" echo "" elif [ "$CMD" == "stop" ]; then echo "" @@ -1160,6 +1162,14 @@ if [ $# -gt 0 ]; then PASS_TO_RUN_EXAMPLE+=" --verbose" shift ;; + -v) + SOLR_LOG_LEVEL=DEBUG + shift + ;; + -q) + SOLR_LOG_LEVEL=WARN + shift + ;; -all) stop_all=true shift @@ -1187,6 +1197,10 @@ if [ $# -gt 0 ]; then done fi +if [[ $SOLR_LOG_LEVEL ]] ; then + SOLR_LOG_LEVEL_OPT="-Dsolr.log.level=$SOLR_LOG_LEVEL" +fi + if [ -z "$SOLR_SERVER_DIR" ]; then SOLR_SERVER_DIR="$DEFAULT_SERVER_DIR" fi @@ -1518,6 +1532,11 @@ function launch_solr() { echo -e " RMI_PORT = $RMI_PORT" echo -e " REMOTE_JMX_OPTS = ${REMOTE_JMX_OPTS[@]}" fi + + if [ "$SOLR_LOG_LEVEL" != "" ]; then + echo -e " SOLR_LOG_LEVEL = $SOLR_LOG_LEVEL" + fi + echo -e "\n" fi @@ -1530,7 +1549,7 @@ function launch_solr() { fi SOLR_START_OPTS=('-server' "${JAVA_MEM_OPTS[@]}" "${GC_TUNE[@]}" "${GC_LOG_OPTS[@]}" \ - "${REMOTE_JMX_OPTS[@]}" "${CLOUD_MODE_OPTS[@]}" \ + "${REMOTE_JMX_OPTS[@]}" "${CLOUD_MODE_OPTS[@]}" $SOLR_LOG_LEVEL_OPT \ "-Djetty.port=$SOLR_PORT" "-DSTOP.PORT=$stop_port" "-DSTOP.KEY=$STOP_KEY" \ "${SOLR_HOST_ARG[@]}" "-Duser.timezone=$SOLR_TIMEZONE" \ "-Djetty.home=$SOLR_SERVER_DIR" "-Dsolr.solr.home=$SOLR_HOME" "-Dsolr.install.dir=$SOLR_TIP" \ diff --git a/solr/bin/solr.cmd b/solr/bin/solr.cmd index 2e6e6a99747..e1f2ffda4a1 100644 --- a/solr/bin/solr.cmd +++ b/solr/bin/solr.cmd @@ -222,6 +222,8 @@ goto done @echo. @echo -noprompt Don't prompt for input; accept all defaults when running examples that accept user input @echo. +@echo -v and -q Verbose (-v) or quiet (-q) logging. Sets default log level to DEBUG or WARN instead of INFO +@echo. @echo -V Verbose messages from this script @echo. goto done @@ -439,6 +441,8 @@ IF "%1"=="-f" goto set_foreground_mode IF "%1"=="-foreground" goto set_foreground_mode IF "%1"=="-V" goto set_verbose IF "%1"=="-verbose" goto set_verbose +IF "%1"=="-v" goto set_debug +IF "%1"=="-q" goto set_warn IF "%1"=="-c" goto set_cloud_mode IF "%1"=="-cloud" goto set_cloud_mode IF "%1"=="-d" goto set_server_dir @@ -481,6 +485,16 @@ set "PASS_TO_RUN_EXAMPLE=--verbose !PASS_TO_RUN_EXAMPLE!" SHIFT goto parse_args +:set_debug +set SOLR_LOG_LEVEL=DEBUG +SHIFT +goto parse_args + +:set_warn +set SOLR_LOG_LEVEL=WARN +SHIFT +goto parse_args + :set_cloud_mode set SOLR_MODE=solrcloud SHIFT @@ -931,6 +945,10 @@ IF "%verbose%"=="1" ( @echo REMOTE_JMX_OPTS = %REMOTE_JMX_OPTS% ) + IF NOT "%SOLR_LOG_LEVEL%"=="" ( + @echo SOLR_LOG_LEVEL = !SOLR_LOG_LEVEL! + ) + @echo. ) @@ -945,6 +963,7 @@ IF NOT "%SOLR_SSL_OPTS%"=="" ( set "SSL_PORT_PROP=-Dsolr.jetty.https.port=%SOLR_PORT%" set "START_OPTS=%START_OPTS% %SOLR_SSL_OPTS% !SSL_PORT_PROP!" ) +IF NOT "%SOLR_LOG_LEVEL%"=="" set "START_OPTS=%START_OPTS% -Dsolr.log.level=%SOLR_LOG_LEVEL%" IF NOT DEFINED LOG4J_CONFIG set "LOG4J_CONFIG=file:%SOLR_SERVER_DIR%\resources\log4j.properties" diff --git a/solr/bin/solr.in.cmd b/solr/bin/solr.in.cmd index 76c77ed7f1e..544894359a2 100644 --- a/solr/bin/solr.in.cmd +++ b/solr/bin/solr.in.cmd @@ -27,6 +27,10 @@ set SOLR_JAVA_MEM=-Xms512m -Xmx512m REM Enable verbose GC logging set GC_LOG_OPTS=-verbose:gc -XX:+PrintHeapAtGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime +REM Changes the logging level. Valid values: ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF. Default is INFO +REM This is an alternative to changing the rootLogger in log4j.properties +REM set SOLR_LOG_LEVEL=INFO + REM These GC settings have shown to work well for a number of common Solr workloads set GC_TUNE=-XX:NewRatio=3 ^ -XX:SurvivorRatio=4 ^ diff --git a/solr/bin/solr.in.sh b/solr/bin/solr.in.sh index e5f8503bc58..33b2ed01f9a 100644 --- a/solr/bin/solr.in.sh +++ b/solr/bin/solr.in.sh @@ -91,6 +91,10 @@ SOLR_OPTS="$SOLR_OPTS -Xss256k" # so you can point the script to use a different log4j.properties file #LOG4J_PROPS=/var/solr/log4j.properties +# Changes the logging level. Valid values: ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF. Default is INFO +# This is an alternative to changing the rootLogger in log4j.properties +#SOLR_LOG_LEVEL=INFO + # Location where Solr should write logs to; should agree with the file appender # settings in server/resources/log4j.properties #SOLR_LOGS_DIR= diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java index f5fe4641764..83de0c302c3 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -114,6 +114,8 @@ public class SolrDispatchFilter extends BaseSolrFilter { public static final String SOLR_LOG_MUTECONSOLE = "solr.log.muteconsole"; + public static final String SOLR_LOG_LEVEL = "solr.log.level"; + @Override public void init(FilterConfig config) throws ServletException { @@ -122,7 +124,10 @@ public class SolrDispatchFilter extends BaseSolrFilter { if (muteConsole != null && !Arrays.asList("false","0","off","no").contains(muteConsole.toLowerCase(Locale.ROOT))) { StartupLoggingUtils.muteConsole(); } - log.info("SolrDispatchFilter.init(): {}", this.getClass().getClassLoader()); + String logLevel = System.getProperty(SOLR_LOG_LEVEL); + if (logLevel != null) { + StartupLoggingUtils.changeLogLevel(logLevel); + } String exclude = config.getInitParameter("excludePatterns"); if(exclude != null) { diff --git a/solr/core/src/java/org/apache/solr/servlet/StartupLoggingUtils.java b/solr/core/src/java/org/apache/solr/servlet/StartupLoggingUtils.java index fbcebebc52d..feb88e97a8f 100644 --- a/solr/core/src/java/org/apache/solr/servlet/StartupLoggingUtils.java +++ b/solr/core/src/java/org/apache/solr/servlet/StartupLoggingUtils.java @@ -22,6 +22,7 @@ import java.util.Enumeration; import org.apache.log4j.Appender; import org.apache.log4j.ConsoleAppender; +import org.apache.log4j.Level; import org.apache.log4j.LogManager; import org.apache.solr.common.util.SuppressForbidden; import org.slf4j.Logger; @@ -67,6 +68,27 @@ final class StartupLoggingUtils { } } + /** + * Dynamically change log4j log level through property solr.log.level + * @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 + */ + @SuppressForbidden(reason = "Legitimate log4j access") + static boolean changeLogLevel(String logLevel) { + try { + if (!isLog4jActive()) { + logNotSupported("Could not mute logging to console."); + return false; + } + log.info("Log level override, property solr.log.level=" + logLevel); + LogManager.getRootLogger().setLevel(Level.toLevel(logLevel, Level.INFO)); + return true; + } catch (Exception e) { + logNotSupported("Could not change log level."); + return false; + } + } + private static boolean isLog4jActive() { try { // Make sure we have log4j LogManager in classpath diff --git a/solr/server/resources/log4j.properties b/solr/server/resources/log4j.properties index 9d8eca0816a..9a5e3fdea15 100644 --- a/solr/server/resources/log4j.properties +++ b/solr/server/resources/log4j.properties @@ -1,4 +1,5 @@ -# Logging level +# Default Solr log4j config +# rootLogger log level may be programmatically overridden by -Dsolr.log.level solr.log=logs log4j.rootLogger=INFO, file, CONSOLE @@ -17,11 +18,12 @@ log4j.appender.file.File=${solr.log}/solr.log log4j.appender.file.layout=org.apache.log4j.EnhancedPatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%n +# Adjust logging levels that should differ from root logger log4j.logger.org.apache.zookeeper=WARN log4j.logger.org.apache.hadoop=WARN log4j.logger.org.eclipse.jetty=WARN -log4j.logger.org.eclipse.jetty.server=INFO -log4j.logger.org.eclipse.jetty.server.handler=WARN +log4j.logger.org.eclipse.jetty.server.Server=INFO +log4j.logger.org.eclipse.jetty.server.ServerConnector=INFO # set to INFO to enable infostream log messages log4j.logger.org.apache.solr.update.LoggingInfoStream=OFF