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 * @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 >= timeThreshold or not.
127 *
128 * @return
129 */
130 boolean normalAndSlowSuffixesEnabled() default false;
131 }