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 Queue logDataQueue = 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!
返信削除