View Javadoc

1   /* Copyright (c) 2008-2009 HomeAway, Inc.
2    * All rights reserved.  http://www.perf4j.org
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.perf4j.aop;
17  
18  import org.perf4j.StopWatch;
19  
20  import java.lang.annotation.Retention;
21  import java.lang.annotation.Target;
22  import java.lang.annotation.RetentionPolicy;
23  import java.lang.annotation.ElementType;
24  
25  /**
26   * The Profiled annotation is used in concert with the log4j or javalog TimingAspects to enable unobtrusive
27   * performance logging. Methods with this annotation, when enabled with the TimingAspect, will automatically have
28   * their execution time logged.
29   *
30   * @see <a href="http://perf4j.codehaus.org/devguide.html#Adding_the_Profiled_Annotation_to_Method_Declarations">The Perf4J Developer Guide Profiled Annotations Overview</a>
31   * @author Alex Devine
32   */
33  @Retention(RetentionPolicy.RUNTIME)
34  @Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
35  public @interface Profiled {
36      public static final String DEFAULT_TAG_NAME = "@@USE_METHOD_NAME";
37  
38      /**
39       * The tag that should be set on the {@link org.perf4j.StopWatch} when the execution time is logged. If not
40       * specified then the name of the method being annotated will be used for the tag name.
41       *
42       * @return The StopWatch tag
43       */
44      String tag() default DEFAULT_TAG_NAME;
45  
46      /**
47       * The optional message element can be used to set a message on the {@link org.perf4j.StopWatch} that is logged.
48       *
49       * @return The optional message specified for this annotation.
50       */
51      String message() default "";
52  
53      /**
54       * The name of the logger (either a log4J or java.logging Logger, depending on the Aspect in use at runtime) to
55       * use to log the {@link org.perf4j.StopWatch}.
56       *
57       * @return The logger name, defaults to StopWatch.DEFAULT_LOGGER_NAME
58       */
59      String logger() default StopWatch.DEFAULT_LOGGER_NAME;
60  
61      /**
62       * The level to use when logging the StopWatch. Defaults to INFO. Acceptable values are taken from names of the
63       * standard log4j Levels.
64       *
65       * @return The level to use when logging the StopWatch
66       * @see <a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Level.html">log4j Level class</a>
67       */
68      String level() default "INFO";
69  
70      /**
71       * Whether or not the tag and message elements should support Java Expression Language syntax. Setting this to true
72       * enables the tag name to be dynamic with respect to the arguments passed to the method being profiled, the
73       * return value or exception thrown from the method (if any), and the object on which the method is being called.
74       * An Expression Language expression is delimited with curly brackets, and arguments are accessed using the
75       * following variable names:
76       * <p>
77       * <ul>
78       * <li>$0, $1, $2, $3, etc. - the parameters passed to the method in declaration order
79       * <li>$this - the object whose method is being called - when a static class method is profiled, this
80       * will always be null
81       * <li>$return - the return value from the method, which will be null if the method has a void return type, or an
82       * exception was thrown during method execution
83       * <li>$exception - the value of any Throwable thrown by the method - will be null if the method returns normally
84       * </ul>
85       * <p>
86       * For example, suppose you want to profile the <tt>doGet()</tt> method of a servlet, with the tag name dependent
87       * on the name of the servlet AND the path info (as returned by getPathInfo()) of the request.
88       * You could create the following annotation:
89       *
90       * <pre>
91       * &#064;Profiled(tag = "servlet{$this.servletName}_{$0.pathInfo}", el = true)
92       * protected void doGet(HttpServletRequest req, HttpServletResponse res) {
93       * ...
94       * }
95       * </pre>
96       *
97       * If the doGet() method is called with a request whose getPathInfo() method returns "/sub/path", and the servlet's
98       * name if "main", then the tag used when logging a StopWatch will be "servletMain_/sub/path".
99       *
100      * @return True if expression language support should be enabled, false to disable support - defaults to true.
101      * @see <a href="http://commons.apache.org/jexl/">Apache Commons JEXL</a>
102      */
103     boolean el() default true;
104 
105     /**
106      * Whether or not separate tags should be used depending on whether or not the annotated method returns normally
107      * or by throwing an exception. If true, then when the method returns normally the tag name used is
108      * <tt>tag() + ".success"</tt>, when the method throws an exception the tag name used is
109      * <tt>tag() + ".failure"</tt>.
110      *
111      * @return Whether or not failures should be logged under a separate tag, defaults to false.
112      */
113     boolean logFailuresSeparately() default false;
114 
115     /**
116      * If the timeThreshold is set to a positive value, then the method execution time will be logged only if took
117      * more than timeThreshold milliseconds. Thus, this value can be used if you only want to log method executions that
118      * are unexpectedly slow.
119      *
120      * @return The time threshold for logging, in milliseconds.
121      */
122     long timeThreshold() default 0;
123     
124     /**
125      * Default is false. When set to true, normalSuffix and slowSuffix values are appended to tags
126      * based on whether the tags' elapsed time &gt;= timeThreshold or not.
127      * 
128      * @return
129      */
130     boolean normalAndSlowSuffixesEnabled() default false;
131 }