blob: 3d7cb4954e5b66fdde6f34d48292ffcee7cdaf29 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.util;
18
19import com.android.internal.os.RuntimeInit;
Dianne Hackborn8c841092013-06-24 13:46:13 -070020import com.android.internal.util.FastPrintWriter;
Andreas Gampe8413db82015-12-14 13:54:51 -080021import com.android.internal.util.LineBreakBufferedWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022
23import java.io.PrintWriter;
24import java.io.StringWriter;
Andreas Gampe8413db82015-12-14 13:54:51 -080025import java.io.Writer;
Joe Onoratodba50c72011-05-19 13:28:50 -070026import java.net.UnknownHostException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027
28/**
29 * API for sending log output.
30 *
31 * <p>Generally, use the Log.v() Log.d() Log.i() Log.w() and Log.e()
32 * methods.
33 *
34 * <p>The order in terms of verbosity, from least to most is
35 * ERROR, WARN, INFO, DEBUG, VERBOSE. Verbose should never be compiled
36 * into an application except during development. Debug logs are compiled
37 * in but stripped at runtime. Error, warning and info logs are always kept.
38 *
39 * <p><b>Tip:</b> A good convention is to declare a <code>TAG</code> constant
40 * in your class:
41 *
42 * <pre>private static final String TAG = "MyActivity";</pre>
43 *
44 * and use that in subsequent calls to the log methods.
45 * </p>
46 *
47 * <p><b>Tip:</b> Don't forget that when you make a call like
48 * <pre>Log.v(TAG, "index=" + i);</pre>
49 * that when you're building the string to pass into Log.d, the compiler uses a
50 * StringBuilder and at least three allocations occur: the StringBuilder
51 * itself, the buffer, and the String object. Realistically, there is also
52 * another buffer allocation and copy, and even more pressure on the gc.
53 * That means that if your log message is filtered out, you might be doing
54 * significant work and incurring significant overhead.
55 */
56public final class Log {
57
58 /**
59 * Priority constant for the println method; use Log.v.
60 */
61 public static final int VERBOSE = 2;
62
63 /**
64 * Priority constant for the println method; use Log.d.
65 */
66 public static final int DEBUG = 3;
67
68 /**
69 * Priority constant for the println method; use Log.i.
70 */
71 public static final int INFO = 4;
72
73 /**
74 * Priority constant for the println method; use Log.w.
75 */
76 public static final int WARN = 5;
77
78 /**
79 * Priority constant for the println method; use Log.e.
80 */
81 public static final int ERROR = 6;
82
83 /**
84 * Priority constant for the println method.
85 */
86 public static final int ASSERT = 7;
87
Dan Egnor60d87622009-12-16 16:32:58 -080088 /**
Dianne Hackborn164371f2013-10-01 19:10:13 -070089 * Exception class used to capture a stack trace in {@link #wtf}.
Dan Egnor60d87622009-12-16 16:32:58 -080090 */
91 private static class TerribleFailure extends Exception {
92 TerribleFailure(String msg, Throwable cause) { super(msg, cause); }
93 }
94
Brad Fitzpatrick44dc76a2010-06-02 15:12:05 -070095 /**
Dianne Hackborn164371f2013-10-01 19:10:13 -070096 * Interface to handle terrible failures from {@link #wtf}.
Brad Fitzpatrick44dc76a2010-06-02 15:12:05 -070097 *
98 * @hide
99 */
100 public interface TerribleFailureHandler {
Dianne Hackborn52322712014-08-26 22:47:26 -0700101 void onTerribleFailure(String tag, TerribleFailure what, boolean system);
Brad Fitzpatrick44dc76a2010-06-02 15:12:05 -0700102 }
103
104 private static TerribleFailureHandler sWtfHandler = new TerribleFailureHandler() {
Dianne Hackborn52322712014-08-26 22:47:26 -0700105 public void onTerribleFailure(String tag, TerribleFailure what, boolean system) {
106 RuntimeInit.wtf(tag, what, system);
Brad Fitzpatrick44dc76a2010-06-02 15:12:05 -0700107 }
108 };
109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 private Log() {
111 }
112
113 /**
114 * Send a {@link #VERBOSE} log message.
115 * @param tag Used to identify the source of a log message. It usually identifies
116 * the class or activity where the log call occurs.
117 * @param msg The message you would like logged.
118 */
119 public static int v(String tag, String msg) {
Joe Onorato00bb9382010-02-26 18:07:01 -0800120 return println_native(LOG_ID_MAIN, VERBOSE, tag, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 }
122
123 /**
124 * Send a {@link #VERBOSE} log message and log the exception.
125 * @param tag Used to identify the source of a log message. It usually identifies
126 * the class or activity where the log call occurs.
127 * @param msg The message you would like logged.
128 * @param tr An exception to log
129 */
130 public static int v(String tag, String msg, Throwable tr) {
Andreas Gampe8413db82015-12-14 13:54:51 -0800131 return printlns(LOG_ID_MAIN, VERBOSE, tag, msg, tr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 }
133
134 /**
135 * Send a {@link #DEBUG} log message.
136 * @param tag Used to identify the source of a log message. It usually identifies
137 * the class or activity where the log call occurs.
138 * @param msg The message you would like logged.
139 */
140 public static int d(String tag, String msg) {
Joe Onorato00bb9382010-02-26 18:07:01 -0800141 return println_native(LOG_ID_MAIN, DEBUG, tag, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 }
143
144 /**
145 * Send a {@link #DEBUG} log message and log the exception.
146 * @param tag Used to identify the source of a log message. It usually identifies
147 * the class or activity where the log call occurs.
148 * @param msg The message you would like logged.
149 * @param tr An exception to log
150 */
151 public static int d(String tag, String msg, Throwable tr) {
Andreas Gampe8413db82015-12-14 13:54:51 -0800152 return printlns(LOG_ID_MAIN, DEBUG, tag, msg, tr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 }
154
155 /**
156 * Send an {@link #INFO} log message.
157 * @param tag Used to identify the source of a log message. It usually identifies
158 * the class or activity where the log call occurs.
159 * @param msg The message you would like logged.
160 */
161 public static int i(String tag, String msg) {
Joe Onorato00bb9382010-02-26 18:07:01 -0800162 return println_native(LOG_ID_MAIN, INFO, tag, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 }
164
165 /**
166 * Send a {@link #INFO} log message and log the exception.
167 * @param tag Used to identify the source of a log message. It usually identifies
168 * the class or activity where the log call occurs.
169 * @param msg The message you would like logged.
170 * @param tr An exception to log
171 */
172 public static int i(String tag, String msg, Throwable tr) {
Andreas Gampe8413db82015-12-14 13:54:51 -0800173 return printlns(LOG_ID_MAIN, INFO, tag, msg, tr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 }
175
176 /**
177 * Send a {@link #WARN} log message.
178 * @param tag Used to identify the source of a log message. It usually identifies
179 * the class or activity where the log call occurs.
180 * @param msg The message you would like logged.
181 */
182 public static int w(String tag, String msg) {
Joe Onorato00bb9382010-02-26 18:07:01 -0800183 return println_native(LOG_ID_MAIN, WARN, tag, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 }
185
186 /**
187 * Send a {@link #WARN} log message and log the exception.
188 * @param tag Used to identify the source of a log message. It usually identifies
189 * the class or activity where the log call occurs.
190 * @param msg The message you would like logged.
191 * @param tr An exception to log
192 */
193 public static int w(String tag, String msg, Throwable tr) {
Andreas Gampe8413db82015-12-14 13:54:51 -0800194 return printlns(LOG_ID_MAIN, WARN, tag, msg, tr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195 }
196
197 /**
198 * Checks to see whether or not a log for the specified tag is loggable at the specified level.
Dan Egnor60d87622009-12-16 16:32:58 -0800199 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 * The default level of any tag is set to INFO. This means that any level above and including
201 * INFO will be logged. Before you make any calls to a logging method you should check to see
202 * if your tag should be logged. You can change the default level by setting a system property:
203 * 'setprop log.tag.&lt;YOUR_LOG_TAG> &lt;LEVEL>'
Dan Egnor60d87622009-12-16 16:32:58 -0800204 * Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or SUPPRESS. SUPPRESS will
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 * turn off all logging for your tag. You can also create a local.prop file that with the
206 * following in it:
207 * 'log.tag.&lt;YOUR_LOG_TAG>=&lt;LEVEL>'
208 * and place that in /data/local.prop.
Dan Egnor60d87622009-12-16 16:32:58 -0800209 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 * @param tag The tag to check.
211 * @param level The level to check.
212 * @return Whether or not that this is allowed to be logged.
213 * @throws IllegalArgumentException is thrown if the tag.length() > 23.
214 */
215 public static native boolean isLoggable(String tag, int level);
Dan Egnor60d87622009-12-16 16:32:58 -0800216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 /*
218 * Send a {@link #WARN} log message and log the exception.
219 * @param tag Used to identify the source of a log message. It usually identifies
220 * the class or activity where the log call occurs.
221 * @param tr An exception to log
222 */
223 public static int w(String tag, Throwable tr) {
Andreas Gampe8413db82015-12-14 13:54:51 -0800224 return printlns(LOG_ID_MAIN, WARN, tag, "", tr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 }
226
227 /**
228 * Send an {@link #ERROR} log message.
229 * @param tag Used to identify the source of a log message. It usually identifies
230 * the class or activity where the log call occurs.
231 * @param msg The message you would like logged.
232 */
233 public static int e(String tag, String msg) {
Joe Onorato00bb9382010-02-26 18:07:01 -0800234 return println_native(LOG_ID_MAIN, ERROR, tag, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 }
236
237 /**
238 * Send a {@link #ERROR} log message and log the exception.
239 * @param tag Used to identify the source of a log message. It usually identifies
240 * the class or activity where the log call occurs.
241 * @param msg The message you would like logged.
242 * @param tr An exception to log
243 */
244 public static int e(String tag, String msg, Throwable tr) {
Andreas Gampe8413db82015-12-14 13:54:51 -0800245 return printlns(LOG_ID_MAIN, ERROR, tag, msg, tr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 }
247
248 /**
Dan Egnor60d87622009-12-16 16:32:58 -0800249 * What a Terrible Failure: Report a condition that should never happen.
250 * The error will always be logged at level ASSERT with the call stack.
251 * Depending on system configuration, a report may be added to the
252 * {@link android.os.DropBoxManager} and/or the process may be terminated
253 * immediately with an error dialog.
254 * @param tag Used to identify the source of a log message.
255 * @param msg The message you would like logged.
Dan Egnor60d87622009-12-16 16:32:58 -0800256 */
257 public static int wtf(String tag, String msg) {
Dianne Hackborn52322712014-08-26 22:47:26 -0700258 return wtf(LOG_ID_MAIN, tag, msg, null, false, false);
Dan Egnor60d87622009-12-16 16:32:58 -0800259 }
260
261 /**
Dianne Hackborn164371f2013-10-01 19:10:13 -0700262 * Like {@link #wtf(String, String)}, but also writes to the log the full
263 * call stack.
264 * @hide
265 */
266 public static int wtfStack(String tag, String msg) {
Dianne Hackborn52322712014-08-26 22:47:26 -0700267 return wtf(LOG_ID_MAIN, tag, msg, null, true, false);
Dianne Hackborn164371f2013-10-01 19:10:13 -0700268 }
269
270 /**
Dan Egnor60d87622009-12-16 16:32:58 -0800271 * What a Terrible Failure: Report an exception that should never happen.
272 * Similar to {@link #wtf(String, String)}, with an exception to log.
273 * @param tag Used to identify the source of a log message.
274 * @param tr An exception to log.
Dan Egnor60d87622009-12-16 16:32:58 -0800275 */
276 public static int wtf(String tag, Throwable tr) {
Dianne Hackborn52322712014-08-26 22:47:26 -0700277 return wtf(LOG_ID_MAIN, tag, tr.getMessage(), tr, false, false);
Dan Egnor60d87622009-12-16 16:32:58 -0800278 }
279
280 /**
281 * What a Terrible Failure: Report an exception that should never happen.
282 * Similar to {@link #wtf(String, Throwable)}, with a message as well.
283 * @param tag Used to identify the source of a log message.
284 * @param msg The message you would like logged.
285 * @param tr An exception to log. May be null.
Dan Egnor60d87622009-12-16 16:32:58 -0800286 */
287 public static int wtf(String tag, String msg, Throwable tr) {
Dianne Hackborn52322712014-08-26 22:47:26 -0700288 return wtf(LOG_ID_MAIN, tag, msg, tr, false, false);
Dianne Hackborn164371f2013-10-01 19:10:13 -0700289 }
290
Dianne Hackborn52322712014-08-26 22:47:26 -0700291 static int wtf(int logId, String tag, String msg, Throwable tr, boolean localStack,
292 boolean system) {
Brad Fitzpatrick44dc76a2010-06-02 15:12:05 -0700293 TerribleFailure what = new TerribleFailure(msg, tr);
Christopher Ferris2d073ba2015-06-09 10:51:43 -0700294 // Only mark this as ERROR, do not use ASSERT since that should be
295 // reserved for cases where the system is guaranteed to abort.
296 // The onTerribleFailure call does not always cause a crash.
Andreas Gampe8413db82015-12-14 13:54:51 -0800297 int bytes = printlns(logId, ERROR, tag, msg, localStack ? what : tr);
Dianne Hackborn52322712014-08-26 22:47:26 -0700298 sWtfHandler.onTerribleFailure(tag, what, system);
Dan Egnor60d87622009-12-16 16:32:58 -0800299 return bytes;
300 }
301
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800302 static void wtfQuiet(int logId, String tag, String msg, boolean system) {
303 TerribleFailure what = new TerribleFailure(msg, null);
304 sWtfHandler.onTerribleFailure(tag, what, system);
305 }
306
Dan Egnor60d87622009-12-16 16:32:58 -0800307 /**
Brad Fitzpatrick44dc76a2010-06-02 15:12:05 -0700308 * Sets the terrible failure handler, for testing.
309 *
310 * @return the old handler
311 *
312 * @hide
313 */
314 public static TerribleFailureHandler setWtfHandler(TerribleFailureHandler handler) {
315 if (handler == null) {
316 throw new NullPointerException("handler == null");
317 }
318 TerribleFailureHandler oldHandler = sWtfHandler;
319 sWtfHandler = handler;
320 return oldHandler;
321 }
322
323 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 * Handy function to get a loggable stack trace from a Throwable
325 * @param tr An exception to log
326 */
327 public static String getStackTraceString(Throwable tr) {
328 if (tr == null) {
329 return "";
330 }
Joe Onoratodba50c72011-05-19 13:28:50 -0700331
332 // This is to reduce the amount of log spew that apps do in the non-error
333 // condition of the network being unavailable.
334 Throwable t = tr;
335 while (t != null) {
336 if (t instanceof UnknownHostException) {
337 return "";
338 }
339 t = t.getCause();
340 }
341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -0700343 PrintWriter pw = new FastPrintWriter(sw, false, 256);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 tr.printStackTrace(pw);
Dianne Hackborn8c841092013-06-24 13:46:13 -0700345 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 return sw.toString();
347 }
348
349 /**
350 * Low-level logging call.
351 * @param priority The priority/type of this log message
352 * @param tag Used to identify the source of a log message. It usually identifies
353 * the class or activity where the log call occurs.
354 * @param msg The message you would like logged.
355 * @return The number of bytes written.
356 */
Joe Onorato00bb9382010-02-26 18:07:01 -0800357 public static int println(int priority, String tag, String msg) {
358 return println_native(LOG_ID_MAIN, priority, tag, msg);
359 }
360
Joe Onorato8a9b2202010-02-26 18:56:32 -0800361 /** @hide */ public static final int LOG_ID_MAIN = 0;
362 /** @hide */ public static final int LOG_ID_RADIO = 1;
363 /** @hide */ public static final int LOG_ID_EVENTS = 2;
364 /** @hide */ public static final int LOG_ID_SYSTEM = 3;
Mark Salyzyn69eb6f52014-04-09 07:39:15 -0700365 /** @hide */ public static final int LOG_ID_CRASH = 4;
Joe Onorato00bb9382010-02-26 18:07:01 -0800366
Joe Onorato8a9b2202010-02-26 18:56:32 -0800367 /** @hide */ public static native int println_native(int bufID,
368 int priority, String tag, String msg);
Andreas Gampe8413db82015-12-14 13:54:51 -0800369
370 /**
371 * Return the maximum payload the log daemon accepts without truncation.
372 * @return LOGGER_ENTRY_MAX_PAYLOAD.
373 */
374 private static native int logger_entry_max_payload_native();
375
376 /**
377 * Helper function for long messages. Uses the LineBreakBufferedWriter to break
378 * up long messages and stacktraces along newlines, but tries to write in large
379 * chunks. This is to avoid truncation.
Andreas Gamped888beb2016-02-18 14:01:41 -0800380 * @hide
Andreas Gampe8413db82015-12-14 13:54:51 -0800381 */
Andreas Gamped888beb2016-02-18 14:01:41 -0800382 public static int printlns(int bufID, int priority, String tag, String msg,
Andreas Gampe8413db82015-12-14 13:54:51 -0800383 Throwable tr) {
384 ImmediateLogWriter logWriter = new ImmediateLogWriter(bufID, priority, tag);
385 // Acceptable buffer size. Get the native buffer size, subtract two zero terminators,
386 // and the length of the tag.
387 // Note: we implicitly accept possible truncation for Modified-UTF8 differences. It
388 // is too expensive to compute that ahead of time.
389 int bufferSize = NoPreloadHolder.LOGGER_ENTRY_MAX_PAYLOAD // Base.
390 - 2 // Two terminators.
391 - (tag != null ? tag.length() : 0) // Tag length.
392 - 32; // Some slack.
393 // At least assume you can print *some* characters (tag is not too large).
394 bufferSize = Math.max(bufferSize, 100);
395
396 LineBreakBufferedWriter lbbw = new LineBreakBufferedWriter(logWriter, bufferSize);
397
398 lbbw.println(msg);
399
400 if (tr != null) {
401 // This is to reduce the amount of log spew that apps do in the non-error
402 // condition of the network being unavailable.
403 Throwable t = tr;
404 while (t != null) {
405 if (t instanceof UnknownHostException) {
406 break;
407 }
408 t = t.getCause();
409 }
410 if (t == null) {
411 tr.printStackTrace(lbbw);
412 }
413 }
414
415 lbbw.flush();
416
417 return logWriter.getWritten();
418 }
419
420 /**
421 * NoPreloadHelper class. Caches the LOGGER_ENTRY_MAX_PAYLOAD value to avoid
422 * a JNI call during logging.
423 */
424 static class NoPreloadHolder {
425 public final static int LOGGER_ENTRY_MAX_PAYLOAD =
426 logger_entry_max_payload_native();
427 }
428
429 /**
430 * Helper class to write to the logcat. Different from LogWriter, this writes
431 * the whole given buffer and does not break along newlines.
432 */
433 private static class ImmediateLogWriter extends Writer {
434
435 private int bufID;
436 private int priority;
437 private String tag;
438
439 private int written = 0;
440
441 /**
442 * Create a writer that immediately writes to the log, using the given
443 * parameters.
444 */
445 public ImmediateLogWriter(int bufID, int priority, String tag) {
446 this.bufID = bufID;
447 this.priority = priority;
448 this.tag = tag;
449 }
450
451 public int getWritten() {
452 return written;
453 }
454
455 @Override
456 public void write(char[] cbuf, int off, int len) {
457 // Note: using String here has a bit of overhead as a Java object is created,
458 // but using the char[] directly is not easier, as it needs to be translated
459 // to a C char[] for logging.
460 written += println_native(bufID, priority, tag, new String(cbuf, off, len));
461 }
462
463 @Override
464 public void flush() {
465 // Ignored.
466 }
467
468 @Override
469 public void close() {
470 // Ignored.
471 }
472 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473}