log日志打印封装,并保存到本地文件
2016-06-21 19:33
447 查看
封装了本地日志,可以通过config
文件动态控制log的打印,方便上线前日志打印的检查,并且如果在测试环境下,日志等级为i以上的日志都会存文件,并且文件以日期命名,最大数量为5,可以配置。
代码如下所示:
线程池类代码如下:
文件保存类代码如下:
文件目录的创建代码:
保存的文件如下所示:
文件中的日志如下所示:
文件动态控制log的打印,方便上线前日志打印的检查,并且如果在测试环境下,日志等级为i以上的日志都会存文件,并且文件以日期命名,最大数量为5,可以配置。
代码如下所示:
public final class EBLog { private static final String TAG = EBLog.class.getName(); /** * Define the log priority. */ private static LogType logType; private static HashMap<Integer, String> level = new HashMap<>(); static { level.put(2, "verbose"); level.put(3, "debug"); level.put(4, "info"); level.put(5, "warn"); level.put(6, "error"); level.put(7, "asset"); if (Config.ISRELEASE) { setLogType(LogType.asset); } else { setLogType(LogType.verbose); } } private EBLog() { } /** * Get the log level. * * @return log level */ public static LogType getLogType() { return logType; } /** * Set the log level for the application. * * @param logType the value to be set. */ public static void setLogType(LogType logType) { EBLog.logType = logType; i(TAG, "logType: " + logType); } /** * Send a log message. * * @param tag Used to identify the source of a log message. It usually * identifies the class or activity where the log call occurs. * @param msg The message you would like logged. */ public static int v(String tag, String msg) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; return ElectronicBrandPrintln(LogType.verbose.value(), tag, msg,stackTraceElement); } /** * Send a log message and log the exception. * * @param tag Used to identify the source of a log message. It usually * identifies the class or activity where the log call occurs. * @param msg The message you would like logged. * @param tr An exception to log */ public static int v(String tag, String msg, Throwable tr) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; return ElectronicBrandPrintln(LogType.verbose.value(), tag, msg + '\n' + getStackTraceString(tr),stackTraceElement); } /** * Send a log message. * * @param tag Used to identify the source of a log message. It usually * identifies the class or activity where the log call occurs. * @param msg The message you would like logged. */ public static int d(String tag, String msg) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; return ElectronicBrandPrintln(LogType.debug.value(), tag, msg,stackTraceElement); } /** * Send a log message and log the exception. * * @param tag Used to identify the source of a log message. It usually * identifies the class or activity where the log call occurs. * @param msg The message you would like logged. * @param tr An exception to log */ public static int d(String tag, String msg, Throwable tr) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; return ElectronicBrandPrintln(LogType.debug.value(), tag, msg + '\n' + getStackTraceString(tr),stackTraceElement); } /** * Send an log message. * * @param tag Used to identify the source of a log message. It usually * identifies the class or activity where the log call occurs. * @param msg The message you would like logged. */ public static int i(String tag, String msg) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; return ElectronicBrandPrintln(LogType.info.value(), tag, msg,stackTraceElement); } /** * Send a log message and log the exception. * * @param tag Used to identify the source of a log message. It usually * identifies the class or activity where the log call occurs. * @param msg The message you would like logged. * @param tr An exception to log */ public static int i(String tag, String msg, Throwable tr) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; return ElectronicBrandPrintln(LogType.info.value(), tag, msg + '\n' + getStackTraceString(tr),stackTraceElement); } /** * Send a log message. * * @param tag Used to identify the source of a log message. It usually * identifies the class or activity where the log call occurs. * @param msg The message you would like logged. */ public static int w(String tag, String msg) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; return ElectronicBrandPrintln(LogType.warn.value(), tag, msg,stackTraceElement); } /** * Send a log message and log the exception. * * @param tag Used to identify the source of a log message. It usually * identifies the class or activity where the log call occurs. * @param msg The message you would like logged. * @param tr An exception to log */ public static int w(String tag, String msg, Throwable tr) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; return ElectronicBrandPrintln(LogType.warn.value(), tag, msg + '\n' + getStackTraceString(tr),stackTraceElement); } /** * Checks to see whether or not a log for the specified tag is loggable at * the specified level. The default level of any tag is set to INFO. This * means that any level above and including INFO will be logged. Before you * make any calls to a logging method you should check to see if your tag * should be logged. You can change the default level by setting a system * property: 'setprop log.tag.<YOUR_LOG_TAG> <LEVEL>' Where level is * either value of LogType, or SUPPRESS. SUPRESS will turn off all logging * for your tag. You can also create a local.prop file that with the * following in it: 'log.tag.<YOUR_LOG_TAG>=<LEVEL>' and place that in * /data/local.prop. * * @param tag The tag to check. * @param level The level to check, value of LogType. * @return Whether or not that this is allowed to be logged. * @throws IllegalArgumentException is thrown if the tag.length() > 23. */ public static native boolean isLoggable(String tag, int level); /* * Send a {@link #WARN} log message and log the exception. * * @param tag Used to identify the source of a log message. It usually * identifies the class or activity where the log call occurs. * * @param tr An exception to log */ public static int w(String tag, Throwable tr) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; return ElectronicBrandPrintln(LogType.warn.value(), tag, getStackTraceString(tr),stackTraceElement); } /** * Send an log message. * * @param tag Used to identify the source of a log message. It usually * identifies the class or activity where the log call occurs. * @param msg The message you would like logged. */ public static int e(String tag, String msg) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; return ElectronicBrandPrintln(LogType.error.value(), tag, msg,stackTraceElement); } /** * Send a log message and log the exception. * * @param tag Used to identify the source of a log message. It usually * identifies the class or activity where the log call occurs. * @param msg The message you would like logged. * @param tr An exception to log */ public static int e(String tag, String msg, Throwable tr) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[3]; return ElectronicBrandPrintln(LogType.error.value(), tag, msg + "\n" + getStackTraceString(tr),stackTraceElement); } /** * Handy function to get a loggable stack trace from a Throwable * * @param tr An exception to log */ private static String getStackTraceString(Throwable tr) { if (tr == null) { return ""; } StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); tr.printStackTrace(pw); return sw.toString(); } private static int ElectronicBrandPrintln(int priority, String tag, String msg,StackTraceElement stackTraceElement) { if (priority >= logType.value()) { if (!Config.ISRELEASE && priority >= 4) { ThreadPoolService.addTask(new LogSaveUtils(getLogInfo( priority, tag, msg,stackTraceElement))); } return android.util.Log.println(priority, tag, msg); } else { return -1; } } /** * May be verbose, debug, info, warn, error, asset. * * @author coleman */ public static enum LogType { verbose(2), debug(3), info(4), warn(5), error(6), asset(7); private final int type; private LogType(int type) { this.type = type; } public int value() { return type; } public static LogType instanse(int i) { LogType type = verbose; switch (i) { case 2: type = verbose; break; case 3: type = debug; break; case 4: type = info; break; case 5: type = warn; break; case 6: type = error; break; case 7: type = asset; break; default: type = null; break; } return type; } } /** * 保存日志所包含的信息 * * @param tag * @param priority * @return */ private static String getLogInfo(int priority, String tag, String msg,StackTraceElement stackTraceElement) { StringBuilder logInfoStringBuilder = new StringBuilder(); // 获取线程名 String threadName = Thread.currentThread().getName(); // 获取类名.即包名+类名 String className = stackTraceElement.getClassName(); // 获取方法名称 String methodName = stackTraceElement.getMethodName(); // 获取生日输出行数 int lineNumber = stackTraceElement.getLineNumber(); logInfoStringBuilder.append(GeneralUtils.getCurrentTime(Constants.YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)); logInfoStringBuilder.append(" ["); logInfoStringBuilder.append(threadName).append("] "); logInfoStringBuilder.append(className).append(" "); logInfoStringBuilder.append(level.get(priority)).append("/").append(tag); logInfoStringBuilder.append(" [methodName=" + methodName).append("] "); logInfoStringBuilder.append("[lineNumber=" + lineNumber); logInfoStringBuilder.append(" ] "); logInfoStringBuilder.append(msg); return logInfoStringBuilder.toString(); } }
线程池类代码如下:
/** * <线程池管理> * * @author caoyinfei * @version [版本号, 2016/6/21] * @see [相关类/方法] * @since [V1] */ public class ThreadPoolService { private static ExecutorService executor = Executors.newCachedThreadPool(); public static void addTask(LogSaveUtils logSaveUtils){ executor.execute(logSaveUtils); } }
文件保存类代码如下:
/** * <日志文件处理类> * * @author caoyinfei * @version [版本号, 2016/6/21] * @see [相关类/方法] * @since [V1] */ public class LogSaveUtils implements Runnable { private String content; public LogSaveUtils(String content) { this.content = content; } /** * 文件最大个数 */ private static final int MAX_SIZE = 5; /** * 文件名后缀 */ private static String FILE_NAME = ".log"; /** * 文件 */ private File file; /** * 输出流 */ private RandomAccessFile randomAccessFile; private SimpleDateFormat dataFormat = new SimpleDateFormat("yyyy-MM-dd");// 日志名称格式 @Override public void run() { saveToFile(); } /** * 保存到本地文件 */ private synchronized void saveToFile() { try { deleteFile(); LocalFileStorageManager localFileStorageManager = BridgeFactory.getBridge(Bridges.LOCAL_FILE_STORAGE); String fileName = localFileStorageManager.getVersionLogPath() + Config.LOG_FILE_NAME + GeneralUtils.getCurrentTime(Constants.YEAR_MONTH_DAY) + FILE_NAME; file = new File(fileName); randomAccessFile = new RandomAccessFile(file, "rw"); randomAccessFile.seek(file.length()); randomAccessFile.write(content.getBytes("utf-8")); randomAccessFile.write("\r\n".getBytes()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { randomAccessFile.close(); } catch (Exception e) { } } } /** * 文件超过最大个数则删除最旧的文件 */ private void deleteFile() { LocalFileStorageManager localFileStorageManager = BridgeFactory.getBridge(Bridges.LOCAL_FILE_STORAGE); File root = new File(localFileStorageManager.getVersionLogPath()); if (root.isDirectory()) { File[] listFiles = root.listFiles(); if (listFiles != null && listFiles.length >= MAX_SIZE) { Arrays.sort(listFiles, new FileComparator()); listFiles[0].delete(); } } } class FileComparator implements Comparator<File> { public int compare(File file1, File file2) { String createInfo1 = getFileNameWithoutExtension(file1.getName()); String createInfo2 = getFileNameWithoutExtension(file2.getName()); try { Date create1 = dataFormat.parse(createInfo1); Date create2 = dataFormat.parse(createInfo2); if (create1.before(create2)) { return -1; } else { return 1; } } catch (ParseException e) { return 0; } } } /** * 去除文件的扩展类型(.log) * * @param fileName * @return */ private String getFileNameWithoutExtension(String fileName) { try { return fileName.substring(fileName.indexOf(".")+1, fileName.lastIndexOf(".")); } catch (Exception e) { return ""; } } }
/** * <上线前需要更改的配置文件> * * @author caoyinfei * @version [版本号, 2016/6/21] * @see [相关类/方法] * @since [产品/模块版本] */ public class Config { /** * 是否为release版本 */ public static final boolean ISRELEASE = false; /** * 日志文件前缀 */ public static final String LOG_FILE_NAME = "eb-p."; }
文件目录的创建代码:
/** * <日志目录> * <功能详细描述> * @return */ public static String getVersionLogPath() { return FileUtil.createNewFile(getCacheFilePath() + FOLDER_NAME_LOG + File.separator); }
public static String createNewFile(String path) { File dir = new File(path); if (!dir.exists()) { dir.mkdirs(); } return path; }
保存的文件如下所示:
eb-p.2016-06-23.log eb-p.2016-06-28.log
文件中的日志如下所示:
2016-06-23 16:43:17 [main] com.test.electronicbrand.capabilities.log.EBLog info/com.test.electronicbrand.capabilities.log.EBLog [methodName=setLogType] [lineNumber=90 ] logType: verbose 2016-06-23 16:43:17 [main] com.test.electronicbrand.ui.personcenter.LoginActivity info/sdsd [methodName=initData] [lineNumber=57 ] ssdsd 2016-06-23 16:43:17 [main] com.test.electronicbrand.ui.personcenter.LoginActivity info/aaa [methodName=setHeader] [lineNumber=64 ] dfdf
相关文章推荐
- Tomcat端口被占用解决方法(不用重启)
- “传奇”图象数据存储方式
- 超大数据量存储常用数据库分表分库算法总结
- flash 打开本地文件代码
- SQL Server误区30日谈 第18天 有关FileStream的存储,垃圾回收以及其它
- C++实现图的邻接表存储和广度优先遍历实例分析
- 详解Android文件存储
- 利用xcopy命令实现本地文件复制到远程服务器的方法
- C#调用sql2000存储过程方法小结
- PHP 存储文本换行实现方法
- mysql日志文件在哪 如何修改MySQL日志文件位置
- 注册表中存储数据库链接字符串的方法
- C#记录消息到日志文件的方法
- Mysql中存储UUID去除横线的方法
- Shell脚本定期清空大于1G的日志文件
- Mysql日志文件和日志类型介绍
- mysql二进制日志文件恢复数据库
- MySQLMerge存储引擎
- 深入PHP变量存储的详解
- MySQL存储毫秒数据的方法