分享一个项目中用到的日志统计并提交服务器的日志工具类.
通过过得当前app的PID,采用命令行的方式实用logcat工具过滤日志。
源码如下:
项目地址:http://code.google.com/p/andutils/
001 |
package org.and.util;
|
002 |
003 |
import java.io.BufferedReader;
|
004 |
import java.io.File;
|
005 |
import java.io.FileNotFoundException;
|
006 |
import java.io.FileOutputStream;
|
007 |
import java.io.IOException;
|
008 |
import java.io.InputStreamReader;
|
009 |
import java.util.ArrayList;
|
010 |
import java.util.List;
|
011 |
012 |
import android.content.Context;
|
013 |
import android.os.Environment;
|
014 |
|
015 |
016 |
/** |
017 |
* TODO: log日志统计保存、上传-工具类
|
018 |
*
|
019 |
* @author hljdrl@gmail.com
|
020 |
021 |
* @date 2012-8-27 上午11:43:52
|
022 |
023 |
*/
|
024 |
025 |
public class LogcatHelper {
|
026 |
027 |
private static LogcatHelper INSTANCE = null;
|
028 |
029 |
private static String PATH_LOGCAT ;
|
030 |
031 |
private LogDumper mLogDumper = null;
|
032 |
033 |
private Context mContext;
|
034 |
035 |
private int mPId;
|
036 |
037 |
/**
|
038 |
039 |
* 初始化目录
|
040 |
041 |
* */
|
042 |
043 |
public static void init(Context context)
|
044 |
045 |
{
|
046 |
047 |
StringBuffer LogPath = new StringBuffer();
|
048 |
049 |
LogPath.append(Environment.getExternalStorageDirectory());
|
050 |
051 |
LogPath.append("/Android/data/");
|
052 |
053 |
LogPath.append(context.getPackageName()).append("/");
|
054 |
055 |
LogPath.append("logs").append("/");
|
056 |
057 |
PATH_LOGCAT = LogPath.toString();
|
058 |
059 |
//
|
060 |
061 |
File file =new File(PATH_LOGCAT);
|
062 |
063 |
if(!file.exists()){
|
064 |
065 |
file.mkdirs(); |
066 |
067 |
} |
068 |
069 |
}
|
070 |
071 |
public static LogcatHelper getInstance(Context context)
|
072 |
073 |
{
|
074 |
075 |
if(INSTANCE == null){
|
076 |
077 |
INSTANCE = new LogcatHelper(context);
|
078 |
079 |
}
|
080 |
081 |
return INSTANCE;
|
082 |
083 |
}
|
084 |
085 |
private LogcatHelper(Context context) {
|
086 |
087 |
mContext = context;
|
088 |
089 |
mPId = android.os.Process.myPid();
|
090 |
091 |
} |
092 |
093 |
public void start() {
|
094 |
095 |
if(mLogDumper==null){
|
096 |
097 |
mLogDumper = new LogDumper(String.valueOf(mPId),PATH_LOGCAT);
|
098 |
099 |
mLogDumper.start(); |
100 |
101 |
} |
102 |
103 |
} |
104 |
105 |
public void stop()
|
106 |
107 |
{ |
108 |
109 |
if(mLogDumper!=null){
|
110 |
111 |
mLogDumper.stopLogs(); |
112 |
113 |
mLogDumper = null;
|
114 |
115 |
} |
116 |
117 |
} |
118 |
119 |
public void sendLogMessage(Context context,String user)
|
120 |
121 |
{ |
122 |
123 |
if(mLogDumper!=null){
|
124 |
125 |
mLogDumper.setLogFileLock(true);
|
126 |
127 |
String file = mLogDumper.getLogFileName(); |
128 |
129 |
File sendFile = new File(file);
|
130 |
131 |
if(sendFile.exists() && sendFile.length()>2000){
|
132 |
133 |
try{
|
134 |
135 |
EmailHelper.sendMail(context, user, file); |
136 |
137 |
}catch(Exception ex){
|
138 |
139 |
ex.printStackTrace(); |
140 |
141 |
} |
142 |
143 |
File newFile = new File(file);
|
144 |
145 |
try {
|
146 |
147 |
newFile.createNewFile(); |
148 |
149 |
} catch (IOException e) {
|
150 |
151 |
e.printStackTrace(); |
152 |
153 |
} |
154 |
155 |
} |
156 |
157 |
mLogDumper.setLogFileLock(false);
|
158 |
159 |
} |
160 |
161 |
} |
162 |
163 |
private class LogDumper extends Thread{
|
164 |
165 |
String fileName; |
166 |
167 |
private Process logcatProc;
|
168 |
169 |
private BufferedReader mReader = null;
|
170 |
171 |
private boolean mRunning = false;
|
172 |
173 |
String cmds=null;
|
174 |
175 |
private final String mPID;
|
176 |
177 |
private FileOutputStream out = null;
|
178 |
179 |
private List<String> logsMessage = new ArrayList<String>();
|
180 |
181 |
private boolean mLogFileLock = false;
|
182 |
183 |
private String logFileName;
|
184 |
185 |
public void setLogFileLock(boolean lock){
|
186 |
187 |
mLogFileLock = lock; |
188 |
189 |
} |
190 |
191 |
public boolean isLogFileLock()
|
192 |
193 |
{ |
194 |
195 |
return mLogFileLock;
|
196 |
197 |
} |
198 |
199 |
public LogDumper(String pid,String file) {
|
200 |
201 |
mPID = String.valueOf(pid); |
202 |
203 |
fileName = file; |
204 |
205 |
File mFile = new File(fileName,"error.txt");
|
206 |
207 |
if(!mFile.exists()){
|
208 |
209 |
try {
|
210 |
211 |
mFile.createNewFile(); |
212 |
213 |
} catch (IOException e) {
|
214 |
215 |
e.printStackTrace(); |
216 |
217 |
} |
218 |
219 |
} |
220 |
221 |
try {
|
222 |
223 |
logFileName = mFile.toString(); |
224 |
225 |
out = new FileOutputStream(mFile,true);
|
226 |
227 |
} catch (FileNotFoundException e) {
|
228 |
229 |
e.printStackTrace(); |
230 |
231 |
} |
232 |
233 |
/** |
234 |
235 |
* 日志等级:*:v , *:d , *:w , *:e , *:f , *:s |
236 |
237 |
* 显示当前mPID程序的 E和W等级的日志. |
238 |
239 |
* */ |
240 |
241 |
cmds ="logcat *:e *:w | grep \"("+mPID+")\"";
|
242 |
243 |
} |
244 |
245 |
public String getLogFileName()
|
246 |
247 |
{ |
248 |
249 |
return logFileName;
|
250 |
251 |
} |
252 |
253 |
public void stopLogs() {
|
254 |
255 |
mRunning = false;
|
256 |
257 |
} |
258 |
259 |
private boolean checkFileMaxSize(String file){
|
260 |
261 |
File sizefile = new File(file);
|
262 |
263 |
if(sizefile.exists()){
|
264 |
265 |
//1.5MB |
266 |
267 |
if(sizefile.length()>1572864){
|
268 |
269 |
return true;
|
270 |
271 |
} |
272 |
273 |
else {
|
274 |
275 |
return false;
|
276 |
277 |
} |
278 |
279 |
}else {
|
280 |
281 |
return false;
|
282 |
283 |
} |
284 |
285 |
} |
286 |
287 |
|
288 |
289 |
@Override |
290 |
291 |
public void run() {
|
292 |
293 |
System.out.println("LogCatHelper'");
|
294 |
295 |
mRunning = true;
|
296 |
297 |
try {
|
298 |
299 |
logcatProc = Runtime.getRuntime() |
300 |
301 |
.exec(cmds); |
302 |
303 |
|
304 |
305 |
mReader = new BufferedReader(new InputStreamReader(
|
306 |
307 |
logcatProc.getInputStream()), 1024);
|
308 |
309 |
String line = null;
|
310 |
311 |
while (mRunning && (line = mReader.readLine()) != null) {
|
312 |
313 |
if (!mRunning) {
|
314 |
315 |
break;
|
316 |
317 |
} |
318 |
319 |
if (line.length() == 0) {
|
320 |
321 |
continue;
|
322 |
323 |
} |
324 |
325 |
synchronized (out) {
|
326 |
327 |
if (out != null) {
|
328 |
329 |
boolean maxSize = checkFileMaxSize(getLogFileName());
|
330 |
331 |
if(maxSize){
|
332 |
333 |
//文件大小超过1.5mb |
334 |
335 |
sendLogMessage(mContext, DeviceHelper.getInstance(mContext).getImei()); |
336 |
337 |
} |
338 |
339 |
if (isLogFileLock()) {
|
340 |
341 |
if(line.contains(mPID)){
|
342 |
343 |
logsMessage.add(line.getBytes() + "\n");
|
344 |
345 |
} |
346 |
347 |
} else {
|
348 |
349 |
if(logsMessage.size()>0){
|
350 |
351 |
for(String _log:logsMessage){
|
352 |
353 |
out.write(_log.getBytes()); |
354 |
355 |
} |
356 |
357 |
logsMessage.clear(); |
358 |
359 |
} |
360 |
361 |
/** |
362 |
363 |
* 再次过滤日志,筛选当前日志中有 mPID 则是当前程序的日志. |
364 |
365 |
* */ |
366 |
367 |
if(line.contains(mPID)){
|
368 |
369 |
out.write(line.getBytes()); |
370 |
371 |
out.write("\n".getBytes());
|
372 |
373 |
} |
374 |
375 |
} |
376 |
377 |
} |
378 |
379 |
} |
380 |
381 |
|
382 |
383 |
} |
384 |
385 |
} catch (IOException e) {
|
386 |
387 |
e.printStackTrace(); |
388 |
389 |
return;
|
390 |
391 |
} finally {
|
392 |
393 |
if (logcatProc != null) {
|
394 |
395 |
logcatProc.destroy(); |
396 |
397 |
logcatProc = null;
|
398 |
399 |
} |
400 |
401 |
if (mReader != null) {
|
402 |
403 |
try {
|
404 |
405 |
mReader.close(); |
406 |
407 |
mReader = null;
|
408 |
409 |
} catch (IOException e) {
|
410 |
411 |
e.printStackTrace(); |
412 |
413 |
} |
414 |
415 |
} |
416 |
417 |
if(out!=null){
|
418 |
419 |
try {
|
420 |
421 |
out.close(); |
422 |
423 |
} catch (IOException e) {
|
424 |
425 |
e.printStackTrace(); |
426 |
427 |
} |
428 |
429 |
out = null;
|
430 |
431 |
} |
432 |
433 |
} |
434 |
435 |
} |
436 |
437 |
} |
438 |
439 |
|
440 |
441 |
} |