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