/*
|
* CDDL HEADER START
|
*
|
* The contents of this file are subject to the terms of the
|
* Common Development and Distribution License, Version 1.0 only
|
* (the "License"). You may not use this file except in compliance
|
* with the License.
|
*
|
* You can obtain a copy of the license at
|
* trunk/opends/resource/legal-notices/OpenDS.LICENSE
|
* or https://OpenDS.dev.java.net/OpenDS.LICENSE.
|
* See the License for the specific language governing permissions
|
* and limitations under the License.
|
*
|
* When distributing Covered Code, include this CDDL HEADER in each
|
* file and include the License file at
|
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
|
* add the following below this CDDL HEADER, with the fields enclosed
|
* by brackets "[]" replaced with your own identifying information:
|
* Portions Copyright [yyyy] [name of copyright owner]
|
*
|
* CDDL HEADER END
|
*
|
*
|
* Copyright 2006-2008 Sun Microsystems, Inc.
|
*/
|
package org.opends.server.loggers.debug;
|
|
import org.aspectj.lang.annotation.*;
|
import org.aspectj.lang.JoinPoint;
|
|
import static
|
org.opends.server.loggers.debug.DebugLogger.DEFAULT_CONSTRUCTOR_LEVEL;
|
import static
|
org.opends.server.loggers.debug.DebugLogger.DEFAULT_ENTRY_EXIT_LEVEL;
|
import static
|
org.opends.server.loggers.debug.DebugLogger.DEFAULT_THROWN_LEVEL;
|
|
/**
|
* An aspect for source-code tracing at the method level.
|
*
|
* One DebugLogger aspect instance exists for each Java class using tracing.
|
* Tracer must be registered with the DebugLogger.
|
*
|
* Logging is always done at a level basis, with debug log messages
|
* exceeding the trace threshold being traced, others being discarded.
|
*/
|
@Aspect()
|
public class DebugAspect
|
{
|
/**
|
* Pointcut for matching static context events.
|
*/
|
@Pointcut("!this(Object)")
|
private void staticContext()
|
{
|
}
|
|
/**
|
* Pointcut for matching non static context events.
|
* @param obj The object being operated on.
|
*/
|
@Pointcut("this(obj)")
|
private void nonStaticContext(Object obj)
|
{
|
}
|
|
/**
|
* Pointcut for matching all toString() methods.
|
*/
|
@Pointcut("execution(* *..toString(..))")
|
private void toStringMethod()
|
{
|
}
|
|
/**
|
* Pointcut for matching all getMessage() methods.
|
*/
|
@Pointcut("execution(String org.opends.server." +
|
"messages.MessageHandler.getMessage(..))")
|
private void getMessageMethod()
|
{
|
}
|
|
/**
|
* Pointcut for matching the getDirectoryThreadGroup method.
|
*/
|
@Pointcut("execution(public static ThreadGroup org.opends.server." +
|
"core.DirectoryServer.getDirectoryThreadGroup(..))")
|
private void getThreadGroupMethod()
|
{
|
}
|
|
/**
|
* Pointcut for matching all getDebugProperties() methods.
|
* TODO: Make this less general. Find out if pointcut matches
|
* subclass methods.
|
*/
|
@Pointcut("execution(* *..getDebugProperties(..))")
|
private void getDebugPropertiesMethod()
|
{
|
}
|
|
/**
|
* Pointcut for matching all logging related classes.
|
*/
|
@Pointcut("within(org.opends.server.loggers.*+ || " +
|
"org.opends.server.loggers.debug..*+ || " +
|
"org.opends.server.types.DebugLogLevel+ || " +
|
"org.opends.server.types.DebugLogCategory+ || " +
|
"org.opends.server.api.DebugLogPublisher+ || " +
|
"org.opends.server.util.TimeThread+ ||" +
|
"org.opends.server.util.MultiOutputStream+)")
|
private void debugRelatedClasses()
|
{
|
}
|
|
/**
|
* Pointcut to exclude all pointcuts which should not be adviced by the
|
* debug logger.
|
*/
|
@Pointcut("toStringMethod() || getMessageMethod() || " +
|
"getDebugPropertiesMethod() || debugRelatedClasses() || " +
|
"getThreadGroupMethod()")
|
private void excluded()
|
{
|
}
|
|
/**
|
* Pointcut for matching the execution of all public methods.
|
*/
|
@Pointcut("execution(!@(DebugLogger.NoDebugTracing || " +
|
"DebugLogger.NoEntryDebugTracing) public * *(..)) && " +
|
"!excluded()")
|
void tracedEntryMethod()
|
{
|
}
|
|
/**
|
* Pointcut for matching the execution of all public methods.
|
*/
|
@Pointcut("execution(!@(DebugLogger.NoDebugTracing || " +
|
"DebugLogger.NoExitDebugTracing) public * *(..)) && " +
|
"!excluded()")
|
void tracedExitMethod()
|
{
|
}
|
|
/**
|
* Pointcut for matching the execution of all public methods.
|
*/
|
@Pointcut("execution(@DebugLogger.TraceThrown public * *(..)) && " +
|
"!excluded()")
|
void tracedThrownMethod()
|
{
|
}
|
|
/**
|
* Pointcut for matching the execution of all constructors.
|
*/
|
@Pointcut("execution(!@(DebugLogger.NoDebugTracing || " +
|
"DebugLogger.NoEntryDebugTracing) public new(..)) && !excluded()")
|
void tracedEntryConstructor()
|
{
|
}
|
|
/**
|
* Pointcut for matching the execution of all constructors.
|
*/
|
@Pointcut("execution(!@(DebugLogger.NoDebugTracing || " +
|
"DebugLogger.NoExitDebugTracing) public new(..)) && !excluded()")
|
void tracedExitConstructor()
|
{
|
}
|
|
/**
|
* Pointcut for matching only if there are publishers.
|
*
|
* @return if debug logging is enabled.
|
*/
|
@Pointcut("if()")
|
public static boolean shouldTrace()
|
{
|
return DebugLogger.enabled;
|
}
|
|
/**
|
* AspectJ Implementation.
|
*
|
* @param thisJoinPoint the JoinPoint reflection object.
|
*/
|
@Before("shouldTrace() && tracedEntryConstructor()")
|
public void traceConstructor(JoinPoint thisJoinPoint)
|
{
|
String signature =
|
thisJoinPoint.getSignature().getDeclaringTypeName();
|
Object[] args = thisJoinPoint.getArgs();
|
DebugTracer tracer = DebugLogger.getTracer(signature);
|
if(tracer != null)
|
{
|
tracer.debugConstructor(
|
DEFAULT_CONSTRUCTOR_LEVEL, args);
|
}
|
}
|
|
/**
|
* AspectJ Implementation.
|
*
|
* @param thisJoinPoint the JoinPoint reflection object.
|
* @param obj the object this method operations on.
|
*/
|
@Before("shouldTrace() && tracedEntryMethod() && nonStaticContext(obj)")
|
public void traceNonStaticMethodEntry(JoinPoint thisJoinPoint, Object obj)
|
{
|
String signature =
|
thisJoinPoint.getSignature().getDeclaringTypeName();
|
Object[] args = thisJoinPoint.getArgs();
|
Object callerInstance = thisJoinPoint.getThis();
|
DebugTracer tracer = DebugLogger.getTracer(signature);
|
if(tracer != null)
|
{
|
tracer.debugMethodEntry(
|
DEFAULT_ENTRY_EXIT_LEVEL, callerInstance, args);
|
}
|
}
|
|
/**
|
* AspectJ Implementation.
|
*
|
* @param thisJoinPoint the JoinPoint reflection object.
|
*/
|
@Before("shouldTrace() && tracedEntryMethod() && staticContext()")
|
public void traceStaticMethodEntry(JoinPoint thisJoinPoint)
|
{
|
String signature =
|
thisJoinPoint.getSignature().getDeclaringTypeName();
|
Object[] args = thisJoinPoint.getArgs();
|
DebugTracer tracer = DebugLogger.getTracer(signature);
|
if(tracer != null)
|
{
|
tracer.debugStaticMethodEntry(
|
DEFAULT_ENTRY_EXIT_LEVEL, args);
|
}
|
}
|
|
/**
|
* AspectJ Implementation.
|
*
|
* @param thisJoinPointStaticPart the JoinPoint reflection object.
|
* @param ret the return value of the method.
|
*/
|
@AfterReturning(pointcut = "shouldTrace() && " +
|
"(tracedExitMethod() || tracedExitConstructor())",
|
returning = "ret")
|
public void traceReturn(JoinPoint.StaticPart thisJoinPointStaticPart,
|
Object ret)
|
{
|
String signature =
|
thisJoinPointStaticPart.getSignature().getDeclaringTypeName();
|
DebugTracer tracer = DebugLogger.getTracer(signature);
|
if(tracer != null)
|
{
|
tracer.debugReturn(
|
DEFAULT_ENTRY_EXIT_LEVEL, ret);
|
}
|
}
|
|
/**
|
* AspectJ Implementation.
|
*
|
* @param thisJoinPointStaticPart the JoinPoint reflection object.
|
* @param ex the exception thrown.
|
*/
|
@SuppressAjWarnings({"adviceDidNotMatch"})
|
@AfterThrowing(pointcut = "shouldTrace() && tracedThrownMethod()",
|
throwing = "ex")
|
public void traceThrown(JoinPoint.StaticPart thisJoinPointStaticPart,
|
Throwable ex)
|
{
|
String signature =
|
thisJoinPointStaticPart.getSignature().getDeclaringTypeName();
|
DebugTracer tracer = DebugLogger.getTracer(signature);
|
if(tracer != null)
|
{
|
tracer.debugThrown(
|
DEFAULT_THROWN_LEVEL, ex);
|
}
|
}
|
}
|