/* * @(#) SystemArchitectureAspect.java * Created Dec 23, 2010 by oleg * (C) ONE, SIA */ package odkl.cassandra.stat; import java.net.InetAddress; import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.io.CompactionIterator; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.thrift.ConsistencyLevel; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import one.conf.Configuration; import one.conf.ConfigurationFactory; import one.conf.dynamic.ConfigurationException; /** * Defines all logging pointcuts for cassandra to collect stats to one-log * * NOTE: * To enable these aspects you should list em in META-INF/aop.xml <aspects> list * and run java with -javaagent:/path/to/aspectjweaver.jar * * @author Oleg Anastasyev<oa@one.lv> */ @Aspect public abstract class SystemArchitectureAspect { public static String OP_LOGGER_NAME = "stats.cassandra.server"; public static String MSG_LOGGER_NAME = "msg.cassandra.server"; @Pointcut("call( public org.apache.cassandra.utils.LatencyTracker.new() )") public void latencyTrackerPointcut() {} // local store statistic points @Pointcut("set( org.apache.cassandra.utils.LatencyTracker org.apache.cassandra.db.ColumnFamilyStore.read* )") public void readLatencyTrackerPointcut() {} @Pointcut("set( org.apache.cassandra.utils.LatencyTracker org.apache.cassandra.db.ColumnFamilyStore.write* )") public void writeLatencyTrackerPointcut() {} @Pointcut("execution( org.apache.cassandra.db.ColumnFamilyStore.new(String,..) )") public void cfsPointcut() {} @Pointcut("within( odkl.cassandra.stat.* )") public void withinStatPointcut() {} // proxy (coodinator node) statistic points @Pointcut("set( org.apache.cassandra.utils.LatencyTracker org.apache.cassandra.service.StorageProxy.range* )") public void proxyRangeLatencyTrackerPointcut() {} // how long node waited for write to be acked by all endpoints // to decide on hint write @Pointcut("set( org.apache.cassandra.utils.LatencyTracker org.apache.cassandra.service.StorageProxy.hint* )") public void proxyHintLatencyTrackerPointcut() {} // READ.ONE calls @Pointcut("execution( * org.apache.cassandra.service.StorageProxy.weak*(..) ) ") public void proxyWeakReadPointcut() {} // READ QUORUM and more calls @Pointcut("execution( * org.apache.cassandra.service.StorageProxy.strong*(..,org.apache.cassandra.thrift.ConsistencyLevel) ) && args(..,cl) ") public void proxyStrongReadPointcut(ConsistencyLevel cl) {} // WRITE.ONE calls @Pointcut("execution( * org.apache.cassandra.service.StorageProxy.mutate(..) ) ") public void proxyWriteOnePointcut() {} // WRITE.QUORUM and more calls @Pointcut("execution( * org.apache.cassandra.service.StorageProxy.mutateBlocking(..,org.apache.cassandra.thrift.ConsistencyLevel) ) && args(..,cl) ") public void proxyWriteQuorumPointcut(ConsistencyLevel cl) {} // RANGE calls @Pointcut("execution( * org.apache.cassandra.service.StorageProxy.getRangeSlice(..,org.apache.cassandra.thrift.ConsistencyLevel) ) && args(..,cl) ") public void proxyRangePointcut(ConsistencyLevel cl) {} // when read repair happens this method is called @Pointcut("execution( * org.apache.cassandra.service.StorageProxy.countReadRepair() )") public void proxyRRPointcut() {} // HH activity // store of hint at coordinator node @Pointcut("execution( * org.apache.cassandra.db.HintedHandOffManager+.storeHint(java.net.InetAddress,..) ) && args(endpoint,..)") public void hintStorePointcut(InetAddress endpoint) {} // hint delivery @Pointcut("( execution( * org.apache.cassandra.db.HintedHandOffManager+.sendMessage(java.net.InetAddress,..) ) " + "|| execution( * org.apache.cassandra.db.HintedHandOffManager+.deliverHint(java.net.InetAddress,..) ) ) " + "&& args(endpoint,..)") public void hintDeliveryPointcut(InetAddress endpoint) {} // start and stop of cassandra service. this is neccessary for statistics collection daemons starting and stopping to mixin their init and stop code @Pointcut("execution( * org.apache.cassandra.thrift.CassandraDaemon.setup(..) ) ") public void cassandraStart() {} @Pointcut("execution( * org.apache.cassandra.thrift.CassandraDaemon.stop(..) ) ") public void cassandraStop() {} // start of apache cassandra non embedded server. @Pointcut("execution( * org.apache.cassandra.tools.WrapperMain.start(..) ) ") public void wrapperStart() {} /** * Called when any message just read from channel was dropped due to rpc timeout. * @param verb kind of message */ @Pointcut("execution( * org.apache.cassandra.net.MessagingService.incrementDroppedMessages(org.apache.cassandra.service.StorageService.Verb) ) && args(verb)") public void droppedMessage(StorageService.Verb verb) {} @Pointcut("execution( * org.apache.cassandra.db.CompactionManager.CompactionExecutor.beginCompaction(org.apache.cassandra.db.ColumnFamilyStore,org.apache.cassandra.io.CompactionIterator) ) && args(cfs,ci)") public void compactionStartedPointcut(ColumnFamilyStore cfs, CompactionIterator ci) {} @Pointcut("execution( * org.apache.cassandra.db.CompactionManager.CompactionExecutor.afterExecute(..) )") public void compactionCompletedPointcut() {} @Before("wrapperStart()") public void initStatistics() { if ( Configuration.get() == null ) { try { LogFactory.getLog(SystemArchitectureAspect.class).info("Standalone apache cassandra server initialization of statistics 2.0"); new ConfigurationFactory().startManaging(); } catch (ConfigurationException e) { LogFactory.getLog(SystemArchitectureAspect.class) .fatal("Cannot initialize one-conf. Cannot continue, sorry",e); System.exit(-1); } } } }