logservice.doc_第1页
logservice.doc_第2页
logservice.doc_第3页
logservice.doc_第4页
logservice.doc_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

package com.study.service;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Calendar;import java.util.Comparator;import java.util.Date;import java.util.List;import android.app.AlarmManager;import android.app.PendingIntent;import android.app.Service;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Environment;import android.os.IBinder;import android.os.PowerManager;import android.os.PowerManager.WakeLock;import android.util.Log;/* * 日志服务,日志默认会存储在SDcar里如果没有SDcard会存储在内存中的安装目录下面。 * 1.本服务默认在SDcard中每天生成一个日志文件, * 2.如果有SDCard的话会将之前内存中的文件拷贝到SDCard中 * 3.如果没有SDCard,在安装目录下只保存当前在写日志 * 4.SDcard的装载卸载动作会在步骤2,3中切换 * 5.SDcard中的日志文件只保存7天 * author Administrator * */public class LogService extends Serviceprivate static final String TAG = LogService;private static final int MEMORY_LOG_FILE_MAX_SIZE = 10 * 1024 * 1024; / 内存中日志文件最大值,10Mprivate static final int MEMORY_LOG_FILE_MONITOR_INTERVAL = 10 * 60 * 1000; / 内存中的日志文件大小监控时间间隔,10分钟private static final int SDCARD_LOG_FILE_SAVE_DAYS = 7; / sd卡中日志文件的最多保存天数private String LOG_PATH_MEMORY_DIR; / 日志文件在内存中的路径(日志文件在安装目录中的路径)private String LOG_PATH_SDCARD_DIR; / 日志文件在sdcard中的路径SuppressWarnings(unused)private String LOG_SERVICE_LOG_PATH; / 本服务产生的日志,记录日志服务开启失败信息private final int SDCARD_TYPE = 0; / 当前的日志记录类型为存储在SD卡下面private final int MEMORY_TYPE = 1; / 当前的日志记录类型为存储在内存中private int CURR_LOG_TYPE = SDCARD_TYPE; / 当前的日志记录类型private String CURR_INSTALL_LOG_NAME; / 如果当前的日志写在内存中,记录当前的日志文件名称private String logServiceLogName = Log.log;/ 本服务输出的日志文件名称private SimpleDateFormat myLogSdf = new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);private OutputStreamWriter writer;private SimpleDateFormat sdf = new SimpleDateFormat(yyyy-MM-dd HHmmss);/ 日志名称格式private Process process;private WakeLock wakeLock;private SDStateMonitorReceiver sdStateReceiver; / SDcard状态监测private LogTaskReceiver logTaskReceiver;/* * 是否正在监测日志文件大小; 如果当前日志记录在SDcard中则为false 如果当前日志记录在内存中则为true */private boolean logSizeMoniting = false;private static String MONITOR_LOG_SIZE_ACTION = com.walktour.gui.MONITOR_LOG_SIZE; / 日志文件监测actionprivate static String SWITCH_LOG_FILE_ACTION = com.walktour.gui.SWITCH_LOG_FILE_ACTION; / 切换日志文件actionOverridepublic IBinder onBind(Intent intent)return null;Overridepublic void onCreate()super.onCreate();init();register();deploySwitchLogFileTask();new LogCollectorThread().start();private void init()LOG_PATH_MEMORY_DIR = getFilesDir().getAbsolutePath() + File.separator+ log;LOG_SERVICE_LOG_PATH = LOG_PATH_MEMORY_DIR + File.separator+ logServiceLogName;LOG_PATH_SDCARD_DIR = Environment.getExternalStorageDirectory().getAbsolutePath()+ File.separator+ walktour+ File.separator + log;createLogDir();/* * * try writer = new OutputStreamWriter(new FileOutputStream( * LOG_SERVICE_LOG_PATH, true); catch (FileNotFoundException e) * Log.e(TAG, e.getMessage(), e); * * */PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);CURR_LOG_TYPE = getCurrLogType();Log.i(TAG, LogService onCreate);private void register()IntentFilter sdCarMonitorFilter = new IntentFilter();sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);sdCarMonitorFilter.addDataScheme(file);sdStateReceiver = new SDStateMonitorReceiver();registerReceiver(sdStateReceiver, sdCarMonitorFilter);IntentFilter logTaskFilter = new IntentFilter();logTaskFilter.addAction(MONITOR_LOG_SIZE_ACTION);logTaskFilter.addAction(SWITCH_LOG_FILE_ACTION);logTaskReceiver = new LogTaskReceiver();registerReceiver(logTaskReceiver, logTaskFilter);/* * 获取当前应存储在内存中还是存储在SDCard中 * * return */public int getCurrLogType()if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)return MEMORY_TYPE;elsereturn SDCARD_TYPE;/* * 部署日志切换任务,每天凌晨切换日志文件 */private void deploySwitchLogFileTask()Intent intent = new Intent(SWITCH_LOG_FILE_ACTION);PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);Calendar calendar = Calendar.getInstance();calendar.add(Calendar.DAY_OF_MONTH, 1);calendar.set(Calendar.HOUR_OF_DAY, 0);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);/ 部署任务AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY, sender);recordLogServiceLog(deployNextTask succ,next task time is:+ myLogSdf.format(calendar.getTime();/* * 日志收集 1.清除日志缓存 2.杀死应用程序已开启的Logcat进程防止多个进程写入一个日志文件 3.开启日志收集进程 4.处理日志文件 移动 * OR 删除 */class LogCollectorThread extends Threadpublic LogCollectorThread()super(LogCollectorThread);Log.d(TAG, LogCollectorThread is create);Overridepublic void run()trywakeLock.acquire(); / 唤醒手机clearLogCache();List orgProcessList = getAllProcess();List processInfoList = getProcessInfoList(orgProcessList);killLogcatProc(processInfoList);createLogCollector();Thread.sleep(1000);/ 休眠,创建文件,然后处理文件,不然该文件还没创建,会影响文件删除handleLog();wakeLock.release(); / 释放catch (Exception e)e.printStackTrace();recordLogServiceLog(Log.getStackTraceString(e);/* * 每次记录日志之前先清除日志的缓存, 不然会在两个日志文件中记录重复的日志 */private void clearLogCache()Process proc = null;List commandList = new ArrayList();commandList.add(logcat);commandList.add(-c);tryproc = Runtime.getRuntime().exec(commandList.toArray(new StringcommandList.size();StreamConsumer errorGobbler = new StreamConsumer(proc.getErrorStream();StreamConsumer outputGobbler = new StreamConsumer(proc.getInputStream();errorGobbler.start();outputGobbler.start();if (proc.waitFor() != 0)Log.e(TAG, clearLogCache proc.waitFor() != 0);recordLogServiceLog(clearLogCache clearLogCache proc.waitFor() != 0);catch (Exception e)Log.e(TAG, clearLogCache failed, e);recordLogServiceLog(clearLogCache failed);finallytryproc.destroy();catch (Exception e)Log.e(TAG, clearLogCache failed, e);recordLogServiceLog(clearLogCache failed);/* * 关闭由本程序开启的logcat进程: 根据用户名称杀死进程(如果是本程序进程开启的Logcat收集进程那么两者的USER一致) * 如果不关闭会有多个进程读取logcat日志缓存信息写入日志文件 * * param allProcList * return */private void killLogcatProc(List allProcList)if (process != null)process.destroy();String packName = this.getPackageName();String myUser = getAppUser(packName, allProcList);/* * recordLogServiceLog(app user is:+myUser); * recordLogServiceLog(=); for (ProcessInfo * processInfo : allProcList) * recordLogServiceLog(processInfo.toString(); * recordLogServiceLog(=); */for (ProcessInfo processInfo : allProcList)if (processI.toLowerCase().equals(logcat)& processInfo.user.equals(myUser)android.os.Process.killProcess(Integer.parseInt(processInfo.pid);/ recordLogServiceLog(kill another logcat process success,the process info is:/ + processInfo);/* * 获取本程序的用户名称 * * param packName * param allProcList * return */private String getAppUser(String packName, List allProcList)for (ProcessInfo processInfo : allProcList)if (processI.equals(packName)return processInfo.user;return null;/* * 根据ps命令得到的内容获取PID,User,name等信息 * * param orgProcessList * return */private List getProcessInfoList(List orgProcessList)List procInfoList = new ArrayList();for (int i = 1; i orgProcessList.size(); i+)String processInfo = orgProcessList.get(i);String proStr = processInfo.split( );/ USER PID PPID VSIZE RSS WCHAN PC NAME/ root 1 0 416 300 c00d4b28 0000cd5c S /initList orgInfo = new ArrayList();for (String str : proStr)if (!.equals(str)orgInfo.add(str);if (orgInfo.size() = 9)ProcessInfo pInfo = new ProcessInfo();pInfo.user = orgInfo.get(0);pInfo.pid = orgInfo.get(1);pInfo.ppid = orgInfo.get(2);pI = orgInfo.get(8);procInfoList.add(pInfo);return procInfoList;/* * 运行PS命令得到进程信息 * * return USER PID PPID VSIZE RSS WCHAN PC NAME root 1 0 416 300 c00d4b28 * 0000cd5c S /init */private List getAllProcess()List orgProcList = new ArrayList();Process proc = null;tryproc = Runtime.getRuntime().exec(ps);StreamConsumer errorConsumer = new StreamConsumer(proc.getErrorStream();StreamConsumer outputConsumer = new StreamConsumer(proc.getInputStream(), orgProcList);errorConsumer.start();outputConsumer.start();if (proc.waitFor() != 0)Log.e(TAG, getAllProcess proc.waitFor() != 0);recordLogServiceLog(getAllProcess proc.waitFor() != 0);catch (Exception e)Log.e(TAG, getAllProcess failed, e);recordLogServiceLog(getAllProcess failed);finallytryproc.destroy();catch (Exception e)Log.e(TAG, getAllProcess failed, e);recordLogServiceLog(getAllProcess failed);return orgProcList;/* * 开始收集日志信息 */public void createLogCollector()String logFileName = sdf.format(new Date() + .log;/ 日志文件名称List commandList = new ArrayList();commandList.add(logcat);commandList.add(-f);/ commandList.add(LOG_PATH_INSTALL_DIR + File.separator + logFileName);commandList.add(getLogPath();commandList.add(-v);commandList.add(time);commandList.add(*:I);/ commandList.add(*:E);/ 过滤所有的错误信息/ 过滤指定TAG的信息/ commandList.add(MyAPP:V);/ commandList.add(*:S);tryprocess = Runtime.getRuntime().exec(commandList.toArray(new StringcommandList.size();recordLogServiceLog(start collecting the log,and log name is:+ logFileName);/ process.waitFor();catch (Exception e)Log.e(TAG, CollectorThread = + e.getMessage(), e);recordLogServiceLog(CollectorThread = + e.getMessage();/* * 根据当前的存储位置得到日志的绝对存储路径 * * return */public String getLogPath()createLogDir();String logFileName = sdf.format(new Date() + .log;/ 日志文件名称if (CURR_LOG_TYPE = MEMORY_TYPE)CURR_INSTALL_LOG_NAME = logFileName;Log.d(TAG, Log stored in memory, the path is:+ LOG_PATH_MEMORY_DIR + File.separator + logFileName);return LOG_PATH_MEMORY_DIR + File.separator + logFileName;elseCURR_INSTALL_LOG_NAME = null;Log.d(TAG, Log stored in SDcard, the path is:+ LOG_PATH_SDCARD_DIR + File.separator + logFileName);return LOG_PATH_SDCARD_DIR + File.separator + logFileName;/* * 处理日志文件 1.如果日志文件存储位置切换到内存中,删除除了正在写的日志文件 并且部署日志大小监控任务,控制日志大小不超过规定值 * 2.如果日志文件存储位置切换到SDCard中,删除7天之前的日志,移 动所有存储在内存中的日志到SDCard中,并将之前部署的日志大小 监控取消 */public void handleLog()if (CURR_LOG_TYPE = MEMORY_TYPE)deployLogSizeMonitorTask();deleteMemoryExpiredLog();elsemoveLogfile();cancelLogSizeMonitorTask();deleteSDcardExpiredLog();/* * 部署日志大小监控任务 */private void deployLogSizeMonitorTask()if (logSizeMoniting) / 如果当前正在监控着,则不需要继续部署return;logSizeMoniting = true;Intent intent = new Intent(MONITOR_LOG_SIZE_ACTION);PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),MEMORY_LOG_FILE_MONITOR_INTERVAL, sender);Log.d(TAG, deployLogSizeMonitorTask() succ !);/ recordLogServiceLog(deployLogSizeMonitorTask() succ ,start time is / + calendar.getTime().toLocaleString();/* * 取消部署日志大小监控任务 */private void cancelLogSizeMonitorTask()logSizeMoniting = false;AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);Intent intent = new Intent(MONITOR_LOG_SIZE_ACTION);PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);am.cancel(sender);Log.d(TAG, canelLogSizeMonitorTask() succ);/* * 检查日志文件大小是否超过了规定大小 如果超过了重新开启一个日志收集进程 */private void checkLogSize()if (CURR_INSTALL_LOG_NAME != null & !.equals(CURR_INSTALL_LOG_NAME)String path = LOG_PATH_MEMORY_DIR + File.separator+ CURR_INSTALL_LOG_NAME;File file = new File(path);if (!file.exists()return;Log.d(TAG, checkLog() = The size of the log is too big?);if (file.length() = MEMORY_LOG_FILE_MAX_SIZE)Log.d(TAG, The logs size is too big!);new LogCollectorThread().start();/* * 创建日志目录 */private void createLogDir()File file = new File(LOG_PATH_MEMORY_DIR);boolean mkOk;if (!file.isDirectory()mkOk = file.mkdirs();if (!mkOk)mkOk = file.mkdirs();/* * * file = new File(LOG_SERVICE_LOG_PATH); if (!file.exists() try * mkOk = file.createNewFile(); if (!mkOk) file.createNewFile(); * catch (IOException e) Log.e(TAG, e.getMessage(), e); * * */if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)file = new File(LOG_PATH_SDCARD_DIR);if (!file.isDirectory()mkOk = file.mkdirs();if (!mkOk)recordLogServiceLog(move file failed,dir is not created succ);return;/* * 将日志文件转移到SD卡下面 */private void moveLogfile()if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)/ recordLogServiceLog(move file failed, sd card does not mount);return;File file = new File(LOG_PATH_SDCARD_DIR);if (!file.isDirectory()boolean mkOk = file.mkdirs();if (!mkOk)/ recordLogServiceLog(move file failed,dir is not created succ);return;file = new File(LOG_PATH_MEMORY_DIR);if (file.isDirectory()File allFiles = file.listFiles();for (File logFile : allFiles)String fileName = logFile.getName();if (logServiceLogName.equals(fileName)continue;/ String createDateInfo =/ getFileNameWithoutExtension(fileName);boolean isSucc = copy(logFile, new File(LOG_PATH_SDCARD_DIR+ File.separator + fileName);if (isSucc)logFile.delete();/ recordLogServiceLog(move file success,log name is:+fileName);/* * 删除内存下过期的日志 */private void deleteSDcardExpiredLog()File file = new File(LOG_PATH_SDCARD_DIR);if (file.isDirectory()File allFiles = file.listFiles();for (File logFile : allFiles)String fileName = logFile.getName();if (logServiceLogName.equals(fileName)continue;String createDateInfo = getFileNameWithoutExtension(fileName);if (canDeleteSDLog(createDateInfo)logFile.delete();Log.d(TAG, delete expired log success,the log path is:+ logFile.getAbsolutePath();/* * 判断sdcard上的日志文件是否可以删除 * * param createDateStr * return */public boolean canDeleteSDLog(String createDateStr)boolean canDel = false;Calendar calendar = Calendar.getInstance();calendar.add(Calendar.DAY_OF_MONTH, -1 * SDCARD_LOG_FILE_SAVE_DAYS);/ 删除7天之前日志Date expiredDate = calendar.getTime();tryDate createDate = sdf.parse(createDateStr);canDel = createDate.before(expiredDate);catch (ParseException e)Log.e(TAG, e.getMessage(), e);canDel = false;return canDel;/* * 删除内存中的过期日志,删除规则: 除了当前的日志和离当前时间最近的日志保存其他的都删除 */private void deleteMemoryExpiredLog()File file = new File(LOG_PATH_MEMORY_DIR);if (file.isDirectory()File all

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论