1 /* 2 * Copyright (C) 2006 The Android Open Source Project 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 17 package android.util; 18 19 import com.android.internal.os.RuntimeInit; 20 21 import java.io.PrintWriter; 22 import java.io.StringWriter; 23 import java.net.UnknownHostException; 24 25 /** 26 * API for sending log output. 27 * 28 * <p>Generally, use the Log.v() Log.d() Log.i() Log.w() and Log.e() 29 * methods. 30 * 31 * <p>The order in terms of verbosity, from least to most is 32 * ERROR, WARN, INFO, DEBUG, VERBOSE. Verbose should never be compiled 33 * into an application except during development. Debug logs are compiled 34 * in but stripped at runtime. Error, warning and info logs are always kept. 35 * 36 * <p><b>Tip:</b> A good convention is to declare a <code>TAG</code> constant 37 * in your class: 38 * 39 * <pre>private static final String TAG = "MyActivity";</pre> 40 * 41 * and use that in subsequent calls to the log methods. 42 * </p> 43 * 44 * <p><b>Tip:</b> Don't forget that when you make a call like 45 * <pre>Log.v(TAG, "index=" + i);</pre> 46 * that when you're building the string to pass into Log.d, the compiler uses a 47 * StringBuilder and at least three allocations occur: the StringBuilder 48 * itself, the buffer, and the String object. Realistically, there is also 49 * another buffer allocation and copy, and even more pressure on the gc. 50 * That means that if your log message is filtered out, you might be doing 51 * significant work and incurring significant overhead. 52 */ 53 public final class Log { 54 55 /** 56 * Priority constant for the println method; use Log.v. 57 */ 58 public static final int VERBOSE = 2; 59 60 /** 61 * Priority constant for the println method; use Log.d. 62 */ 63 public static final int DEBUG = 3; 64 65 /** 66 * Priority constant for the println method; use Log.i. 67 */ 68 public static final int INFO = 4; 69 70 /** 71 * Priority constant for the println method; use Log.w. 72 */ 73 public static final int WARN = 5; 74 75 /** 76 * Priority constant for the println method; use Log.e. 77 */ 78 public static final int ERROR = 6; 79 80 /** 81 * Priority constant for the println method. 82 */ 83 public static final int ASSERT = 7; 84 85 /** 86 * Exception class used to capture a stack trace in {@link #wtf()}. 87 */ 88 private static class TerribleFailure extends Exception { TerribleFailure(String msg, Throwable cause)89 TerribleFailure(String msg, Throwable cause) { super(msg, cause); } 90 } 91 92 /** 93 * Interface to handle terrible failures from {@link #wtf()}. 94 * 95 * @hide 96 */ 97 public interface TerribleFailureHandler { onTerribleFailure(String tag, TerribleFailure what)98 void onTerribleFailure(String tag, TerribleFailure what); 99 } 100 101 private static TerribleFailureHandler sWtfHandler = new TerribleFailureHandler() { 102 public void onTerribleFailure(String tag, TerribleFailure what) { 103 RuntimeInit.wtf(tag, what); 104 } 105 }; 106 Log()107 private Log() { 108 } 109 110 /** 111 * Send a {@link #VERBOSE} log message. 112 * @param tag Used to identify the source of a log message. It usually identifies 113 * the class or activity where the log call occurs. 114 * @param msg The message you would like logged. 115 */ v(String tag, String msg)116 public static int v(String tag, String msg) { 117 return println_native(LOG_ID_MAIN, VERBOSE, tag, msg); 118 } 119 120 /** 121 * Send a {@link #VERBOSE} log message and log the exception. 122 * @param tag Used to identify the source of a log message. It usually identifies 123 * the class or activity where the log call occurs. 124 * @param msg The message you would like logged. 125 * @param tr An exception to log 126 */ v(String tag, String msg, Throwable tr)127 public static int v(String tag, String msg, Throwable tr) { 128 return println_native(LOG_ID_MAIN, VERBOSE, tag, msg + '\n' + getStackTraceString(tr)); 129 } 130 131 /** 132 * Send a {@link #DEBUG} log message. 133 * @param tag Used to identify the source of a log message. It usually identifies 134 * the class or activity where the log call occurs. 135 * @param msg The message you would like logged. 136 */ d(String tag, String msg)137 public static int d(String tag, String msg) { 138 return println_native(LOG_ID_MAIN, DEBUG, tag, msg); 139 } 140 141 /** 142 * Send a {@link #DEBUG} log message and log the exception. 143 * @param tag Used to identify the source of a log message. It usually identifies 144 * the class or activity where the log call occurs. 145 * @param msg The message you would like logged. 146 * @param tr An exception to log 147 */ d(String tag, String msg, Throwable tr)148 public static int d(String tag, String msg, Throwable tr) { 149 return println_native(LOG_ID_MAIN, DEBUG, tag, msg + '\n' + getStackTraceString(tr)); 150 } 151 152 /** 153 * Send an {@link #INFO} log message. 154 * @param tag Used to identify the source of a log message. It usually identifies 155 * the class or activity where the log call occurs. 156 * @param msg The message you would like logged. 157 */ i(String tag, String msg)158 public static int i(String tag, String msg) { 159 return println_native(LOG_ID_MAIN, INFO, tag, msg); 160 } 161 162 /** 163 * Send a {@link #INFO} log message and log the exception. 164 * @param tag Used to identify the source of a log message. It usually identifies 165 * the class or activity where the log call occurs. 166 * @param msg The message you would like logged. 167 * @param tr An exception to log 168 */ i(String tag, String msg, Throwable tr)169 public static int i(String tag, String msg, Throwable tr) { 170 return println_native(LOG_ID_MAIN, INFO, tag, msg + '\n' + getStackTraceString(tr)); 171 } 172 173 /** 174 * Send a {@link #WARN} log message. 175 * @param tag Used to identify the source of a log message. It usually identifies 176 * the class or activity where the log call occurs. 177 * @param msg The message you would like logged. 178 */ w(String tag, String msg)179 public static int w(String tag, String msg) { 180 return println_native(LOG_ID_MAIN, WARN, tag, msg); 181 } 182 183 /** 184 * Send a {@link #WARN} log message and log the exception. 185 * @param tag Used to identify the source of a log message. It usually identifies 186 * the class or activity where the log call occurs. 187 * @param msg The message you would like logged. 188 * @param tr An exception to log 189 */ w(String tag, String msg, Throwable tr)190 public static int w(String tag, String msg, Throwable tr) { 191 return println_native(LOG_ID_MAIN, WARN, tag, msg + '\n' + getStackTraceString(tr)); 192 } 193 194 /** 195 * Checks to see whether or not a log for the specified tag is loggable at the specified level. 196 * 197 * The default level of any tag is set to INFO. This means that any level above and including 198 * INFO will be logged. Before you make any calls to a logging method you should check to see 199 * if your tag should be logged. You can change the default level by setting a system property: 200 * 'setprop log.tag.<YOUR_LOG_TAG> <LEVEL>' 201 * Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or SUPPRESS. SUPPRESS will 202 * turn off all logging for your tag. You can also create a local.prop file that with the 203 * following in it: 204 * 'log.tag.<YOUR_LOG_TAG>=<LEVEL>' 205 * and place that in /data/local.prop. 206 * 207 * @param tag The tag to check. 208 * @param level The level to check. 209 * @return Whether or not that this is allowed to be logged. 210 * @throws IllegalArgumentException is thrown if the tag.length() > 23. 211 */ isLoggable(String tag, int level)212 public static native boolean isLoggable(String tag, int level); 213 214 /* 215 * Send a {@link #WARN} log message and log the exception. 216 * @param tag Used to identify the source of a log message. It usually identifies 217 * the class or activity where the log call occurs. 218 * @param tr An exception to log 219 */ w(String tag, Throwable tr)220 public static int w(String tag, Throwable tr) { 221 return println_native(LOG_ID_MAIN, WARN, tag, getStackTraceString(tr)); 222 } 223 224 /** 225 * Send an {@link #ERROR} log message. 226 * @param tag Used to identify the source of a log message. It usually identifies 227 * the class or activity where the log call occurs. 228 * @param msg The message you would like logged. 229 */ e(String tag, String msg)230 public static int e(String tag, String msg) { 231 return println_native(LOG_ID_MAIN, ERROR, tag, msg); 232 } 233 234 /** 235 * Send a {@link #ERROR} log message and log the exception. 236 * @param tag Used to identify the source of a log message. It usually identifies 237 * the class or activity where the log call occurs. 238 * @param msg The message you would like logged. 239 * @param tr An exception to log 240 */ e(String tag, String msg, Throwable tr)241 public static int e(String tag, String msg, Throwable tr) { 242 return println_native(LOG_ID_MAIN, ERROR, tag, msg + '\n' + getStackTraceString(tr)); 243 } 244 245 /** 246 * What a Terrible Failure: Report a condition that should never happen. 247 * The error will always be logged at level ASSERT with the call stack. 248 * Depending on system configuration, a report may be added to the 249 * {@link android.os.DropBoxManager} and/or the process may be terminated 250 * immediately with an error dialog. 251 * @param tag Used to identify the source of a log message. 252 * @param msg The message you would like logged. 253 */ wtf(String tag, String msg)254 public static int wtf(String tag, String msg) { 255 return wtf(tag, msg, null); 256 } 257 258 /** 259 * What a Terrible Failure: Report an exception that should never happen. 260 * Similar to {@link #wtf(String, String)}, with an exception to log. 261 * @param tag Used to identify the source of a log message. 262 * @param tr An exception to log. 263 */ wtf(String tag, Throwable tr)264 public static int wtf(String tag, Throwable tr) { 265 return wtf(tag, tr.getMessage(), tr); 266 } 267 268 /** 269 * What a Terrible Failure: Report an exception that should never happen. 270 * Similar to {@link #wtf(String, Throwable)}, with a message as well. 271 * @param tag Used to identify the source of a log message. 272 * @param msg The message you would like logged. 273 * @param tr An exception to log. May be null. 274 */ wtf(String tag, String msg, Throwable tr)275 public static int wtf(String tag, String msg, Throwable tr) { 276 TerribleFailure what = new TerribleFailure(msg, tr); 277 int bytes = println_native(LOG_ID_MAIN, ASSERT, tag, msg + '\n' + getStackTraceString(tr)); 278 sWtfHandler.onTerribleFailure(tag, what); 279 return bytes; 280 } 281 282 /** 283 * Sets the terrible failure handler, for testing. 284 * 285 * @return the old handler 286 * 287 * @hide 288 */ setWtfHandler(TerribleFailureHandler handler)289 public static TerribleFailureHandler setWtfHandler(TerribleFailureHandler handler) { 290 if (handler == null) { 291 throw new NullPointerException("handler == null"); 292 } 293 TerribleFailureHandler oldHandler = sWtfHandler; 294 sWtfHandler = handler; 295 return oldHandler; 296 } 297 298 /** 299 * Handy function to get a loggable stack trace from a Throwable 300 * @param tr An exception to log 301 */ getStackTraceString(Throwable tr)302 public static String getStackTraceString(Throwable tr) { 303 if (tr == null) { 304 return ""; 305 } 306 307 // This is to reduce the amount of log spew that apps do in the non-error 308 // condition of the network being unavailable. 309 Throwable t = tr; 310 while (t != null) { 311 if (t instanceof UnknownHostException) { 312 return ""; 313 } 314 t = t.getCause(); 315 } 316 317 StringWriter sw = new StringWriter(); 318 PrintWriter pw = new PrintWriter(sw); 319 tr.printStackTrace(pw); 320 return sw.toString(); 321 } 322 323 /** 324 * Low-level logging call. 325 * @param priority The priority/type of this log message 326 * @param tag Used to identify the source of a log message. It usually identifies 327 * the class or activity where the log call occurs. 328 * @param msg The message you would like logged. 329 * @return The number of bytes written. 330 */ println(int priority, String tag, String msg)331 public static int println(int priority, String tag, String msg) { 332 return println_native(LOG_ID_MAIN, priority, tag, msg); 333 } 334 335 /** @hide */ public static final int LOG_ID_MAIN = 0; 336 /** @hide */ public static final int LOG_ID_RADIO = 1; 337 /** @hide */ public static final int LOG_ID_EVENTS = 2; 338 /** @hide */ public static final int LOG_ID_SYSTEM = 3; 339 println_native(int bufID, int priority, String tag, String msg)340 /** @hide */ public static native int println_native(int bufID, 341 int priority, String tag, String msg); 342 } 343