/* TMTS - Android automation testing Framework.
Copyright (C) 2010-2011 TaoBao UI AutoMan Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., HuaXing road, Hangzhou,China.
Email:taichan@taobao.com,shidun@taobao.com,bingyang@taobao.com
*/
package com.taobao.tmts.framework;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Calendar;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;
/**
* Class for printing and saving log.
* @author bingyang.djj
*
*/
public class TmtsLog {
private static final String LOG_TAG = "TmtsLog";
private static final String LOG_FILE_EXTENSION = ".html";
private static final String NEW_LINE = "<br/>";
private static final String RED_START = "<p style='color:red'>";
private static final String GREEN_START = "<p style='color:green'>";
private static final String COLOR_END = "</p>";
/**
* Mini space to save log file, 1MB
*/
private static final long SAFETY_SPACE = 1;
private static File normalFile;
/**
* Print and save normal log
* @param tag Log tag
* @param msg message
*/
public static void i(String tag, String msg) {
Log.i(tag, msg);
final StringBuffer log = new StringBuffer();
log.append(GREEN_START).append(getlogTime()).append(" ")
.append(getPid()).append(" ")
.append(tag).append(" ")
.append(msg).append(NEW_LINE);
new Runnable() {
@Override
public void run() {
saveNormalLog(log.append(COLOR_END).toString());
}
}.run();
}
/**
* @deprecated Use e(String tag, String msg, Throwable e)
* Print and save error/crash log
* @param tag Log tag
* @param msg Log message
*/
public static void e(String tag, String msg) {
StackTraceElement[] traceElements = new Throwable().getStackTrace();
final StringBuffer allLog = new StringBuffer();
Log.e(tag, msg);
allLog.append(RED_START).append(msg).append(NEW_LINE);
//start from 1, we do not need 0
for (int i = 1; i < traceElements.length; i++) {
Log.e(tag, traceElements[i].toString());
allLog.append(traceElements[i].toString())
.append(NEW_LINE);
}
new Runnable() {
@Override
public void run() {
saveNormalLog(allLog.append(COLOR_END).toString());
}
}.run();
}
/**
* Print and save error/crash log
* @param tag Log tag
* @param msg Log message
*/
public static void e(String tag, String msg, Throwable e) {
StackTraceElement[] traceElements = e.getStackTrace();
final StringBuffer allLog = new StringBuffer();
Log.e(tag, msg);
allLog.append(RED_START).append(msg).append(NEW_LINE);
for (int i = 0; i < traceElements.length; i++) {
Log.e(tag, traceElements[i].toString());
allLog.append(traceElements[i].toString())
.append(NEW_LINE);
}
new Runnable() {
@Override
public void run() {
saveNormalLog(allLog.append(COLOR_END).toString());
}
}.run();
}
/**
* Get the Sd Root path.
* @return Sd Root path.
*/
private static File getSdRootPath() {
File sdDir = null;
boolean sdCardExist = Environment.getExternalStorageState()
.equals(android.os.Environment.MEDIA_MOUNTED);
if (sdCardExist) {
sdDir = Environment.getExternalStorageDirectory();
return sdDir;
} else {
Log.i(LOG_TAG, "Sd Card not found");
}
return null;
}
/**
* Get available size of Sd Card.
* @return Available size of Sd Card in MB.
*/
private static long getAvailableSize() {
File path = getSdRootPath();
if (null == path) {
return 0;
}
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return (availableBlocks * blockSize) / 1024 / 1024;
}
/**
* Determine whether the Sd Card has enough space to hold log file
* @return Whether the Sd Card has enough space to hold log file
*/
private static boolean isEnoughSpace() {
return (getAvailableSize() > SAFETY_SPACE) ? true : false;
}
/**
* Determine where to save log files
* @return Root path to save log files
*/
private static File getRootPath() {
return isEnoughSpace() ? getSdRootPath() : Environment.getDataDirectory();
}
/**
* Save crash/error log information to sdcard in html format
* @param logContent Log content
*/
private static void saveLogToFile(String logContent) {
File directory = new File(getRootPath() + "/TMTS_Log/Error");
if (!directory.exists()) {
directory.mkdirs();
}
if (!isEnoughSpace()) {
try {
throw new Exception("There is not enough space in SD Card");
} catch (Exception e) {
e.printStackTrace();
}
}
String fileName = directory.getPath() + "/log_" + getTimeStamp() + LOG_FILE_EXTENSION;
Log.i(LOG_TAG, "file is " + fileName);
FileWriter fwriter = null;
try {
fwriter = new FileWriter(fileName);
synchronized (fwriter) {
fwriter.write(logContent);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (null != fwriter) {
fwriter.flush();
fwriter.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
/**
* Save normal log to Sd Card
* @param logContent Log information
*/
private static void saveNormalLog(String logContent) {
File directory = new File(getRootPath() + "/TMTS_Log/Normal");
if (!directory.exists()) {
directory.mkdirs();
}
if (!isEnoughSpace()) {
try {
throw new Exception("There is not enough space in SD Card");
} catch (Exception e) {
e.printStackTrace();
}
}
File file = null;
if (null == normalFile) {
String fileName = directory.getPath() + "/log_" + getTimeStamp() + LOG_FILE_EXTENSION;
file = new File(fileName);
normalFile = file;
} else {
file = normalFile;
}
FileWriter fwriter = null;
try {
fwriter = new FileWriter(file, true);
synchronized (fwriter) {
fwriter.write(logContent);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != fwriter) {
fwriter.flush();
fwriter.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
/**
* Get a timestamp used for log file name
* @return Timestamp
*/
private static String getTimeStamp() {
Calendar now = Calendar.getInstance();
String timestamp = now.get(Calendar.YEAR)
+ "_" + (now.get(Calendar.MONTH)+1)
+ "_" + now.get(Calendar.DAY_OF_MONTH)
+ "_" + now.get(Calendar.HOUR_OF_DAY)
+ now.get(Calendar.MINUTE)
+ now.get(Calendar.SECOND)
+ now.get(Calendar.MILLISECOND);
return timestamp;
}
/**
* Get current time used for log
* @return current time
*/
private static String getlogTime() {
Calendar now = Calendar.getInstance();
String logTime = (now.get(Calendar.MONTH)+1)
+ "-" + now.get(Calendar.DAY_OF_MONTH)
+ " " + now.get(Calendar.HOUR_OF_DAY)
+ ":" + now.get(Calendar.MINUTE)
+ ":" + now.get(Calendar.SECOND)
+ "." + now.get(Calendar.MILLISECOND);
return logTime;
}
/**
* Get current pid.
* @return current pid.
*/
private static String getPid() {
return String.valueOf(android.os.Process.myPid());
}
}