You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Tracing.java 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*******************************************************************************
  2. * Copyright (c) 2005 IBM Corporation and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v 2.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  7. *
  8. * Contributors:
  9. * Matthew Webster - initial implementation
  10. * Sian January
  11. *******************************************************************************/
  12. package org.aspectj.lib.tracing;
  13. import org.aspectj.lang.*;
  14. /**
  15. * This root abstract aspect determines the basic tracing behaviour
  16. * i.e. entry/exit/exception using the method/constructor execution() pointcut
  17. * and before/after returning/after throwing advice. Determining what
  18. * methods and constructors belonging to which classes is delegated to a
  19. * user-supplied concrete aspect using an abstract pointcut. When tracing
  20. * occurs and what is done with the captured data is delegated to an abstract,
  21. * infrastructure-specific sub-aspect through template methods.
  22. */
  23. public abstract aspect Tracing {
  24. /**
  25. * Sub-aspects <b>must</b> implement this pointcut to determine what and when to
  26. * trace
  27. */
  28. protected abstract pointcut shouldTrace ();
  29. private pointcut staticContext () : !this(Object);
  30. private pointcut nonStaticContext (Object obj) : this(obj);
  31. private pointcut voidMethod () : execution(void *(..));
  32. public final static pointcut methodExecution () : execution(* *(..));
  33. public final static pointcut constructorExecution () : execution(new(..));
  34. public final static pointcut objectMethod () : execution(* Object.*(..));
  35. /**
  36. * Sub-aspects <b>may</b> override this point to determine which methods if any
  37. * are traced. By default include only public methods and those not inherited
  38. * from java.lang.Object e.g. toString().
  39. */
  40. protected pointcut includedMethod () :
  41. execution(public * *(..))
  42. && !objectMethod();
  43. /**
  44. * Sub-aspects <b>may</b> override this point to determine which constructors if any
  45. * are traced. By default include only public constructors.
  46. */
  47. protected pointcut includedConstructor () :
  48. execution(public new(..));
  49. /*
  50. * Exclude methods and constructors in Tracing and sub-aspects as well as
  51. * those in the control flow of Tracing advice or constructors to avoid recursion.
  52. */
  53. private pointcut excluded () :
  54. within(Tracing+)
  55. // || cflow((adviceexecution() || execution(new(..))) && within(Tracing+))
  56. || cflow((adviceexecution() && within(Tracing+)))
  57. ;
  58. /*
  59. * Trace only method execution included by the user but excluded by the aspect e.g. itself
  60. */
  61. private pointcut tracedMethod () :
  62. methodExecution()
  63. && includedMethod()
  64. && !excluded()
  65. ;
  66. /*
  67. * Trace only constructor execution included by the user but excluded by the aspect e.g. itself
  68. */
  69. private pointcut tracedConstructor (Object obj) :
  70. constructorExecution()
  71. && includedConstructor()
  72. && !excluded()
  73. && this(obj)
  74. ;
  75. /*
  76. * Trace entry to instance methods
  77. *
  78. * Tracing pattern 1: Only use thisJoinPoint in before()
  79. */
  80. before (Object obj) : tracedMethod() && nonStaticContext(obj) && shouldTrace() {
  81. enter(thisJoinPoint,obj);
  82. }
  83. /*
  84. * Trace entry to static methods
  85. *
  86. * Tracing pattern 1: Only use thisJoinPoint in before()
  87. */
  88. before () : tracedMethod() && staticContext() && shouldTrace() {
  89. enter(thisJoinPoint);
  90. }
  91. /*
  92. * Trace exit from void methods
  93. *
  94. * Tracing pattern 1: Use thisJoinPointStaticPart in after()
  95. */
  96. after() returning() : tracedMethod() && voidMethod() && shouldTrace() {
  97. exit(thisJoinPointStaticPart);
  98. }
  99. /*
  100. * Trace exit from non-void methods including return value
  101. *
  102. * Tracing pattern 1: Use thisJoinPointStaticPart in after()
  103. */
  104. after() returning(Object ret) : tracedMethod() && !voidMethod() && shouldTrace() {
  105. exit(thisJoinPointStaticPart,ret);
  106. }
  107. /*
  108. * Trace exceptions thrown from methods and constructors
  109. *
  110. * Tracing pattern 1: Use thisJoinPointStaticPart in after()
  111. */
  112. after() throwing(Throwable th) : (tracedMethod() || tracedConstructor(Object)) && shouldTrace() {
  113. if (shouldTrace(th)) exception(thisJoinPointStaticPart,th);
  114. }
  115. /*
  116. * Trace entry to constructors
  117. *
  118. * Tracing pattern 1: Only use thisJoinPoint in before()
  119. */
  120. before () : tracedConstructor(Object) && shouldTrace() {
  121. enter(thisJoinPoint);
  122. }
  123. /*
  124. * Trace exit from constructors including new object
  125. *
  126. * Tracing pattern 1: Only use thisJoinPoint in before()
  127. */
  128. after (Object obj) : tracedConstructor(obj) && shouldTrace() {
  129. exit(thisJoinPointStaticPart,obj);
  130. }
  131. /*
  132. * Template methods to log data implemented by infrastructure-specific sub-aspects
  133. * e.g. java.util.logging.Logger
  134. */
  135. protected abstract void enter (JoinPoint jp, Object obj);
  136. protected abstract void enter (JoinPoint jp);
  137. protected abstract void exit (JoinPoint.StaticPart sjp);
  138. protected abstract void exit (JoinPoint.StaticPart sjp, Object ret);
  139. protected abstract void exception (JoinPoint.StaticPart sjp, Throwable th);
  140. /**
  141. * Format arguments into a comma separated list
  142. *
  143. * @param names array of argument names
  144. * @param args array of arguments
  145. * @return the formated list
  146. */
  147. protected String formatArgs (String[] names, Object[] args) {
  148. StringBuffer sb = new StringBuffer();
  149. for (int i = 0; i < args.length; i++) {
  150. sb.append(formatParam(names[i],args[i]));
  151. if (i < args.length-1) sb.append(", ");
  152. }
  153. return sb.toString();
  154. }
  155. /**
  156. * Format objects safely avoiding toString which can cause recursion,
  157. * NullPointerExceptions or highly verbose results.
  158. *
  159. * @param obj parameter to be formatted
  160. * @return the formated parameter
  161. */
  162. protected Object formatObj (Object obj) {
  163. if (obj == null
  164. || obj instanceof String
  165. || obj instanceof Number
  166. || obj instanceof Boolean
  167. || obj instanceof Character
  168. || obj instanceof Class
  169. || obj instanceof StringBuffer
  170. ) return obj;
  171. else try {
  172. return obj.getClass().getName() + "@" + Integer.toString(obj.hashCode(),16);
  173. } catch (Exception ex) {
  174. return obj.getClass().getName();
  175. }
  176. }
  177. /**
  178. * Format parameter into name=value pair
  179. *
  180. * @param name parameter name
  181. * @param arg parameted to be formatted
  182. * @return the formated parameter
  183. */
  184. protected String formatParam (String name, Object arg) {
  185. return name + "=" + formatObj(arg);
  186. }
  187. /**
  188. * By default we do not trace errors e.g. OutOfMemoryError because the
  189. * system my be in an inconsistent state. However users may override this
  190. *
  191. * @param th excpeption or error to be traced
  192. * @return whether it should be traced
  193. */
  194. protected boolean shouldTrace (Throwable th) {
  195. return !(th instanceof Error);
  196. }
  197. }