1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/base/background/common/log/Logger.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,232 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +package org.mozilla.gecko.background.common.log; 1.9 + 1.10 +import java.io.PrintWriter; 1.11 +import java.util.Iterator; 1.12 +import java.util.LinkedHashSet; 1.13 +import java.util.Set; 1.14 + 1.15 +import org.mozilla.gecko.background.common.GlobalConstants; 1.16 +import org.mozilla.gecko.background.common.log.writers.AndroidLevelCachingLogWriter; 1.17 +import org.mozilla.gecko.background.common.log.writers.AndroidLogWriter; 1.18 +import org.mozilla.gecko.background.common.log.writers.LogWriter; 1.19 +import org.mozilla.gecko.background.common.log.writers.PrintLogWriter; 1.20 +import org.mozilla.gecko.background.common.log.writers.SimpleTagLogWriter; 1.21 +import org.mozilla.gecko.background.common.log.writers.ThreadLocalTagLogWriter; 1.22 + 1.23 +import android.util.Log; 1.24 + 1.25 +/** 1.26 + * Logging helper class. Serializes all log operations (by synchronizing). 1.27 + */ 1.28 +public class Logger { 1.29 + public static final String LOGGER_TAG = "Logger"; 1.30 + public static final String DEFAULT_LOG_TAG = "GeckoLogger"; 1.31 + 1.32 + // For extra debugging. 1.33 + public static boolean LOG_PERSONAL_INFORMATION = false; 1.34 + 1.35 + /** 1.36 + * Allow each thread to use its own global log tag. This allows 1.37 + * independent services to log as different sources. 1.38 + * 1.39 + * When your thread sets up logging, it should do something like the following: 1.40 + * 1.41 + * Logger.setThreadLogTag("MyTag"); 1.42 + * 1.43 + * The value is inheritable, so worker threads and such do not need to 1.44 + * set the same log tag as their parent. 1.45 + */ 1.46 + private static final InheritableThreadLocal<String> logTag = new InheritableThreadLocal<String>() { 1.47 + @Override 1.48 + protected String initialValue() { 1.49 + return DEFAULT_LOG_TAG; 1.50 + } 1.51 + }; 1.52 + 1.53 + public static void setThreadLogTag(final String logTag) { 1.54 + Logger.logTag.set(logTag); 1.55 + } 1.56 + public static String getThreadLogTag() { 1.57 + return Logger.logTag.get(); 1.58 + } 1.59 + 1.60 + /** 1.61 + * Current set of writers to which we will log. 1.62 + * <p> 1.63 + * We want logging to be available while running tests, so we initialize 1.64 + * this set statically. 1.65 + */ 1.66 + protected final static Set<LogWriter> logWriters; 1.67 + static { 1.68 + final Set<LogWriter> defaultWriters = Logger.defaultLogWriters(); 1.69 + logWriters = new LinkedHashSet<LogWriter>(defaultWriters); 1.70 + } 1.71 + 1.72 + /** 1.73 + * Default set of log writers to log to. 1.74 + */ 1.75 + public final static Set<LogWriter> defaultLogWriters() { 1.76 + final String processedPackage = GlobalConstants.BROWSER_INTENT_PACKAGE.replace("org.mozilla.", ""); 1.77 + 1.78 + final Set<LogWriter> defaultLogWriters = new LinkedHashSet<LogWriter>(); 1.79 + 1.80 + final LogWriter log = new AndroidLogWriter(); 1.81 + final LogWriter cache = new AndroidLevelCachingLogWriter(log); 1.82 + 1.83 + final LogWriter single = new SimpleTagLogWriter(processedPackage, new ThreadLocalTagLogWriter(Logger.logTag, cache)); 1.84 + 1.85 + defaultLogWriters.add(single); 1.86 + return defaultLogWriters; 1.87 + } 1.88 + 1.89 + public static synchronized void startLoggingTo(LogWriter logWriter) { 1.90 + logWriters.add(logWriter); 1.91 + } 1.92 + 1.93 + public static synchronized void startLoggingToWriters(Set<LogWriter> writers) { 1.94 + logWriters.addAll(writers); 1.95 + } 1.96 + 1.97 + public static synchronized void stopLoggingTo(LogWriter logWriter) { 1.98 + try { 1.99 + logWriter.close(); 1.100 + } catch (Exception e) { 1.101 + Log.e(LOGGER_TAG, "Got exception closing and removing LogWriter " + logWriter + ".", e); 1.102 + } 1.103 + logWriters.remove(logWriter); 1.104 + } 1.105 + 1.106 + public static synchronized void stopLoggingToAll() { 1.107 + for (LogWriter logWriter : logWriters) { 1.108 + try { 1.109 + logWriter.close(); 1.110 + } catch (Exception e) { 1.111 + Log.e(LOGGER_TAG, "Got exception closing and removing LogWriter " + logWriter + ".", e); 1.112 + } 1.113 + } 1.114 + logWriters.clear(); 1.115 + } 1.116 + 1.117 + /** 1.118 + * Write to only the default log writers. 1.119 + */ 1.120 + public static synchronized void resetLogging() { 1.121 + stopLoggingToAll(); 1.122 + logWriters.addAll(Logger.defaultLogWriters()); 1.123 + } 1.124 + 1.125 + /** 1.126 + * Start writing log output to stdout. 1.127 + * <p> 1.128 + * Use <code>resetLogging</code> to stop logging to stdout. 1.129 + */ 1.130 + public static synchronized void startLoggingToConsole() { 1.131 + setThreadLogTag("Test"); 1.132 + startLoggingTo(new PrintLogWriter(new PrintWriter(System.out, true))); 1.133 + } 1.134 + 1.135 + // Synchronized version for other classes to use. 1.136 + public static synchronized boolean shouldLogVerbose(String logTag) { 1.137 + for (LogWriter logWriter : logWriters) { 1.138 + if (logWriter.shouldLogVerbose(logTag)) { 1.139 + return true; 1.140 + } 1.141 + } 1.142 + return false; 1.143 + } 1.144 + 1.145 + public static void error(String tag, String message) { 1.146 + Logger.error(tag, message, null); 1.147 + } 1.148 + 1.149 + public static void warn(String tag, String message) { 1.150 + Logger.warn(tag, message, null); 1.151 + } 1.152 + 1.153 + public static void info(String tag, String message) { 1.154 + Logger.info(tag, message, null); 1.155 + } 1.156 + 1.157 + public static void debug(String tag, String message) { 1.158 + Logger.debug(tag, message, null); 1.159 + } 1.160 + 1.161 + public static void trace(String tag, String message) { 1.162 + Logger.trace(tag, message, null); 1.163 + } 1.164 + 1.165 + public static void pii(String tag, String message) { 1.166 + if (LOG_PERSONAL_INFORMATION) { 1.167 + Logger.debug(tag, "$$PII$$: " + message); 1.168 + } 1.169 + } 1.170 + 1.171 + public static synchronized void error(String tag, String message, Throwable error) { 1.172 + Iterator<LogWriter> it = logWriters.iterator(); 1.173 + while (it.hasNext()) { 1.174 + LogWriter writer = it.next(); 1.175 + try { 1.176 + writer.error(tag, message, error); 1.177 + } catch (Exception e) { 1.178 + Log.e(LOGGER_TAG, "Got exception logging; removing LogWriter " + writer + ".", e); 1.179 + it.remove(); 1.180 + } 1.181 + } 1.182 + } 1.183 + 1.184 + public static synchronized void warn(String tag, String message, Throwable error) { 1.185 + Iterator<LogWriter> it = logWriters.iterator(); 1.186 + while (it.hasNext()) { 1.187 + LogWriter writer = it.next(); 1.188 + try { 1.189 + writer.warn(tag, message, error); 1.190 + } catch (Exception e) { 1.191 + Log.e(LOGGER_TAG, "Got exception logging; removing LogWriter " + writer + ".", e); 1.192 + it.remove(); 1.193 + } 1.194 + } 1.195 + } 1.196 + 1.197 + public static synchronized void info(String tag, String message, Throwable error) { 1.198 + Iterator<LogWriter> it = logWriters.iterator(); 1.199 + while (it.hasNext()) { 1.200 + LogWriter writer = it.next(); 1.201 + try { 1.202 + writer.info(tag, message, error); 1.203 + } catch (Exception e) { 1.204 + Log.e(LOGGER_TAG, "Got exception logging; removing LogWriter " + writer + ".", e); 1.205 + it.remove(); 1.206 + } 1.207 + } 1.208 + } 1.209 + 1.210 + public static synchronized void debug(String tag, String message, Throwable error) { 1.211 + Iterator<LogWriter> it = logWriters.iterator(); 1.212 + while (it.hasNext()) { 1.213 + LogWriter writer = it.next(); 1.214 + try { 1.215 + writer.debug(tag, message, error); 1.216 + } catch (Exception e) { 1.217 + Log.e(LOGGER_TAG, "Got exception logging; removing LogWriter " + writer + ".", e); 1.218 + it.remove(); 1.219 + } 1.220 + } 1.221 + } 1.222 + 1.223 + public static synchronized void trace(String tag, String message, Throwable error) { 1.224 + Iterator<LogWriter> it = logWriters.iterator(); 1.225 + while (it.hasNext()) { 1.226 + LogWriter writer = it.next(); 1.227 + try { 1.228 + writer.trace(tag, message, error); 1.229 + } catch (Exception e) { 1.230 + Log.e(LOGGER_TAG, "Got exception logging; removing LogWriter " + writer + ".", e); 1.231 + it.remove(); 1.232 + } 1.233 + } 1.234 + } 1.235 +}