AndroidHandler.java revision 886f3d69b79748fe937725e33b8bbb3d67ab82c7
1/* 2 * Copyright (C) 2008 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 com.android.internal.logging; 18 19import android.util.Log; 20 21import java.util.logging.*; 22import java.util.Date; 23import java.text.MessageFormat; 24import java.io.PrintWriter; 25import java.io.StringWriter; 26 27/** 28 * Implements a {@link java.util.logging.Logger} handler that writes to the Android log. The 29 * implementation is rather straightforward. The name of the logger serves as 30 * the log tag. Only the log levels need to be converted appropriately. For 31 * this purpose, the following mapping is being used: 32 * 33 * <table> 34 * <tr> 35 * <th>logger level</th> 36 * <th>Android level</th> 37 * </tr> 38 * <tr> 39 * <td> 40 * SEVERE 41 * </td> 42 * <td> 43 * ERROR 44 * </td> 45 * </tr> 46 * <tr> 47 * <td> 48 * WARNING 49 * </td> 50 * <td> 51 * WARN 52 * </td> 53 * </tr> 54 * <tr> 55 * <td> 56 * INFO 57 * </td> 58 * <td> 59 * INFO 60 * </td> 61 * </tr> 62 * <tr> 63 * <td> 64 * CONFIG 65 * </td> 66 * <td> 67 * DEBUG 68 * </td> 69 * </tr> 70 * <tr> 71 * <td> 72 * FINE, FINER, FINEST 73 * </td> 74 * <td> 75 * VERBOSE 76 * </td> 77 * </tr> 78 * </table> 79 */ 80public class AndroidHandler extends Handler { 81 /** 82 * Holds the formatter for all Android log handlers. 83 */ 84 private static final Formatter THE_FORMATTER = new Formatter() { 85 @Override 86 public String format(LogRecord r) { 87 Throwable thrown = r.getThrown(); 88 if (thrown != null) { 89 StringWriter sw = new StringWriter(); 90 PrintWriter pw = new PrintWriter(sw); 91 sw.write(r.getMessage()); 92 sw.write("\n"); 93 thrown.printStackTrace(pw); 94 pw.flush(); 95 return sw.toString(); 96 } else { 97 return r.getMessage(); 98 } 99 } 100 }; 101 102 /** 103 * Constructs a new instance of the Android log handler. 104 */ 105 public AndroidHandler() { 106 setFormatter(THE_FORMATTER); 107 } 108 109 @Override 110 public void close() { 111 // No need to close, but must implement abstract method. 112 } 113 114 @Override 115 public void flush() { 116 // No need to flush, but must implement abstract method. 117 } 118 119 @Override 120 public void publish(LogRecord record) { 121 try { 122 int level = getAndroidLevel(record.getLevel()); 123 String tag = record.getLoggerName(); 124 125 if (tag == null) { 126 // Anonymous logger. 127 tag = "null"; 128 } else { 129 // Tags must be <= 23 characters. 130 int length = tag.length(); 131 if (length > 23) { 132 // Most loggers use the full class name. Try dropping the 133 // package. 134 int lastPeriod = tag.lastIndexOf("."); 135 if (length - lastPeriod - 1 <= 23) { 136 tag = tag.substring(lastPeriod + 1); 137 } else { 138 // Use last 23 chars. 139 tag = tag.substring(tag.length() - 23); 140 } 141 } 142 } 143 144 if (!Log.isLoggable(tag, level)) { 145 return; 146 } 147 148 String message = getFormatter().format(record); 149 Log.println(level, tag, message); 150 } catch (RuntimeException e) { 151 Log.e("AndroidHandler", "Error logging message.", e); 152 } 153 } 154 155 /** 156 * Converts a {@link java.util.logging.Logger} logging level into an Android one. 157 * 158 * @param level The {@link java.util.logging.Logger} logging level. 159 * 160 * @return The resulting Android logging level. 161 */ 162 static int getAndroidLevel(Level level) { 163 int value = level.intValue(); 164 if (value >= 1000) { // SEVERE 165 return Log.ERROR; 166 } else if (value >= 900) { // WARNING 167 return Log.WARN; 168 } else if (value >= 800) { // INFO 169 return Log.INFO; 170 } else { 171 return Log.DEBUG; 172 } 173 } 174 175} 176