summaryrefslogtreecommitdiffstats
path: root/src/com/android/messaging/util/LogSaver.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/messaging/util/LogSaver.java')
-rw-r--r--src/com/android/messaging/util/LogSaver.java293
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 "?";
- }
- }
-}