Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,9 @@
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.perf4j</groupId>
<artifactId>perf4j</artifactId>
<version>0.9.12</version>
<groupId>com.ecyrd.speed4j</groupId>
<artifactId>speed4j</artifactId>
<version>0.5</version>
</dependency>

<!-- Note the optional tag. If you need to use fastinfoset serialization, you must include this dependency in your project! -->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,26 @@
package me.prettyprint.cassandra.connection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;

import me.prettyprint.cassandra.service.CassandraClientMonitor;
import me.prettyprint.cassandra.service.*;
import me.prettyprint.cassandra.service.CassandraClientMonitor.Counter;
import me.prettyprint.cassandra.service.CassandraHost;
import me.prettyprint.cassandra.service.CassandraHostConfigurator;
import me.prettyprint.cassandra.service.ExceptionsTranslator;
import me.prettyprint.cassandra.service.ExceptionsTranslatorImpl;
import me.prettyprint.cassandra.service.FailoverPolicy;
import me.prettyprint.cassandra.service.JmxMonitor;
import me.prettyprint.cassandra.service.Operation;
import me.prettyprint.hector.api.ClockResolution;
import me.prettyprint.hector.api.exceptions.HCassandraInternalException;
import me.prettyprint.hector.api.exceptions.HInvalidRequestException;
import me.prettyprint.hector.api.exceptions.HTimedOutException;
import me.prettyprint.hector.api.exceptions.HUnavailableException;
import me.prettyprint.hector.api.exceptions.HectorException;
import me.prettyprint.hector.api.exceptions.HectorTransportException;
import me.prettyprint.hector.api.exceptions.PoolExhaustedException;
import me.prettyprint.hector.api.exceptions.*;

import org.apache.cassandra.thrift.AuthenticationRequest;
import org.apache.cassandra.thrift.Cassandra;
import org.cliffc.high_scale_lib.NonBlockingHashMap;
import org.perf4j.StopWatch;
import org.perf4j.slf4j.Slf4JStopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ecyrd.speed4j.StopWatch;
import com.ecyrd.speed4j.StopWatchFactory;
import com.ecyrd.speed4j.log.PeriodicalLog;

public class HConnectionManager {

private static final Logger log = LoggerFactory.getLogger(HConnectionManager.class);
private static final Logger perf4jLogger =
LoggerFactory.getLogger("me.prettyprint.cassandra.hector.TimingLogger");
private StopWatchFactory stopWatchFactory;

private final NonBlockingHashMap<CassandraHost,HClientPool> hostPools;
private final NonBlockingHashMap<CassandraHost,HClientPool> suspendedHostPools;
Expand All @@ -48,7 +31,6 @@ public class HConnectionManager {
private LoadBalancingPolicy loadBalancingPolicy;
private CassandraHostConfigurator cassandraHostConfigurator;
private HostTimeoutTracker hostTimeoutTracker;

private final ClockResolution clock;

final ExceptionsTranslator exceptionsTranslator;
Expand Down Expand Up @@ -89,6 +71,19 @@ public HConnectionManager(String clusterName, CassandraHostConfigurator cassandr
nodeAutoDiscoverService.doAddNodes();
}
}

//
// This sets up the Speed4J logging system. Alternatively, we could
// use the speed4j.properties -file. This was chosen just so that
// it wouldn't confuse anyone and would work pretty much the same
// way as what the old hector config does.
//
PeriodicalLog slog = new PeriodicalLog();
slog.setName("hector-"+clusterName);
slog.setPeriod(60); // 60 seconds
slog.setSlf4jLogname( "me.prettyprint.cassandra.hector.TimingLogger" );

stopWatchFactory = StopWatchFactory.getInstance( slog );
}

