package me.pjq.pushup;
import android.annotation.SuppressLint;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.util.Log;
import java.io.*;
import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* The log util.
*
* @author Jianqing.Peng
* @since 1.0
*/
public class EFLogger {
@SuppressWarnings("unused")
private static final String TAG = EFLogger.class.getSimpleName();
private static final boolean DEBUG = ApplicationConfig.INSTANCE.DEBUG();
private static EFLogger mInstance = null;
public static final int LOG_LEVEL_INFO = 0;
public static final int LOG_LEVEL_DEBUG = 1;
public static final int LOG_LEVEL_EXCEPTION = 2;
public static final int LOG_LEVEL_CRASH = 3;
public static final int LOG_LEVEL_LOC = 4;
public static final int LOG_LEVEL_SPEED = 5;
private static String LOG_PATH = "";
private static final String LOG_INFO_FILENAME = "MYWORDS_I";
private static final String LOG_DEBUG_FILENAME = "MYWORDS_D";
private static final String LOG_EXCEPTION_FILENAME = "MYWORDS_E";
public static final String LOG_CRASH_FILENAME = "MYWORDS_C";
private static final String LOG_LOC_FILENAME = "LOC";
private static final String LOG_SPEED_FILENAME = "SPE";
private static final String LOG_FILE_EXTNAME = ".log";
public static final int CRASH_LOG_MAX_FILE_LENGTH = 2 * 1024;
public static final int EXCEPTION_LOG_MAX_FILE_LENGTH = 500 * 1024;
public static final int LOC_LOG_MAX_FILE_LENGTH = 10 * 1024;
public static final int SPE_LOG_MAX_FILE_LENGTH = 10 * 1024;
private Object FILE_LOCK = new Object();
public static EFLogger init() {
if (mInstance == null) {
mInstance = new EFLogger();
}
return mInstance;
}
private EFLogger() {
LOG_PATH = createLogPath();
}
/**
* @return
*/
private String createLogPath() {
File dir = new File(LocalPathResolver.getLogDir());
if (!dir.exists() || !dir.isDirectory()) {
dir.mkdirs();
}
return dir.getAbsolutePath();
}
public static void d(String tag, String message) {
mInstance.d_(tag, message);
}
private void d_(String tag, String message) {
if (DEBUG) {
Log.d(tag, message);
saveLogToFile(String.format("%s: %s", tag, message),
LOG_LEVEL_DEBUG);
}
}
public static void d(String tag, Throwable ex) {
mInstance.d_(tag, ex);
}
private void d_(String tag, Throwable ex) {
if (DEBUG) {
Log.d(tag, "Exception:", ex);
saveLogToFile(String.format("%s: %s", tag, getDebugReport(ex)),
LOG_LEVEL_DEBUG);
}
}
public static void i(String tag, String message) {
mInstance.i_(tag, message);
}
private void i_(String tag, String message) {
if (DEBUG) {
if (null == message) {
return;
}
Log.i(tag, message);
try {
String str = String.format("%s: %s", tag, message);
saveLogToFile(str, LOG_LEVEL_INFO);
} catch (OutOfMemoryError oom) {
}
}
}
public static void e(String tag, String message) {
mInstance.e_(tag, message);
}
private void e_(String tag, String message) {
if (DEBUG) {
if (null == message) {
return;
}
Log.e(tag, message);
try {
saveLogToFile(String.format("%s: %s", tag, message),
LOG_LEVEL_EXCEPTION);
} catch (OutOfMemoryError oom) {
}
}
}
public void r(String tag, String message) {
mInstance.r_(tag, message);
}
private void r_(String tag, String message) {
if (DEBUG) {
if (null == message) {
return;
}
Log.e(tag, message);
try {
saveLogToFile(String.format("%s: %s", tag, message),
LOG_LEVEL_EXCEPTION);
} catch (OutOfMemoryError oom) {
}
}
}
public static void e(String tag, Throwable ex) {
mInstance.e_(tag, ex);
}
private void e_(String tag, Throwable ex) {
if (DEBUG) {
Log.e(tag, "Exception:", ex);
try {
saveLogToFile(String.format("%s: %s", tag, getDebugReport(ex)),
LOG_LEVEL_EXCEPTION);
} catch (OutOfMemoryError oom) {
}
}
}
public static void v(String tag, String message) {
mInstance.v_(tag, message);
}
private void v_(String tag, String message) {
if (DEBUG) {
Log.v(tag, message);
}
}
public static void w(String tag, String message) {
mInstance.w_(tag, message);
}
private void w_(String tag, String message) {
if (DEBUG) {
Log.w(tag, message);
}
}
/**
* Get the crash report
*
* @param exception
* @return
*/
@SuppressLint("SimpleDateFormat")
public static String getDebugReport(Throwable exception) {
NumberFormat theFormatter = new DecimalFormat("#0.");
StringBuilder theErrReport = new StringBuilder();
theErrReport.append(MyApplication.getContext().getPackageName()
+ " generated the following exception:\n");
if (exception != null) {
theErrReport.append(exception.toString() + "\n\n");
// stack trace
StackTraceElement[] theStackTrace = exception.getStackTrace();
if (theStackTrace.length > 0) {
theErrReport.append("======== Stack trace =======\n");
int length = theStackTrace.length;
for (int i = 0; i < length; i++) {
theErrReport.append(theFormatter.format(i + 1) + "\t"
+ theStackTrace[i].toString() + "\n");
}
theErrReport.append("=====================\n\n");
}
Throwable theCause = exception.getCause();
if (theCause != null) {
theErrReport.append("======== Cause ========\n");
theErrReport.append(theCause.toString() + "\n\n");
theStackTrace = theCause.getStackTrace();
int length = theStackTrace.length;
for (int i = 0; i < length; i++) {
theErrReport.append(theFormatter.format(i + 1) + "\t"
+ theStackTrace[i].toString() + "\n");
}
theErrReport.append("================\n\n");
}
PackageManager pm = MyApplication.getContext()
.getPackageManager();
PackageInfo pi;
try {
pi = pm.getPackageInfo(MyApplication.getContext()
.getPackageName(), 0);
} catch (NameNotFoundException e) {
pi = new PackageInfo();
pi.versionName = "unknown";
pi.versionCode = 0;
}
Date now = new Date();
SimpleDateFormat format = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
theErrReport.append("======== Environment =======\n");
theErrReport.append("Time=" + format.format(now) + "\n");
theErrReport.append("Device=" + Build.FINGERPRINT + "\n");
try {
Field mfField = Build.class.getField("MANUFACTURER");
theErrReport.append("Manufacturer=" + mfField.get(null) + "\n");
} catch (SecurityException e) {
} catch (NoSuchFieldException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}
theErrReport.append("Model=" + Build.MODEL + "\n");
theErrReport.append("Product=" + Build.PRODUCT + "\n");
theErrReport.append("App="
+ MyApplication.getContext().getPackageName()
+ ", version " + pi.versionName + " (build "
+ pi.versionCode + ")\n");
theErrReport.append("=========================\nEnd Report");
} else {
theErrReport.append("the exception object is null\n");
}
return theErrReport.toString();
}
public static void saveCrashExceptionLog(String tag, Throwable exception) {
mInstance.saveCrashExceptionLog_(tag, exception);
}
private void saveCrashExceptionLog_(String tag, Throwable exception) {
String report = getDebugReport(exception);
if (DEBUG) {
Log.d(tag, report);
saveLogToFile(report, LOG_LEVEL_CRASH);
} else {
saveLogToFile(report, LOG_LEVEL_CRASH);
}
}
/**
* @param tag
* @param exception
*/
public void saveCrashExceptionLog(String tag, String log, int logLevel) {
if (DEBUG) {
Log.d(tag, log);
saveLogToFile(log, logLevel);
}
}
@SuppressLint("SimpleDateFormat")
public void saveLogToFile(String message, int mode) {
String text = message;
if (MyApplication.isSDCardAvailable()) {
synchronized (FILE_LOCK) {
LOG_PATH = createLogPath();
switch (mode) {
case LOG_LEVEL_INFO:
case LOG_LEVEL_DEBUG:
if (DEBUG) {
String dfullName = "";
if (mode == LOG_LEVEL_INFO) {
dfullName = LOG_PATH + File.separator
+ LOG_INFO_FILENAME + LOG_FILE_EXTNAME;
} else {
dfullName = LOG_PATH + File.separator
+ LOG_DEBUG_FILENAME + LOG_FILE_EXTNAME;
}
String currentTimeString = new SimpleDateFormat(
"yyyy.MM.dd HH:mm:ss ").format(new Date());
text = currentTimeString + message;
writeFile(dfullName, text);
}
break;
case LOG_LEVEL_EXCEPTION:
String efullName = LOG_PATH + File.separator
+ LOG_EXCEPTION_FILENAME + LOG_FILE_EXTNAME;
File efile = new File(efullName);
if (efile.exists() && efile.isFile()) {
if (efile.length() >= EXCEPTION_LOG_MAX_FILE_LENGTH) {
String newEFileName = LOG_PATH + File.separator
+ LOG_EXCEPTION_FILENAME + "_B"
+ LOG_FILE_EXTNAME;
File bfile = new File(newEFileName);
if (bfile.exists() && bfile.isFile()) {
deleteFile(newEFileName);
}
efile.renameTo(new File(newEFileName));
}
}
String currentTimeString = new SimpleDateFormat(
"yyyy.MM.dd HH:mm:ss ").format(new Date());
try {
text = currentTimeString + message;
} catch (OutOfMemoryError e) {
break;
}
writeFile(efullName, text);
break;
case LOG_LEVEL_CRASH:
String fullName = LOG_PATH + File.separator
+ LOG_CRASH_FILENAME + LOG_FILE_EXTNAME;
fullName = LOG_PATH
+ File.separator
+ LOG_CRASH_FILENAME
+ "_"
+ new SimpleDateFormat("yyyyMMddHHmmss")
.format(new Date()) + LOG_FILE_EXTNAME;
File file = new File(fullName);
if (file.exists() && file.isFile()) {
if (file.length() >= CRASH_LOG_MAX_FILE_LENGTH) {
String newFileName = LOG_PATH
+ File.separator
+ LOG_CRASH_FILENAME
+ new SimpleDateFormat("yyyyMMddHHmmss")
.format(new Date())
+ LOG_FILE_EXTNAME;
file.renameTo(new File(newFileName));
}
}
writeFile(fullName, message);
break;
case LOG_LEVEL_LOC:
String lfullName = LOG_PATH + File.separator
+ LOG_LOC_FILENAME + LOG_FILE_EXTNAME;
File lfile = new File(lfullName);
if (lfile.exists() && lfile.isFile()) {
if (lfile.length() >= LOC_LOG_MAX_FILE_LENGTH) {
break;
}
}
writeFile(lfullName, message);
break;
case LOG_LEVEL_SPEED:
String sfullName = LOG_PATH + File.separator
+ LOG_SPEED_FILENAME + LOG_FILE_EXTNAME;
File sfile = new File(sfullName);
if (sfile.exists() && sfile.isFile()) {
if (sfile.length() >= SPE_LOG_MAX_FILE_LENGTH) {
break;
}
}
writeFile(sfullName, message);
break;
default:
break;
}
}
}
}
/**
* save data to local file
*
* @param data
*/
private void writeFile(String fileName, String data) {
BufferedWriter buf = null;
try {
buf = new BufferedWriter(new FileWriter(fileName, true));
buf.write(data, 0, data.length());
buf.newLine();
if (buf != null) {
buf.close();
buf = null;
}
} catch (OutOfMemoryError oom) {
} catch (Exception e) {
} finally {
try {
if (buf != null) {
buf.close();
buf = null;
}
} catch (IOException e) {
}
}
}
public String readFromFileByLevel(int mode) {
StringBuffer sbuffer = new StringBuffer();
if (MyApplication.isSDCardAvailable()) {
synchronized (FILE_LOCK) {
LOG_PATH = createLogPath();
File dir = new File(LOG_PATH);
File[] files = dir.listFiles();
int length = files.length;
String name = "";
switch (mode) {
case LOG_LEVEL_LOC:
name = LOG_LOC_FILENAME;
break;
case LOG_LEVEL_SPEED:
name = LOG_SPEED_FILENAME;
break;
default:
break;
}
for (int i = 0; i < length; i++) {
if (files[i].getName().startsWith(name)) {
String fullName = files[i].getAbsolutePath();
String log = readFileToString(fullName);
sbuffer.append(log + "\n");
}
}
}
}
return sbuffer.toString();
}
public byte[] readFileToByte(String fullName) {
byte[] data = null;
BufferedInputStream in = null;
ByteArrayOutputStream out = null;
try {
in = new BufferedInputStream(new FileInputStream(fullName));
out = new ByteArrayOutputStream(1024);
byte[] temp = new byte[1024];
int size = 0;
while ((size = in.read(temp)) != -1) {
out.write(temp, 0, size);
}
data = out.toByteArray();
} catch (Exception e) {
data = null;
} finally {
try {
if (in != null)
in.close();
if (out != null)
out.close();
} catch (IOException ie) {
}
}
return data;
}
public String readFileToString(String fullName) {
StringBuffer sbuffer = new StringBuffer();
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(fullName));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
sbuffer.append(line + "\n");
}
} catch (Exception e) {
} finally {
try {
if (bufferedReader != null)
bufferedReader.close();
} catch (IOException ex) {
}
}
return sbuffer.toString();
}
/**
* delete file.
*
* @param fullFileName
*/
public void deleteFile(String fullFileName) {
if (MyApplication.isSDCardAvailable()) {
synchronized (FILE_LOCK) {
File file = new File(fullFileName);
if (file.exists()) {
file.delete();
}
}
}
}
public void deleteFileByMode(int mode) {
if (MyApplication.isSDCardAvailable()) {
synchronized (FILE_LOCK) {
String name = "";
switch (mode) {
case LOG_LEVEL_INFO:
name = LOG_INFO_FILENAME;
break;
case LOG_LEVEL_DEBUG:
name = LOG_DEBUG_FILENAME;
break;
case LOG_LEVEL_EXCEPTION:
name = LOG_EXCEPTION_FILENAME;
break;
case LOG_LEVEL_CRASH:
name = LOG_CRASH_FILENAME;
break;
case LOG_LEVEL_LOC:
name = LOG_LOC_FILENAME;
break;
case LOG_LEVEL_SPEED:
name = LOG_SPEED_FILENAME;
break;
default:
break;
}
if (!name.equals("")) {
LOG_PATH = createLogPath();
File dir = new File(LOG_PATH);
File[] files = dir.listFiles();
int length = files.length;
for (int i = 0; i < length; i++) {
if (files[i].getName().startsWith(name)) {
File f = files[i];
f.delete();
}
}
}
}
}
}
public boolean hasErrLogFile() {
boolean hasFile = false;
if (MyApplication.isSDCardAvailable()) {
LOG_PATH = createLogPath();
File dir = new File(LOG_PATH);
File[] files = dir.listFiles();
int count = 0;
int length = files.length;
for (int i = 0; i < length; i++) {
if (files[i].getName().startsWith(LOG_CRASH_FILENAME)) {
count++;
}
}
if (count > 0) {
hasFile = true;
}
}
return hasFile;
}
public static void d(String tag, String string, Throwable t) {
mInstance.d_(tag, string, t);
}
private void d_(String tag, String string, Throwable t) {
if (DEBUG) {
Log.d(tag, string, t);
saveLogToFile(String.format("%s: %s", tag, string),
LOG_LEVEL_DEBUG);
}
}
public static void w(String tag, String string, Exception e) {
mInstance.w_(tag, string, e);
}
private void w_(String tag, String string, Exception e) {
if (DEBUG) {
Log.w(tag, string, e);
saveLogToFile(String.format("%s: %s", tag, e),
LOG_LEVEL_DEBUG);
}
}
public static void e(String tag, String string, Exception e) {
mInstance.e_(tag, string, e);
}
private void e_(String tag, String string, Exception e) {
if (DEBUG) {
Log.e(tag, string, e);
saveLogToFile(String.format("%s: %s", tag, e),
LOG_LEVEL_DEBUG);
}
}
}