logcat保存当前应用程序的日志并上传服务器或指定邮箱
给大家分享一个项目中用到的日志统计并提交服务器的日志工具类.
通过过得当前app的PID,采用命令行的方式实用logcat工具过滤日志。
代码区:
package org.and.util; import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List; import android.content.Context;
import android.os.Environment; /**
* TODO: log日志统计保存、上传-工具类
*
* @author hljdrl@gmail.com * @date 2012-8-27 上午11:43:52 */ public class LogcatHelper { private static LogcatHelper INSTANCE = null; private static String PATH_LOGCAT ; private LogDumper mLogDumper = null; private Context mContext; private int mPId; /** * 初始化目录 * */ public static void init(Context context) { StringBuffer LogPath = new StringBuffer(); LogPath.append(Environment.getExternalStorageDirectory()); LogPath.append("/Android/data/"); LogPath.append(context.getPackageName()).append("/"); LogPath.append("logs").append("/"); PATH_LOGCAT = LogPath.toString(); // File file =new File(PATH_LOGCAT); if(!file.exists()){ file.mkdirs(); } } public static LogcatHelper getInstance(Context context) { if(INSTANCE == null){ INSTANCE = new LogcatHelper(context); } return INSTANCE; } private LogcatHelper(Context context) { mContext = context; mPId = android.os.Process.myPid(); } public void start() { if(mLogDumper==null){ mLogDumper = new LogDumper(String.valueOf(mPId),PATH_LOGCAT); mLogDumper.start(); } } public void stop() { if(mLogDumper!=null){ mLogDumper.stopLogs(); mLogDumper = null; } } public void sendLogMessage(Context context,String user) { if(mLogDumper!=null){ mLogDumper.setLogFileLock(true); String file = mLogDumper.getLogFileName(); File sendFile = new File(file); if(sendFile.exists() && sendFile.length()>2000){ try{ EmailHelper.sendMail(context, user, file); }catch(Exception ex){ ex.printStackTrace(); } File newFile = new File(file); try { newFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } mLogDumper.setLogFileLock(false); } } private class LogDumper extends Thread{ String fileName; private Process logcatProc; private BufferedReader mReader = null; private boolean mRunning = false; String cmds=null; private final String mPID; private FileOutputStream out = null; private List<String> logsMessage = new ArrayList<String>(); private boolean mLogFileLock = false; private String logFileName; public void setLogFileLock(boolean lock){ mLogFileLock = lock; } public boolean isLogFileLock() { return mLogFileLock; } public LogDumper(String pid,String file) { mPID = String.valueOf(pid); fileName = file; File mFile = new File(fileName,"error.txt"); if(!mFile.exists()){ try { mFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } try { logFileName = mFile.toString(); out = new FileOutputStream(mFile,true); } catch (FileNotFoundException e) { e.printStackTrace(); } /** * 日志等级:*:v , *:d , *:w , *:e , *:f , *:s * 显示当前mPID程序的 E和W等级的日志. * */ cmds ="logcat *:e *:w | grep \"("+mPID+")\""; } public String getLogFileName() { return logFileName; } public void stopLogs() { mRunning = false; } private boolean checkFileMaxSize(String file){ File sizefile = new File(file); if(sizefile.exists()){ //1.5MB if(sizefile.length()>1572864){ return true; } else { return false; } }else { return false; } } @Override public void run() { System.out.println("LogCatHelper'"); mRunning = true; try { logcatProc = Runtime.getRuntime() .exec(cmds); mReader = new BufferedReader(new InputStreamReader( logcatProc.getInputStream()), 1024); String line = null; while (mRunning && (line = mReader.readLine()) != null) { if (!mRunning) { break; } if (line.length() == 0) { continue; } synchronized (out) { if (out != null) { boolean maxSize = checkFileMaxSize(getLogFileName()); if(maxSize){ //文件大小超过1.5mb sendLogMessage(mContext, DeviceHelper.getInstance(mContext).getImei()); } if (isLogFileLock()) { if(line.contains(mPID)){ logsMessage.add(line.getBytes() + "\n"); } } else { if(logsMessage.size()>0){ for(String _log:logsMessage){ out.write(_log.getBytes()); } logsMessage.clear(); } /** * 再次过滤日志,筛选当前日志中有 mPID 则是当前程序的日志. * */ if(line.contains(mPID)){ out.write(line.getBytes()); out.write("\n".getBytes()); } } } } } } catch (IOException e) { e.printStackTrace(); return; } finally { if (logcatProc != null) { logcatProc.destroy(); logcatProc = null; } if (mReader != null) { try { mReader.close(); mReader = null; } catch (IOException e) { e.printStackTrace(); } } if(out!=null){ try { out.close(); } catch (IOException e) { e.printStackTrace(); } out = null; } } } } }
详细说明:http://android.662p.com/thread-216-1-1.html
logcat保存当前应用程序的日志并上传服务器或指定邮箱的更多相关文章
- Laravel中的日志与上传
PHP中的框架众多,我自己就接触了好几个.大学那会啥也不懂啥也不会,拿了一个ThinkPHP学了.也许有好多人吐槽TP,但是个人感觉不能说哪个框架好,哪个框架不好,再不好的框架你能把源码读上一遍,框架 ...
- 微信小程序:多张图片上传
最近在写小程序的相册,需要多张图片的上传.因为小程序不支持数组的多张图片同时上传,然后根据自己的需求+借鉴网上各位大神的案例,总算搞定.分享下,不足之处,多多指教哦 页面wxml: <form ...
- 微信小程序简单封装图片上传组件
微信小程序简单封装图片上传组件 希望自己 "day day up" -----小陶 我从哪里来 在写小程序的时候需要上传图片,个人觉得官方提供的 Uploader 组件不是太好用, ...
- Android将应用程序的崩溃信息如何保存到本地文件,并上传服务器
导语:最近实在是太忙了,没有怎么更新公众号,也没有怎么认真去写一些内容,在这里先给关注我的朋友说一声抱歉,可能在接下来的一段时间,还是很忙,但是我会争取抽空多分享一下技术文章,给大家看,共同进步,也希 ...
- MVC应用程序中管理(更新)上传的文件
实现上传文件功能,有时上传也会操作出错,能让用户有改正有机会,开发上传文件能有更新的功能. 文件上传时,如果是存储于应用程序某一目录的话,在更新时需要了解一些流程,先是删除旧文件,更新数据表相关信息, ...
- 如何上传网站程序(文件浏览器上传网页、FileZilla上传网站程序)
问题场景: 网页制作完成后,程序需上传至虚拟主机. 注意事项: Windows系统的主机请将全部网页文件直接上传到FTP根目录,即 / . Linux系统的主机请将全部网页文件直接上传到 /htdoc ...
- iOS 日志系统 本地日志打包上传到服务器
日志系统主要包含两个部分 1.本地保存 我们知道NSLog打印的日志一般都是直接输出到控制台,开发人员可以在控制台直接看到实时打印的log,既然可以在控制台输出,那么能否将日志输出到其他地方呢,比如说 ...
- ios上传应用后,审核流程完成前(reveiw)修改了程序内容,如何上传替换
其实挺简单,只需要更改下version和build版本 看图说话就可以.我的程序之前版的版本设置 修改bug之后的设置: 然后重新打包就好了,提示打包成功后,在itunesconnect查看发现 选中 ...
- 微信小程序实现图片是上传、预览功能
本文实例讲述了微信小程序实现图片上传.删除和预览功能的方法,分享给大家供大家参考,具体如下: 这里主要介绍一下微信小程序的图片上传图片删除和图片预览 1.可以调用相机也可以从本地相册选择 2.本地实现 ...
随机推荐
- git 空提交和重置提交者(转载)
From:http://www.xiukun.me/git%E4%BD%BF%E7%94%A8-allow-empty-%E8%BF%9B%E8%A1%8C%E7%A9%BA%E7%99%BD%E6% ...
- Ubuntu 12.04.2搭建nfs服务器
1.安装nfs 服务器(192.168.0.1) apt-get install nfs-kernel-server 2.修改nfs配置文件: vim /etc/exports 在exports文件中 ...
- Python多个版本安装!
Python可以同时安装多个版本,目前我安装的是3.6和3.5,在Eclipse中使用3.6:在Visual Studio中使用3.5.如何让哪个版本的Python成为系统默认的解释器呢?通过调整不同 ...
- linux内核神级list
源码: #ifndef _LINUX_LIST_H #define _LINUX_LIST_H /* * Simple doubly linked list implementation. * * S ...
- c# as
as:用于检查在兼容的引用类型之间执行某些类型的转换. Employee myEmployee = myObject as Employee; if (myEmployee != null) { } ...
- QT中QWidget、QDialog QMainWindow
继承关系:在Qt中所有的类都有一个共同的基类QObject ,QWidget直接继承与QPaintDevice类,QDialog.QMainWindow.QFrame直接继承QWidget 类. QW ...
- .net中三种数据类型转换区别((int),Int32.Parse() 和 Convert.toInt32() )
(typename)valuename,是通用方法: Convert类提供了灵活的类型转换封装: Parse方法,适用于向数字类型的转换. 例如,(int),Int32.Parse() 和 Conve ...
- (medium)LeetCode 207.Course Schedule
There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prer ...
- sqlite报错OutOfMemory
如 java.sql.SQLException: out of memory at org.sqlite.DB.throwex(DB.java:252) at org.sqlite.NestedDB. ...
- SVN小小用法(一)svn服务器搭建
最近由于公司项目用SVN作为版本控制工具,本着学一点是一点的原则,今天小配了下svn,给大家介绍一下 软件:TortoiseSVN-1.8.3.24901-win32-svn-1.8.4.msi(本人 ...