OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 package org.chromium.base; | |
6 | |
7 import org.chromium.base.annotations.NoSideEffects; | |
8 | |
9 import java.util.Locale; | |
10 | |
11 /** | |
12 * Utility class for Logging. | |
13 * | |
14 * <p> | |
15 * Defines logging access points for each feature. They format and forward the l ogs to | |
16 * {@link android.util.Log}, allowing to standardize the output, to make it easy to identify | |
17 * the origin of logs, and enable or disable logging in different parts of the c ode. | |
18 * </p> | |
19 * <p> | |
20 * Please make use of the formatting capability of the logging methods rather th an doing | |
21 * concatenations in the calling code. In the release builds of Chrome, debug an d verbose log | |
22 * calls will be stripped out of the binary. Concatenations and method calls how ever will still | |
23 * remain and be executed. If they can't be avoided, use {@link Log#isEnabled(in t)} to guard | |
24 * such calls. Another possibility is to annotate methods to be called with {@li nk NoSideEffects}. | |
25 * </p> | |
26 * | |
27 * Usage: | |
28 * <pre> | |
29 * Log.FEATURE.d("MyTag", "My %s message", awesome); | |
30 * </pre> | |
31 * | |
32 * Logcat output: | |
33 * <pre> | |
34 * D/chromium.Feature (999): [MyTag] My awesome message | |
35 * </pre> | |
36 * | |
37 * Set the log level for a given feature: | |
38 * <pre> | |
39 * adb shell setprop log.tag.chromium:Feature VERBOSE | |
40 * </pre> | |
41 * | |
42 *<p> | |
43 *<b>Notes:</b> | |
44 * <ul> | |
45 * <li>For loggers configured to log the origin of debug calls (see {@link #Log( String, boolean)}, | |
46 * the tag provided for debug and verbose calls will be ignored and replaced in the log with | |
47 * the file name and the line number.</li> | |
48 * <li>New features or features not having a dedicated logger: please make a new one rather | |
49 * than using {@link #ROOT}.</li> | |
50 * </ul> | |
51 * </p> | |
52 */ | |
53 public class Log { | |
54 /** | |
55 * Logger for the "chromium" tag. | |
56 * Note: Disabling logging for that one will not disable the others. | |
57 */ | |
58 public static final Log ROOT = new Log(null, true); | |
59 | |
60 private static final String BASE_TAG = "chromium"; | |
61 | |
62 /** | |
63 * Maximum length for the feature tag. | |
64 * | |
65 * A complete tag will look like <code>chromium:FooFeature</code>. Because o f the 23 characters | |
66 * limit on log tags, feature tags have to be restricted to fit. | |
67 */ | |
68 private static final int MAX_FEATURE_TAG_LENGTH = 23 - 1 - BASE_TAG.length() ; | |
69 | |
70 @VisibleForTesting | |
71 final String mTag; | |
72 private final boolean mDebugWithStack; | |
73 | |
74 /** | |
75 * Creates a new logging access point for the given tag. | |
76 * @param featureTag The complete log tag will be displayed as "chromium.fea tureTag". | |
77 * If <code>null</code>, it will only be "chromium". | |
78 * @param debugWithStack Whether to replace the secondary tag name with the file name and line | |
79 * number of the origin of the call for debug and verb ose logs. | |
80 * @throws IllegalArgumentException If <code>featureTag</code> is too long. The complete | |
81 * tag has to fit within 23 characters. | |
82 */ | |
83 protected Log(String featureTag, boolean debugWithStack) { | |
84 mDebugWithStack = debugWithStack; | |
85 if (featureTag == null) { | |
86 mTag = BASE_TAG; | |
87 return; | |
88 } else if (featureTag.length() > MAX_FEATURE_TAG_LENGTH) { | |
89 throw new IllegalArgumentException( | |
90 "The feature tag can be at most " + MAX_FEATURE_TAG_LENGTH + " characters."); | |
91 } else { | |
92 mTag = BASE_TAG + "." + featureTag; | |
93 } | |
94 } | |
95 | |
96 /** Returns whether this logger is currently allowed to send logs.*/ | |
97 public boolean isEnabled(int level) { | |
98 return android.util.Log.isLoggable(mTag, level); | |
99 } | |
100 | |
101 /** Returns a formatted log message, using the supplied format and arguments .*/ | |
102 @VisibleForTesting | |
103 protected String formatLog(String secondaryTag, String messageTemplate, Obje ct... params) { | |
104 if (params != null && params.length != 0) { | |
105 messageTemplate = String.format(Locale.US, messageTemplate, params); | |
106 } | |
107 | |
108 return "[" + secondaryTag + "] " + messageTemplate; | |
109 } | |
110 | |
111 /** | |
112 * Sends a {@link android.util.Log#VERBOSE} log message. | |
113 * | |
114 * For optimization purposes, only the fixed parameters versions are visible . If you need more | |
115 * than 7 parameters, consider building your log message using a function an notated with | |
116 * {@link NoSideEffects}. | |
117 * | |
118 * @param secondaryTag Used to identify the source of a log message. It usua lly identifies the | |
119 * class where the log call occurs. If the logger is con figured to log the | |
120 * call's origin (see {@link #Log(String, boolean)}, thi s parameter is | |
121 * unused and will be replaced in the log message with t he file name and | |
122 * the line number. | |
123 * @param messageTemplate The message you would like logged. It is to be spe cified as a format | |
124 * string. | |
125 * @param args Arguments referenced by the format specifiers in the format s tring. | |
126 */ | |
127 private void verbose(String secondaryTag, String messageTemplate, Object... args) { | |
128 if (isEnabled(android.util.Log.VERBOSE)) { | |
129 if (mDebugWithStack) secondaryTag = getCallOrigin(); | |
130 android.util.Log.v(mTag, formatLog(secondaryTag, messageTemplate, ar gs)); | |
131 } | |
132 } | |
133 | |
134 /** Sends a {@link android.util.Log#VERBOSE} log message. 0 arg version. */ | |
135 public void v(String secondaryTag, String message) { | |
136 verbose(secondaryTag, message); | |
137 } | |
138 | |
139 /** Sends a {@link android.util.Log#VERBOSE} log message. 1 arg version. */ | |
140 public void v(String secondaryTag, String messageTemplate, Object arg1) { | |
141 verbose(secondaryTag, messageTemplate, arg1); | |
142 } | |
143 | |
144 /** Sends a {@link android.util.Log#VERBOSE} log message. 2 args version */ | |
145 public void v(String secondaryTag, String messageTemplate, Object arg1, Obje ct arg2) { | |
146 verbose(secondaryTag, messageTemplate, arg1, arg2); | |
147 } | |
148 | |
149 /** Sends a {@link android.util.Log#VERBOSE} log message. 3 args version */ | |
150 public void v( | |
151 String secondaryTag, String messageTemplate, Object arg1, Object arg 2, Object arg3) { | |
152 verbose(secondaryTag, messageTemplate, arg1, arg2, arg3); | |
153 } | |
154 | |
155 /** Sends a {@link android.util.Log#VERBOSE} log message. 4 args version */ | |
156 public void v(String secondaryTag, String messageTemplate, Object arg1, Obje ct arg2, | |
157 Object arg3, Object arg4) { | |
158 verbose(secondaryTag, messageTemplate, arg1, arg2, arg3, arg4); | |
159 } | |
160 | |
161 /** Sends a {@link android.util.Log#VERBOSE} log message. 5 args version */ | |
162 public void v(String secondaryTag, String messageTemplate, Object arg1, Obje ct arg2, | |
163 Object arg3, Object arg4, Object arg5) { | |
164 verbose(secondaryTag, messageTemplate, arg1, arg2, arg3, arg4, arg5); | |
165 } | |
166 | |
167 /** Sends a {@link android.util.Log#VERBOSE} log message. 6 args version */ | |
168 public void v(String secondaryTag, String messageTemplate, Object arg1, Obje ct arg2, | |
169 Object arg3, Object arg4, Object arg5, Object arg6) { | |
170 verbose(secondaryTag, messageTemplate, arg1, arg2, arg3, arg4, arg5, arg 6); | |
171 } | |
172 | |
173 /** Sends a {@link android.util.Log#VERBOSE} log message. 7 args version */ | |
174 public void v(String secondaryTag, String messageTemplate, Object arg1, Obje ct arg2, | |
175 Object arg3, Object arg4, Object arg5, Object arg6, Object arg7) { | |
176 verbose(secondaryTag, messageTemplate, arg1, arg2, arg3, arg4, arg5, arg 6, arg7); | |
177 } | |
178 | |
179 /** | |
180 * Sends a {@link android.util.Log#DEBUG} log message. | |
181 * | |
182 * For optimization purposes, only the fixed parameters versions are visible . If you need more | |
183 * than 7 parameters, consider building your log message using a function an notated with | |
184 * {@link NoSideEffects}. | |
185 * | |
186 * @param secondaryTag Used to identify the source of a log message. It usua lly identifies the | |
187 * class where the log call occurs. If the logger is con figured to log the | |
188 * call's origin (see {@link #Log(String, boolean)}, thi s parameter is | |
189 * unused and will be replaced in the log message with t he file name and | |
190 * the line number. | |
191 * @param messageTemplate The message you would like logged. It is to be spe cified as a format | |
192 * string. | |
193 * @param args Arguments referenced by the format specifiers in the format s tring. | |
194 */ | |
195 private void debug(String secondaryTag, String messageTemplate, Object... ar gs) { | |
196 if (isEnabled(android.util.Log.DEBUG)) { | |
197 if (mDebugWithStack) secondaryTag = getCallOrigin(); | |
198 android.util.Log.d(mTag, formatLog(secondaryTag, messageTemplate, ar gs)); | |
199 } | |
200 } | |
201 | |
202 /** Sends a {@link android.util.Log#DEBUG} log message. 0 arg version. */ | |
203 public void d(String secondaryTag, String message) { | |
204 debug(secondaryTag, message); | |
205 } | |
206 | |
207 /** Sends a {@link android.util.Log#DEBUG} log message. 1 arg version. */ | |
208 public void d(String secondaryTag, String messageTemplate, Object arg1) { | |
209 debug(secondaryTag, messageTemplate, arg1); | |
210 } | |
211 /** Sends a {@link android.util.Log#DEBUG} log message. 2 args version */ | |
212 public void d(String secondaryTag, String messageTemplate, Object arg1, Obje ct arg2) { | |
213 debug(secondaryTag, messageTemplate, arg1, arg2); | |
214 } | |
215 /** Sends a {@link android.util.Log#DEBUG} log message. 3 args version */ | |
216 public void d( | |
217 String secondaryTag, String messageTemplate, Object arg1, Object arg 2, Object arg3) { | |
218 debug(secondaryTag, messageTemplate, arg1, arg2, arg3); | |
219 } | |
220 | |
221 /** Sends a {@link android.util.Log#DEBUG} log message. 4 args version */ | |
222 public void d(String secondaryTag, String messageTemplate, Object arg1, Obje ct arg2, | |
223 Object arg3, Object arg4) { | |
224 debug(secondaryTag, messageTemplate, arg1, arg2, arg3, arg4); | |
225 } | |
226 | |
227 /** Sends a {@link android.util.Log#DEBUG} log message. 5 args version */ | |
228 public void d(String secondaryTag, String messageTemplate, Object arg1, Obje ct arg2, | |
229 Object arg3, Object arg4, Object arg5) { | |
230 debug(secondaryTag, messageTemplate, arg1, arg2, arg3, arg4, arg5); | |
231 } | |
232 | |
233 /** Sends a {@link android.util.Log#DEBUG} log message. 6 args version */ | |
234 public void d(String secondaryTag, String messageTemplate, Object arg1, Obje ct arg2, | |
235 Object arg3, Object arg4, Object arg5, Object arg6) { | |
236 debug(secondaryTag, messageTemplate, arg1, arg2, arg3, arg4, arg5, arg6) ; | |
237 } | |
238 | |
239 /** Sends a {@link android.util.Log#DEBUG} log message. 7 args version */ | |
240 public void d(String secondaryTag, String messageTemplate, Object arg1, Obje ct arg2, | |
241 Object arg3, Object arg4, Object arg5, Object arg6, Object arg7) { | |
242 debug(secondaryTag, messageTemplate, arg1, arg2, arg3, arg4, arg5, arg6, arg7); | |
243 } | |
244 | |
245 /** | |
246 * Sends an {@link android.util.Log#INFO} log message. | |
247 * | |
248 * @param secondaryTag Used to identify the source of a log message. It usua lly identifies the | |
249 * class where the log call occurs. | |
250 * @param messageTemplate The message you would like logged. It is to be spe cified as a format | |
251 * string. | |
252 * @param args Arguments referenced by the format specifiers in the format s tring. | |
253 */ | |
254 public void info(String secondaryTag, String messageTemplate, Object... args ) { | |
255 if (isEnabled(android.util.Log.INFO)) { | |
256 android.util.Log.i(mTag, formatLog(secondaryTag, messageTemplate, ar gs)); | |
257 } | |
258 } | |
259 | |
260 /** | |
261 * Sends a {@link android.util.Log#WARN} log message. | |
262 * | |
263 * @param secondaryTag Used to identify the source of a log message. It usua lly identifies the | |
264 * class where the log call occurs. | |
265 * @param messageTemplate The message you would like logged. It is to be spe cified as a format | |
266 * string. | |
267 * @param args Arguments referenced by the format specifiers in the format s tring. | |
268 */ | |
269 public void w(String secondaryTag, String messageTemplate, Object... args) { | |
270 if (isEnabled(android.util.Log.WARN)) { | |
271 android.util.Log.w(mTag, formatLog(secondaryTag, messageTemplate, ar gs)); | |
272 } | |
273 } | |
274 | |
275 /** | |
276 * Sends an {@link android.util.Log#ERROR} log message. | |
277 * | |
278 * @param secondaryTag Used to identify the source of a log message. It usua lly identifies the | |
279 * class where the log call occurs. | |
280 * @param messageTemplate The message you would like logged. It is to be spe cified as a format | |
281 * string. | |
282 * @param args Arguments referenced by the format specifiers in the format s tring. | |
283 */ | |
284 public void e(String secondaryTag, String messageTemplate, Object... args) { | |
285 if (isEnabled(android.util.Log.ERROR)) { | |
286 android.util.Log.e(mTag, formatLog(secondaryTag, messageTemplate, ar gs)); | |
287 } | |
288 } | |
289 | |
290 /** Returns a string form of the origin of the log call, to be used as secon dary tag.*/ | |
291 private String getCallOrigin() { | |
dgn
2015/04/02 14:47:15
Following Ted's comment on the design doc, I added
| |
292 StackTraceElement[] st = Thread.currentThread().getStackTrace(); | |
293 | |
294 // The call stack should look like: | |
295 // - Something in thread | |
296 // - getStackTrace() | |
297 // - getCallOrigin() | |
298 // - privateLogFunction: verbose or debug | |
299 // - logFunction: v, d, i, etc. | |
300 // - caller | |
301 | |
302 return st[5].getFileName() + ":" + st[5].getLineNumber(); | |
Ted C
2015/04/02 16:19:55
Is the index stable between art and dalvik?
I hav
dgn
2015/04/02 16:49:04
I was just trying to test that and noticed that 5
| |
303 } | |
304 } | |
OLD | NEW |