AndroidのLogをファイルで出力
AndroidのLog出力をスマートに変更し、そのログをFileにも出力するようにしたソースです。出力されたログファイルはSplash(アプリ起動する)時にサーバ側にアップロードすることで、Debugが可能になるかと思います。
Libraryは
jodaとGuava
を利用しています。com.park.constants.Globalsには各種設定情報が格納されています。
package com.park.util; import android.util.Log; import com.google.common.base.Charsets; import com.google.common.io.CharSink; import com.google.common.io.Files; import com.park.constants.Globals; import com.park.exception.PlatformException; import org.joda.time.format.DateTimeFormat; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; /** * Filename : LogUtil.java * Function : * Comment : ログ出力に関するUtil * History : 2016/03/30, su min park, develop * * @version 1.0 * @author su min park * @since JDK 1.7 */ public class LogUtil { // ********************************************************************** // 定数 // ********************************************************************** private static final String TAG = "After"; private static final int LOG_LEVEL = Log.DEBUG; // ********************************************************************** // メンバ // ********************************************************************** private static boolean mIsShowLog = true; private static boolean mIsRunWriteThread = false; private static QueuelogDataQueue = new ConcurrentLinkedQueue (); // ********************************************************************** // パブリックメソッド // ********************************************************************** public static void setShowLog(boolean isShowLog) { mIsShowLog = isShowLog; } public static void d() { outputLog(Log.DEBUG, null, null); } public static void d(String message) { outputLog(Log.DEBUG, message, null); } public static void d(String message, Throwable throwable) { outputLog(Log.DEBUG, message, throwable); } public static void i(String message) { outputLog(Log.INFO, message, null); } public static void i(String message, Throwable throwable) { outputLog(Log.INFO, message, throwable); } public static void w(String message) { outputLog(Log.WARN, message, null); } public static void w(String message, Throwable throwable) { outputLog(Log.WARN, message, throwable); } public static void e(String message, Throwable throwable) { outputLog(Log.ERROR, message, throwable); } public static void e(Throwable throwable) { outputLog(Log.ERROR, null, throwable); } // ********************************************************************** // プライベートメソッド // ********************************************************************** private static void outputLog(int type, String message, Throwable throwable) { if (!mIsShowLog) { // ログ出力フラグが立っていない場合は何もしません。 return; } // ログのメッセージ部分にスタックトレース情報を付加します。 if (message == null) { message = getStackTraceInfo(); } else { message = getStackTraceInfo() + message; } // ログを出力! switch (type) { case Log.DEBUG: if (throwable == null) { Log.d(TAG, message); } else { Log.d(TAG, message, throwable); } break; case Log.INFO: if (throwable == null) { Log.i(TAG, message); } else { Log.i(TAG, message, throwable); } break; case Log.WARN: if (throwable == null) { Log.w(TAG, message); } else { Log.w(TAG, message, throwable); } break; case Log.ERROR: if (throwable == null) { Log.e(TAG, message); } else { Log.e(TAG, message, throwable); } break; } //ファイル出力はしない if (type >= LOG_LEVEL) { addQueue(message, throwable); threadQueue(); } } /** * Queueにログを追加する * 処理に時間がかかる場合はThreadに修正 * @param message * @param throwable */ private static void addQueue(String message, Throwable throwable) { String eMessage = ""; if (throwable != null) { try { eMessage = getStackTraceString(throwable); } catch (IOException ioe) { } } String logWriteTime = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").toString(); logDataQueue.offer(logWriteTime + "\t" + message +"\n"+ eMessage); } /** * Queueに溜まったデータをThreadで処理する */ private static synchronized void threadQueue() { try { if (!mIsRunWriteThread) { mIsRunWriteThread = true; //UI制御はない。 (new Thread(new Runnable() { @Override public void run() { StringBuffer logBuffer = new StringBuffer(); while (!logDataQueue.isEmpty()) { String log = logDataQueue.poll(); if (log != null) { logBuffer.append(log); } } //残り write writeLogFile(logBuffer); mIsRunWriteThread = false; } })).start(); } } catch (Exception e) { Log.e(TAG, "Log thread error" , e); } } /** * 操作ログデータをファイルに書き込む * @param logBuffer */ private static synchronized void writeLogFile(final StringBuffer logBuffer) { if (logBuffer == null || logBuffer.length() == 0) return ; try { try { String sPath = Globals.getInstance().LOG_PATH; //String sPath = Environment.getExternalStorageDirectory().getPath() + "/appName/log"; String sLogName = "ll_" + DateTimeFormat.forPattern("yyyyMMdd").toString() + ".txt"; File logFile = new File(sPath + File.separator + sLogName); Files.createParentDirs(logFile); CharSink sink = Files.asCharSink(logFile, Charsets.UTF_8); sink.write(logBuffer.toString()); } catch (IOException e) { Log.e(TAG, "Log Write failed" , e); } catch (PlatformException e) { Log.e(TAG, "Globals not init" , e); } } finally { logBuffer.charAt(0); } } /** * スタックトレースから呼び出し元の基本情報を取得。 * @return */ private static String getStackTraceInfo() { // 現在のスタックトレースを取得。 // 0:VM 1:スレッド 2:getStackTraceInfo() 3:outputLog() 4:logDebug()等 5:呼び出し元 StackTraceElement element = Thread.currentThread().getStackTrace()[5]; String fullName = element.getClassName(); String className = fullName.substring(fullName.lastIndexOf(".") + 1); String methodName = element.getMethodName(); int lineNumber = element.getLineNumber(); return "<<" + className + "#" + methodName + ":" + lineNumber + ">> "; } /** * Throwableのスタックトレース情報を返す。 * @param e * @return * @throws IOException */ private static String getStackTraceString(Throwable e) throws IOException { // エラーのスタックトレースを表示 StringWriter sw = new StringWriter(); PrintWriter pw = null; try { pw = new PrintWriter(sw); e.printStackTrace(pw); pw.flush(); } finally { if (pw != null) { pw.close(); } } return sw.toString(); } }
Someone essentially assist to make severely articles I would state. That is the first time I frequented your web page and up to now? I amazed with the analysis you made to create this actual post extraordinary. Excellent task!
返信削除Click to see the code!
To insert emoticon you must added at least one space before the code.