Chromium Code Reviews| 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 |