/**
Expand Down Expand Up @@ -202,7 +197,7 @@ public List<String> getStatusPerPool() {


public void operateWithFailover(Operation<?> op) throws HectorException {
final StopWatch stopWatch = new Slf4JStopWatch(perf4jLogger);
final StopWatch stopWatch = stopWatchFactory.getStopWatch();
int retries = Math.min(op.failoverPolicy.numRetries, hostPools.size());
HThriftClient client = null;
HClientPool pool = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,37 +62,6 @@ public void registerMonitor(String name, String monitorType, Object monitoringIn
}

mbs.registerMBean(monitoringInterface, oName);

// Register perf4j monitors
if ("true".equalsIgnoreCase(
System.getProperty("com.prettyprint.cassandra.load_hector_log4j", "true"))) {
registerPerf4J();
}
}

private void registerPerf4J() {
URL url = getClass().getClassLoader().getResource("hectorLog4j.xml");
if (url == null) {
log.warn("Unable to locate hectorLog4j.xml; performance counters will not be exported");
} else {
try {
final Class<?> domConfiguratorClass = getClass().getClassLoader().loadClass("org.apache.log4j.xml.DOMConfigurator");
final Method method = domConfiguratorClass.getMethod( "configure", URL.class );
method.invoke( null, url );
} catch( ClassNotFoundException e ) {
log.warn("Unable to load log4j's DOMConfigurator. Performance counters will not be exported. To fix, include the log4j jar in your application's classpath.");
} catch( SecurityException e ) {
log.error( "Could not access method DOMConfigurator.configure(URL)", e );
} catch( NoSuchMethodException e ) {
log.error( "Could not find method DOMConfigurator.configure(URL)", e );
} catch( IllegalArgumentException e ) {
log.error( "Could not invoke method DOMConfigurator.configure(URL)", e );
} catch( IllegalAccessException e ) {
log.error( "Could not invoke method DOMConfigurator.configure(URL)", e );
} catch( InvocationTargetException e ) {
throw new RuntimeException(e.getCause());
}
}
}

private String generateMonitorName(String className, String monitorType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

/**
* Specifies the "type" of operation - read or write.
* It's used for perf4j, so should be in sync with hectorLog4j.xml
* It's used for Speed4j, so should be in sync with hectorLog4j.xml
* @author Ran Tavory (ran@outbain.com)
*
*/
Expand Down
48 changes: 0 additions & 48 deletions core/src/main/resources/hectorLog4j.xml
Original file line number Diff line number Diff line change
@@ -1,53 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
<!--
This AsyncCoalescingStatisticsAppender groups StopWatch log messages
into GroupedTimingStatistics messages which it sends on the
file appender defined below
-->
<appender name="hector_CoalescingStatistics" class="org.perf4j.log4j.AsyncCoalescingStatisticsAppender">
<!--
The TimeSlice option is used to determine the time window for which
all received StopWatch logs are aggregated to create a single
GroupedTimingStatistics log. Here we set it to 10 seconds, overriding
the default of 30000 ms
-->
<param name="TimeSlice" value="10000"/>
<!-- send to downstream jmx appender -->
<appender-ref ref="perf4jJmxAppender"/>
</appender>

<!--
This JMX appender creates an MBean and publishes it to the platform MBean server by
default.
-->
<appender name="perf4jJmxAppender" class="org.perf4j.log4j.JmxAttributeStatisticsAppender">
<!--
You must specify the tag names whose statistics should be exposed as
MBean attributes.
-->
<param name="TagNamesToExpose"
value="READ.success_,WRITE.success_,READ.fail_,WRITE.fail_,META_READ.success_,META_READ.fail_"/>
<!--
You can also specify an optional MBeanName param, which overrides
the default MBean name of org.perf4j:type=StatisticsExposingMBean,name=Perf4J
-->
<param name="MBeanName" value="me.prettyprint.cassandra.service:type=perf4j,name=perf4j"/>

</appender>

<!-- Loggers -->
<!--
The Perf4J logger. Note that org.perf4j.TimingLogger is the value of the
org.perf4j.StopWatch.DEFAULT_LOGGER_NAME constant. Also, note that
additivity is set to false, which is usually what is desired - this means
that timing statements will only be sent to this logger and NOT to
upstream loggers.
-->
<logger name="me.prettyprint.cassandra.hector.TimingLogger" additivity="false">
<level value="TRACE"/>
<appender-ref ref="hector_CoalescingStatistics"/>
</logger>

</log4j:configuration>
21 changes: 21 additions & 0 deletions core/src/main/resources/speed4j.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#
# This is the main configuration for Speed4j. You may override this in your
# own project.
#
# For hector, we define a simple Log which is used to both output things
# to the given SLF4J logger, as well as display it in a JMX bean.
#

# Which Log instance shall we use?
speed4j.hector = com.ecyrd.speed4j.log.PeriodicalLog

# How often shall this Log log (in seconds)?
speed4j.hector.period = 60

# Which of these attributes shall be exposed in JMX?
speed4j.hector.jmx=READ.success_,WRITE.success_,READ.fail_,WRITE.fail_,META_READ.success_,META_READ.fail_

# Which SLF4J log name shall we output to? Speed4J uses the INFO log level.
# Note that this is slightly different from the old Log4J name just to ensure that we
# don't mess with any existing log4j configurations.
speed4j.hector.slf4jLogname=me.prettyprint.hector.TimingLogger