Merge branch 'cassandra-2.0' into cassandra-2.1 Conflicts: src/java/org/apache/cassandra/service/StorageService.java src/java/org/apache/cassandra/tools/NodeCmd.java src/resources/org/apache/cassandra/tools/NodeToolHelp.yaml
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/d402cf68 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/d402cf68 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/d402cf68 Branch: refs/heads/cassandra-2.1 Commit: d402cf687001390cf81307e2d9d45a87b24f5837 Parents: 24eeeb9 0a20f5f Author: Vijay <vijay2...@gmail.com> Authored: Mon Apr 28 21:38:22 2014 -0700 Committer: Vijay <vijay2...@gmail.com> Committed: Mon Apr 28 21:38:22 2014 -0700 ---------------------------------------------------------------------- conf/logback.xml | 2 +- .../cassandra/service/StorageService.java | 49 ++++++++++++++++++-- .../cassandra/service/StorageServiceMBean.java | 21 ++++++++- .../org/apache/cassandra/tools/NodeProbe.java | 17 +++++++ .../org/apache/cassandra/tools/NodeTool.java | 32 ++++++++++++- 5 files changed, 114 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/d402cf68/conf/logback.xml ---------------------------------------------------------------------- diff --cc conf/logback.xml index 655bcf6,0000000..2657174 mode 100644,000000..100644 --- a/conf/logback.xml +++ b/conf/logback.xml @@@ -1,34 -1,0 +1,34 @@@ +<configuration scan="true"> - ++ <jmxConfigurator /> + <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>/var/log/cassandra/system.log</file> + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>/var/log/cassandra/system.log.%i.zip</fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>20</maxIndex> + </rollingPolicy> + + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>20MB</maxFileSize> + </triggeringPolicy> + <encoder> + <pattern>%-5level [%thread] %date{ISO8601} %F:%L - %msg%n</pattern> + <!-- old-style log format + <pattern>%5level [%thread] %date{ISO8601} %F (line %L) %msg%n</pattern> + --> + </encoder> + </appender> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%-5level %date{HH:mm:ss,SSS} %msg%n</pattern> + </encoder> + </appender> + + <root level="INFO"> + <appender-ref ref="FILE" /> + <appender-ref ref="STDOUT" /> + </root> + + <logger name="com.thinkaurelius.thrift" level="ERROR"/> +</configuration> http://git-wip-us.apache.org/repos/asf/cassandra/blob/d402cf68/src/java/org/apache/cassandra/service/StorageService.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/service/StorageService.java index a9c0233,f44eaed..a284ab4 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@@ -29,14 -29,11 +29,20 @@@ import java.util.* import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; + ++import javax.management.JMX; import javax.management.MBeanServer; import javax.management.Notification; import javax.management.NotificationBroadcasterSupport; import javax.management.ObjectName; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; + ++import ch.qos.logback.classic.LoggerContext; ++import ch.qos.logback.classic.jmx.JMXConfiguratorMBean; ++import ch.qos.logback.classic.spi.ILoggingEvent; ++import ch.qos.logback.core.Appender; + import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Predicate; import com.google.common.collect.*; @@@ -44,9 -42,10 +50,8 @@@ import com.google.common.util.concurren import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Uninterruptibles; --import org.apache.cassandra.cql3.CQL3Type; import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@@ -2874,15 -2793,49 +2879,53 @@@ public class StorageService extends Not return liveEps; } - public void setLoggingLevel(String classQualifier, String rawLevel) - public void setLog4jLevel(String classQualifier, String rawLevel) ++ public void setLoggingLevel(String classQualifier, String rawLevel) throws Exception { - org.apache.log4j.Logger log4jlogger = org.apache.log4j.Logger.getLogger(classQualifier); + ch.qos.logback.classic.Logger logBackLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(classQualifier); ++ + // if both classQualifer and rawLevel are empty, reload from configuration - if (StringUtils.isBlank(classQualifier) && StringUtils.isBlank(rawLevel)) ++ if (StringUtils.isBlank(classQualifier) && StringUtils.isBlank(rawLevel) ) + { - LogManager.resetConfiguration(); - CassandraDaemon.initLog4j(); ++ JMXConfiguratorMBean jmxConfiguratorMBean = JMX.newMBeanProxy(ManagementFactory.getPlatformMBeanServer(), ++ new ObjectName("ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator"), ++ JMXConfiguratorMBean.class); ++ jmxConfiguratorMBean.reloadDefaultConfiguration(); + return; + } + // classQualifer is set, but blank level given - else if (StringUtils.isNotBlank(classQualifier) && StringUtils.isBlank(rawLevel)) ++ else if (StringUtils.isNotBlank(classQualifier) && StringUtils.isBlank(rawLevel) ) + { - if (log4jlogger.getLevel() != null || log4jlogger.getAllAppenders().hasMoreElements()) - log4jlogger.setLevel(null); ++ if (logBackLogger.getLevel() != null || hasAppenders(logBackLogger)) ++ logBackLogger.setLevel(null); + return; + } + - Level level = Level.toLevel(rawLevel); - log4jlogger.setLevel(level); + ch.qos.logback.classic.Level level = ch.qos.logback.classic.Level.toLevel(rawLevel); + logBackLogger.setLevel(level); - logger.info("set log level to {} for classes under '{}' (if the level doesn't look like '{}' then slf4j couldn't parse '{}')", level, classQualifier, rawLevel, rawLevel); + logger.info("set log level to {} for classes under '{}' (if the level doesn't look like '{}' then the logger couldn't parse '{}')", level, classQualifier, rawLevel, rawLevel); } - + /** + * @return the runtime logging levels for all the configured loggers + */ + @Override - public Map<String,String> getLoggingLevels() - { ++ public Map<String,String>getLoggingLevels() { + Map<String, String> logLevelMaps = Maps.newLinkedHashMap(); - org.apache.log4j.Logger rootLogger = org.apache.log4j.Logger.getRootLogger(); - logLevelMaps.put(rootLogger.getName(), rootLogger.getLevel().toString()); - Enumeration<org.apache.log4j.Logger> loggers = LogManager.getCurrentLoggers(); - while (loggers.hasMoreElements()) ++ LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); ++ for (ch.qos.logback.classic.Logger logger : lc.getLoggerList()) + { - org.apache.log4j.Logger logger= loggers.nextElement(); - if (logger.getLevel() != null) ++ if(logger.getLevel() != null || hasAppenders(logger)) + logLevelMaps.put(logger.getName(), logger.getLevel().toString()); + } + return logLevelMaps; + } + ++ private boolean hasAppenders(ch.qos.logback.classic.Logger logger) { ++ Iterator<Appender<ILoggingEvent>> it = logger.iteratorForAppenders(); ++ return it.hasNext(); ++ } ++ + /** * @return list of Token ranges (_not_ keys!) together with estimated key count, * breaking up the data this node is responsible for into pieces of roughly keysPerSplit */ http://git-wip-us.apache.org/repos/asf/cassandra/blob/d402cf68/src/java/org/apache/cassandra/service/StorageServiceMBean.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/service/StorageServiceMBean.java index aab8dcb,9b1487f..8bd57b8 --- a/src/java/org/apache/cassandra/service/StorageServiceMBean.java +++ b/src/java/org/apache/cassandra/service/StorageServiceMBean.java @@@ -329,8 -338,10 +329,25 @@@ public interface StorageServiceMBean ex */ public void forceRemoveCompletion(); -- /** set the logging level at runtime */ - public void setLoggingLevel(String classQualifier, String level); - public void setLog4jLevel(String classQualifier, String level); - - public Map<String,String>getLoggingLevels(); ++ /** ++ * set the logging level at runtime<br> ++ * <br> ++ * If both classQualifer and level are empty/null, it will reload the configuration to reset.<br> ++ * If classQualifer is not empty but level is empty/null, it will set the level to null for the defined classQualifer<br> ++ * If level cannot be parsed, then the level will be defaulted to DEBUG<br> ++ * <br> ++ * The logback configuration should have < jmxConfigurator /> set ++ * ++ * @param classQualifier The logger's classQualifer ++ * @param level The log level ++ * @throws Exception ++ * ++ * @see ch.qos.logback.classic.Level#toLevel(String) ++ */ ++ public void setLoggingLevel(String classQualifier, String level) throws Exception; ++ ++ /** get the runtime logging levels */ ++ public Map<String,String> getLoggingLevels(); /** get the operational mode (leaving, joining, normal, decommissioned, client) **/ public String getOperationMode(); http://git-wip-us.apache.org/repos/asf/cassandra/blob/d402cf68/src/java/org/apache/cassandra/tools/NodeProbe.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/tools/NodeProbe.java index d4cef15,f0ee15d..8e3840c --- a/src/java/org/apache/cassandra/tools/NodeProbe.java +++ b/src/java/org/apache/cassandra/tools/NodeProbe.java @@@ -1132,6 -916,16 +1132,23 @@@ public class NodeProbe implements AutoC { spProxy.reloadTriggerClasses(); } + + public void setLoggingLevel(String classQualifier, String level) + { - ssProxy.setLog4jLevel(classQualifier, level); ++ try ++ { ++ ssProxy.setLoggingLevel(classQualifier, level); ++ } ++ catch (Exception e) ++ { ++ throw new RuntimeException("Error setting log for " + classQualifier +" on level " + level +". Please check logback configuration and ensure to have <jmxConfigurator /> set", e); ++ } + } + + public Map<String, String> getLoggingLevels() + { - return ssProxy.getLoggingLevels(); ++ return ssProxy.getLoggingLevels(); + } } class ColumnFamilyStoreMBeanIterator implements Iterator<Map.Entry<String, ColumnFamilyStoreMBean>>