/*
* @(#) StorageProxyStatsAspect.java
* Created Nov 4, 2011 by oleg
* (C) ONE, SIA
*/
package odkl.cassandra.stat;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.service.StorageService.Verb;
import org.apache.cassandra.thrift.ConsistencyLevel;
import org.apache.cassandra.utils.FBUtilities;
import org.apache.cassandra.utils.LatencyTracker;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import one.log.util.LoggerUtil;
/**
* This collects one-log statistics from StorageProxy - i.e. coordinator node perofrmance
*
* @author Oleg Anastasyev<oa@hq.one.lv>
*
*/
@Aspect
public class StorageProxyStatsAspect extends SystemArchitectureAspect
{
private final Log log= LogFactory.getLog(getClass());
private final Object[] parameters = new Object[] { DatabaseDescriptor.getClusterName(), FBUtilities.getLocalAddress().getHostAddress() };
/**
* Logger of one-log to file stats to.
* for current DAO instance.
*/
private Log opLogger = LogFactory.getLog(OP_LOGGER_NAME);
/**
* timeout to feed into stats
*/
private long timeout = DatabaseDescriptor.getRpcTimeout() ;
@Around("proxyHintLatencyTrackerPointcut()")
public void hintTracker(ProceedingJoinPoint join) throws Throwable
{
// this is inside column family store
join.proceed(new Object[] { buildTracker("WRITE.HINTING") });
}
@Around("proxyRangeLatencyTrackerPointcut()")
public void rangeTracker(ProceedingJoinPoint join) throws Throwable
{
// this is inside column family store
join.proceed(new Object[] { buildTracker("RANGE") });
}
@Around("proxyWeakReadPointcut()")
public Object weakRead(ProceedingJoinPoint join) throws Throwable
{
return collectStats(join, "READ.ONE");
}
@Around("proxyStrongReadPointcut(cl)")
public Object strongRead(ProceedingJoinPoint join, ConsistencyLevel cl) throws Throwable
{
return collectStats(join, "READ."+cl);
}
@Around("proxyWriteOnePointcut()")
public Object writeOne(ProceedingJoinPoint join) throws Throwable
{
return collectStats(join, "WRITE.ONE");
}
@Around("proxyWriteQuorumPointcut(cl)")
public Object writeQuorum(ProceedingJoinPoint join, ConsistencyLevel cl) throws Throwable
{
return collectStats(join, "WRITE."+cl);
}
@Around("proxyRangePointcut(cl)")
public Object range(ProceedingJoinPoint join, ConsistencyLevel cl) throws Throwable
{
return collectStats(join, "RANGE."+cl);
}
@After("proxyRRPointcut()")
public void readRepair() throws Throwable
{
LoggerUtil.operationsSuccess(OP_LOGGER_NAME, 0, 1, "READ.REPAIR", parameters);
}
@After("droppedMessage(verb)")
public void dropped(StorageService.Verb verb)
{
long rpcTimeout = DatabaseDescriptor.getRpcTimeout();
String opName = (verb == Verb.MUTATION ? "WRITE" : verb.toString())+".STORE";
LoggerUtil.operationFailure(OP_LOGGER_NAME, LoggerUtil.getMeasureStartTime() - rpcTimeout - 1, rpcTimeout, opName, parameters);
}
private Object collectStats(ProceedingJoinPoint join, String opName) throws Throwable
{
final long time = LoggerUtil.getMeasureStartTime();
boolean ok=false;
try {
final Object result=join.proceed();
ok=true;
// method call finished successfully
LoggerUtil.operationSuccess(OP_LOGGER_NAME, time, timeout, opName, parameters);
return result;
}
finally
{
if (!ok)
LoggerUtil.operationFailure(OP_LOGGER_NAME, time, timeout, opName, parameters);
}
}
protected LatencyTracker buildTracker(String op)
{
log.debug("Initialized logging tracker for "+op+" by "+this);
return new LoggerLatencyTracker(OP_LOGGER_NAME, op, parameters);
}
}