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