diff options
Diffstat (limited to 'src/com/android/messaging/util/LogSaver.java')
-rw-r--r-- | src/com/android/messaging/util/LogSaver.java | 293 |
1 files changed, 0 insertions, 293 deletions
diff --git a/src/com/android/messaging/util/LogSaver.java b/src/com/android/messaging/util/LogSaver.java deleted file mode 100644 index 7d1f2fd..0000000 --- a/src/com/android/messaging/util/LogSaver.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.messaging.util; - -import android.os.Process; -import android.util.Log; - -import com.android.messaging.Factory; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.text.SimpleDateFormat; -import java.util.logging.FileHandler; -import java.util.logging.Formatter; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Save the app's own log to dump along with adb bugreport - */ -public abstract class LogSaver { - /** - * Writes the accumulated log entries, from oldest to newest, to the specified PrintWriter. - * Log lines are emitted in much the same form as logcat -v threadtime -- specifically, - * lines will include a timestamp, pid, tid, level, and tag. - * - * @param writer The PrintWriter to output - */ - public abstract void dump(PrintWriter writer); - - /** - * Log a line - * - * @param level The log level to use - * @param tag The log tag - * @param msg The message of the log line - */ - public abstract void log(int level, String tag, String msg); - - /** - * Check if the LogSaver still matches the current Gservices settings - * - * @return true if matches, false otherwise - */ - public abstract boolean isCurrent(); - - private LogSaver() { - } - - public static LogSaver newInstance() { - final boolean persistent = BugleGservices.get().getBoolean( - BugleGservicesKeys.PERSISTENT_LOGSAVER, - BugleGservicesKeys.PERSISTENT_LOGSAVER_DEFAULT); - if (persistent) { - final int setSize = BugleGservices.get().getInt( - BugleGservicesKeys.PERSISTENT_LOGSAVER_ROTATION_SET_SIZE, - BugleGservicesKeys.PERSISTENT_LOGSAVER_ROTATION_SET_SIZE_DEFAULT); - final int fileLimitBytes = BugleGservices.get().getInt( - BugleGservicesKeys.PERSISTENT_LOGSAVER_FILE_LIMIT_BYTES, - BugleGservicesKeys.PERSISTENT_LOGSAVER_FILE_LIMIT_BYTES_DEFAULT); - return new DiskLogSaver(setSize, fileLimitBytes); - } else { - final int size = BugleGservices.get().getInt( - BugleGservicesKeys.IN_MEMORY_LOGSAVER_RECORD_COUNT, - BugleGservicesKeys.IN_MEMORY_LOGSAVER_RECORD_COUNT_DEFAULT); - return new MemoryLogSaver(size); - } - } - - /** - * A circular in-memory log to be used to log potentially verbose logs. The logs will be - * persisted in memory in the application and can be dumped by various dump() methods. - * For example, adb shell dumpsys activity provider com.android.messaging. - * The dump will also show up in bugreports. - */ - private static final class MemoryLogSaver extends LogSaver { - /** - * Record to store a single log entry. Stores timestamp, tid, level, tag, and message. - * It can be reused when the circular log rolls over. This avoids creating new objects. - */ - private static class LogRecord { - int mTid; - String mLevelString; - long mTimeMillis; // from System.currentTimeMillis - String mTag; - String mMessage; - - LogRecord() { - } - - void set(int tid, int level, long time, String tag, String message) { - this.mTid = tid; - this.mTimeMillis = time; - this.mTag = tag; - this.mMessage = message; - this.mLevelString = getLevelString(level); - } - } - - private final int mSize; - private final CircularArray<LogRecord> mLogList; - private final Object mLock; - - private final SimpleDateFormat mSdf = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); - - public MemoryLogSaver(final int size) { - mSize = size; - mLogList = new CircularArray<LogRecord>(size); - mLock = new Object(); - } - - @Override - public void dump(PrintWriter writer) { - int pid = Process.myPid(); - synchronized (mLock) { - for (int i = 0; i < mLogList.count(); i++) { - LogRecord rec = mLogList.get(i); - writer.println(String.format("%s %5d %5d %s %s: %s", - mSdf.format(rec.mTimeMillis), - pid, rec.mTid, rec.mLevelString, rec.mTag, rec.mMessage)); - } - } - } - - @Override - public void log(int level, String tag, String msg) { - synchronized (mLock) { - LogRecord rec = mLogList.getFree(); - if (rec == null) { - rec = new LogRecord(); - } - rec.set(Process.myTid(), level, System.currentTimeMillis(), tag, msg); - mLogList.add(rec); - } - } - - @Override - public boolean isCurrent() { - final boolean persistent = BugleGservices.get().getBoolean( - BugleGservicesKeys.PERSISTENT_LOGSAVER, - BugleGservicesKeys.PERSISTENT_LOGSAVER_DEFAULT); - if (persistent) { - return false; - } - final int size = BugleGservices.get().getInt( - BugleGservicesKeys.IN_MEMORY_LOGSAVER_RECORD_COUNT, - BugleGservicesKeys.IN_MEMORY_LOGSAVER_RECORD_COUNT_DEFAULT); - return size == mSize; - } - } - - /** - * A persistent, on-disk log saver. It uses the standard Java util logger along with - * a rotation log file set to store the logs in app's local file directory "app_logs". - */ - private static final class DiskLogSaver extends LogSaver { - private static final String DISK_LOG_DIR_NAME = "logs"; - - private final int mSetSize; - private final int mFileLimitBytes; - private Logger mDiskLogger; - - public DiskLogSaver(final int setSize, final int fileLimitBytes) { - Assert.isTrue(setSize > 0); - Assert.isTrue(fileLimitBytes > 0); - mSetSize = setSize; - mFileLimitBytes = fileLimitBytes; - initDiskLog(); - } - - private static void clearDefaultHandlers(Logger logger) { - Assert.notNull(logger); - for (Handler handler : logger.getHandlers()) { - logger.removeHandler(handler); - } - } - - private void initDiskLog() { - mDiskLogger = Logger.getLogger(LogUtil.BUGLE_TAG); - // We don't want the default console handler - clearDefaultHandlers(mDiskLogger); - // Don't want duplicate print in system log - mDiskLogger.setUseParentHandlers(false); - // FileHandler manages the log files in a fixed rotation set - final File logDir = Factory.get().getApplicationContext().getDir( - DISK_LOG_DIR_NAME, 0/*mode*/); - FileHandler handler = null; - try { - handler = new FileHandler( - logDir + "/%g.log", mFileLimitBytes, mSetSize, true/*append*/); - } catch (Exception e) { - Log.e(LogUtil.BUGLE_TAG, "LogSaver: fail to init disk logger", e); - return; - } - final Formatter formatter = new Formatter() { - @Override - public String format(java.util.logging.LogRecord r) { - return r.getMessage(); - } - }; - handler.setFormatter(formatter); - handler.setLevel(Level.ALL); - mDiskLogger.addHandler(handler); - } - - @Override - public void dump(PrintWriter writer) { - for (int i = mSetSize - 1; i >= 0; i--) { - final File logDir = Factory.get().getApplicationContext().getDir( - DISK_LOG_DIR_NAME, 0/*mode*/); - final String logFilePath = logDir + "/" + i + ".log"; - try { - final File logFile = new File(logFilePath); - if (!logFile.exists()) { - continue; - } - final BufferedReader reader = new BufferedReader(new FileReader(logFile)); - for (String line; (line = reader.readLine()) != null;) { - line = line.trim(); - writer.println(line); - } - } catch (FileNotFoundException e) { - Log.w(LogUtil.BUGLE_TAG, "LogSaver: can not find log file " + logFilePath); - } catch (IOException e) { - Log.w(LogUtil.BUGLE_TAG, "LogSaver: can not read log file", e); - } - } - } - - @Override - public void log(int level, String tag, String msg) { - final SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss.SSS"); - mDiskLogger.info(String.format("%s %5d %5d %s %s: %s\n", - sdf.format(System.currentTimeMillis()), - Process.myPid(), Process.myTid(), getLevelString(level), tag, msg)); - } - - @Override - public boolean isCurrent() { - final boolean persistent = BugleGservices.get().getBoolean( - BugleGservicesKeys.PERSISTENT_LOGSAVER, - BugleGservicesKeys.PERSISTENT_LOGSAVER_DEFAULT); - if (!persistent) { - return false; - } - final int setSize = BugleGservices.get().getInt( - BugleGservicesKeys.PERSISTENT_LOGSAVER_ROTATION_SET_SIZE, - BugleGservicesKeys.PERSISTENT_LOGSAVER_ROTATION_SET_SIZE_DEFAULT); - final int fileLimitBytes = BugleGservices.get().getInt( - BugleGservicesKeys.PERSISTENT_LOGSAVER_FILE_LIMIT_BYTES, - BugleGservicesKeys.PERSISTENT_LOGSAVER_FILE_LIMIT_BYTES_DEFAULT); - return setSize == mSetSize && fileLimitBytes == mFileLimitBytes; - } - } - - private static String getLevelString(final int level) { - switch (level) { - case android.util.Log.DEBUG: - return "D"; - case android.util.Log.WARN: - return "W"; - case android.util.Log.INFO: - return "I"; - case android.util.Log.VERBOSE: - return "V"; - case android.util.Log.ERROR: - return "E"; - case android.util.Log.ASSERT: - return "A"; - default: - return "?"; - } - } -} |