Java tutorial
/*************************************************************************** * Copyright 2012 Kieker Project (http://kieker-monitoring.net) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ package callcount.lib.probe; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import kieker.common.logging.Log; import kieker.common.logging.LogFactory; import kieker.monitoring.core.controller.IMonitoringController; import kieker.monitoring.core.controller.MonitoringController; import kieker.monitoring.core.registry.ControlFlowRegistry; import kieker.monitoring.core.registry.SessionRegistry; import kieker.monitoring.probe.aspectj.AbstractAspectJProbe; import kieker.monitoring.timer.ITimeSource; import callcount.lib.record.OperationExecutionStartRecord; import callcount.lib.record.OperationExecutionStopRecord; /** * @author Andre van Hoorn, Jan Waller */ @Aspect public abstract class AbstractStartEndAspect extends AbstractAspectJProbe { private static final Log LOG = LogFactory.getLog(AbstractStartEndAspect.class); private static final IMonitoringController CTRLINST = MonitoringController.getInstance(); private static final ITimeSource TIME = CTRLINST.getTimeSource(); private static final String VMNAME = CTRLINST.getHostname(); private static final ControlFlowRegistry CFREGISTRY = ControlFlowRegistry.INSTANCE; private static final SessionRegistry SESSIONREGISTRY = SessionRegistry.INSTANCE; @Pointcut public abstract void monitoredOperation(); @Around("monitoredOperation() && notWithinKieker()") public Object operation(final ProceedingJoinPoint thisJoinPoint) throws Throwable { // NOCS (Throwable) final String signature = thisJoinPoint.getSignature().toLongString(); if (!CTRLINST.isProbeActivated(signature)) { return thisJoinPoint.proceed(); } // collect data final boolean entrypoint; final String hostname = VMNAME; final String sessionId = SESSIONREGISTRY.recallThreadLocalSessionId(); final int eoi; // this is executionOrderIndex-th execution in this trace final int ess; // this is the height in the dynamic call tree of this execution long traceId = CFREGISTRY.recallThreadLocalTraceId(); // traceId, -1 if entry point if (traceId == -1) { entrypoint = true; traceId = CFREGISTRY.getAndStoreUniqueThreadLocalTraceId(); CFREGISTRY.storeThreadLocalEOI(0); CFREGISTRY.storeThreadLocalESS(1); // next operation is ess + 1 eoi = 0; ess = 0; } else { entrypoint = false; eoi = CFREGISTRY.incrementAndRecallThreadLocalEOI(); // ess > 1 ess = CFREGISTRY.recallAndIncrementThreadLocalESS(); // ess >= 0 if ((eoi == -1) || (ess == -1)) { LOG.error("eoi and/or ess have invalid values:" + " eoi == " + eoi + " ess == " + ess); CTRLINST.terminateMonitoring(); } } // measure before final long tin = TIME.getTime(); CTRLINST.newMonitoringRecord( new OperationExecutionStartRecord(signature, sessionId, traceId, tin, hostname, eoi, ess)); // execution of the called method final Object retval; try { retval = thisJoinPoint.proceed(); } finally { // measure after final long tout = TIME.getTime(); CTRLINST.newMonitoringRecord( new OperationExecutionStopRecord(sessionId, traceId, tout, hostname, eoi, ess)); // cleanup if (entrypoint) { CFREGISTRY.unsetThreadLocalTraceId(); CFREGISTRY.unsetThreadLocalEOI(); CFREGISTRY.unsetThreadLocalESS(); } else { CFREGISTRY.storeThreadLocalESS(ess); // next operation is ess } } return retval; } }