package com.vci.server.framework.systemConfig.log; import java.io.File; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import org.apache.commons.lang3.StringUtils; import org.hibernate.Transaction; import com.vci.client.common.excel.SheetDataSet; import com.vci.common.log.ServerWithLog4j; import com.vci.common.resource.CommonProperties; import com.vci.corba.framework.data.UserInfo; import com.vci.server.base.persistence.dao.HibernateSessionFactory; import com.vci.server.framework.delegate.RightManagementDelegate; public class LogAutoControlUtil { private Timer timer = null; private TimerTask timerTask = null; private final String AUTO_DELETE_RATE = "log.autoDelete.rate";//自动删除执行频率 private final String AUTO_DELETE_TIME = "log.autoDelete.time";//每天启动自动任务的时间 private final String LOG_SAVE_PERIOD = "logSavePeriod";//日志保存期限 private final String AUTO_DELETE_BACK_PATH = "log.autoDelete.backPath";//备份的文件夹 private Calendar cal = Calendar.getInstance(); private long period = 24*60*60*1000;//执行周期,配置文件里配置,这里初始化为1天 private static LogAutoControlUtil instance = null; public synchronized static LogAutoControlUtil getInstance(){ if(instance == null){ instance = new LogAutoControlUtil(); } return instance; } /** * 自动任务的入口 */ public void startLogDeleteMonitoring(){ timer = new Timer(); timerTask = new TimerTask(){ @Override public void run() { autoDeleteTask();//执行自动删除 } }; period = this.getPeriod() == 0 ? period : this.getPeriod();//如果无配置,则使用默认值 int year = cal.get(Calendar.YEAR);//年 int month = cal.get(Calendar.MONTH);//月 int day = cal.get(Calendar.DAY_OF_MONTH);//日 int times[] = this.getTimeOfDay();//时分秒为手动配置的 int hour = times[0];//时 int minute = times[1];//分 int seconds = times[2];//秒 Calendar calendar = new GregorianCalendar(year,month,day,hour,minute,seconds); timer.scheduleAtFixedRate(timerTask, calendar.getTime(), period); } /** * 获取用户配置的执行起始时间 * @return */ private int[] getTimeOfDay(){ String times = ""; int time[] = new int[3]; times = CommonProperties.getStringProperty(AUTO_DELETE_TIME); String temp[] = times.split("::"); if(temp.length >=3){ time[0] = Integer.parseInt(temp[0]); time[1] = Integer.parseInt(temp[1]); time[2] = Integer.parseInt(temp[2]); } return time; } /** * 取得配置的自动任务执行周期 * @return */ private long getPeriod(){ String days = ""; long res = 0; days = CommonProperties.getStringProperty(AUTO_DELETE_RATE); if(!days.equals("")&&days != null){ res = Long.valueOf(days); } return res*24*60*60*1000;//转化成毫秒 } /** * 自动任务执行的核心方法 */ private void autoDeleteTask(){ ServerWithLog4j.logger.info("日志删除自动任务启动..................."); LogService logSrv = new LogService(); int curPeriod = logSrv.getCurPeriod(LOG_SAVE_PERIOD);//获取当前设置期限 if(curPeriod<1){ return ; } StringBuffer whereSql = new StringBuffer(); boolean flag = false; whereSql.append(" trunc(PLDATE) < add_months(trunc(sysdate),"+(-curPeriod)+")"); //导出excel //先查询出来的数据 List logList = logSrv.getLogListBySql(whereSql.toString()); long logCount = logList.size();//查找出超出期限的日志 ServerWithLog4j.logger.info("需要删除的日志条数为:"+logCount); List> logCollection = switchListForOracleIn(logList,60000); String excelFilePrefix = "自动备份日志" + (new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); if(logCount != 0){ for(int i = 0 ; i < logCollection.size() ; i++){ List logs = logCollection.get(i); try{ writeLog2Excel(logs,excelFilePrefix,i); }catch(Exception e){ e.printStackTrace(); ServerWithLog4j.logger.error("备份日志文件出错",e); } } Transaction t = HibernateSessionFactory.getSession().beginTransaction(); String sql = "delete from pllog where pltype<>'删除日志' and "+whereSql.toString(); flag = logSrv.deleteLogBySql(sql, curPeriod); t.commit(); ServerWithLog4j.logger.info("删除日志"+(flag == true?"成功!":"失败!")); } ServerWithLog4j.logger.info("日志删除自动任务退出..................."); } private void writeLog2Excel(List logs,String excelFilePrefix,int sub) throws Exception{ String excel = excelFilePrefix + "_" + sub + ".xls"; //转换为二维数组 List lstData = new ArrayList(); String[][] data = new String[logs.size()+1][8]; //data[0] = new String[]{"用户名","姓名","用户IP","模块","操作","时间","操作结果","描述"}; lstData.add(new String[]{"用户名","姓名","用户IP","模块","操作","时间","操作结果","描述"}); //需要查询用户的信息 List userIdList = new ArrayList(); for(Log log : logs){ String userName = log.getUsername(); if(!userIdList.contains(userName)){ userIdList.add(userName); } }; List> userIdCollection = switchListForOracleIn(userIdList,500); Map userInfoMap = new HashMap(); for(List userIds :userIdCollection ){ UserInfo[] userInfos = new RightManagementDelegate().fetchUserInfoByNames(userIds.toArray(new String[0])); if(userInfos.length > 0 ){ for(int i = 0 ; i < userInfos.length; i ++){ UserInfo user = userInfos[i]; userInfoMap.put(user.userName, user.trueName); } } } for(int i = 0 ; i < logs.size(); i++){ Log log = logs.get(i); String[] row = new String[8]; row[0] = log.getUsername(); row[1] = userInfoMap.containsKey(log.getUsername())?userInfoMap.get(log.getUsername()):""; row[2] = log.getUserIp(); row[3] = log.getModule(); row[4] = log.getType(); row[5] = date2Str(log.getDate(),"yyyy-MM-dd HH:mm:ss");//时间 String result = "操作成功"; String memo = log.getResult(); if(StringUtils.isNotBlank(memo)){ boolean hasResult =false; if(memo.startsWith("操作") && memo.length()>4){ result = memo.substring(0,4); hasResult = true; } if((memo.startsWith("登入") || memo.startsWith("登出"))&& memo.length()>4){ result = memo.substring(0,4); hasResult = true; } if(memo.length()>5 && hasResult){ memo = memo.substring(5); }else{ //memo = ""; } } row[6]=result;//结果 row[7]=memo;//描述 //data[i+1] = row; lstData.add(row); } //处理文件 String tempFolderPath = CommonProperties.getStringProperty(AUTO_DELETE_BACK_PATH); if(StringUtils.isBlank(tempFolderPath)){ tempFolderPath = this.getClass().getResource("/").getPath() + File.separator + "logsBack"; } File folder = new File(tempFolderPath); if(!folder.exists()){ folder.mkdirs(); } File excelFile = new File(tempFolderPath+ File.separator +excel); excelFile.createNewFile(); SheetDataSet ds = new SheetDataSet(); ds.setDataSet(lstData); ds.setSheet("日志备份"); //ExcelDocumentUtils.writeExcelDocument(excelFile.getPath(), "日志备份", ds); ServerWithLog4j.logger.info("导出" + logs.size() + "条日志到excel文件:" +excelFile.getAbsolutePath() ); } /** * 时间转换 * @param d * @param formate * @return */ private String date2Str(Date d,String formate){ SimpleDateFormat sdf = new SimpleDateFormat(formate); return sdf.format(d); } /** * oracle in 查询不能超过1000,转换一下集合 * 由于SQL语句1000个可能很长,超过oracle10g,所以牺牲性能分配为500个数组 * @param list 需要转换的列表内容 * @return 分组后的list */ private List> switchListForOracleIn(List list,int size) { List> listHasList = new ArrayList>(); if(list == null){ return listHasList; } List newList = new ArrayList(); for(Object obj : list){ //为了让list还可以添加内容,因为使用sublist后,list不能再Add了 newList.add((T)obj); } int muti = 1; if(newList.size() >size){ int balance = newList.size()%size; muti = (newList.size() - balance)/size + (balance == 0?0:1); } for(int i = 0 ; i < muti; i ++){ int start = i*size; int end = start + size; if(i == muti-1 || end >newList.size() ){ end = newList.size(); } List subList = newList.subList(start,end); listHasList.add(subList); } return listHasList; } public static void main(String[] args){ // Thread t1 = new Thread(){ // public void run(){ // LogAutoControlUtil.getInstance().startLogDeleteMonitoring(); // System.err.println("Thread1.........................."); // } // }; // // Thread t2 = new Thread(){ // Timer time = new Timer(); // public void run(){ // System.err.println("Thread2.........................."); // time.schedule(new TimerTask(){ // int i = 0; // @Override // public void run() { // System.err.println("i="+i++); // } // // }, 1000,1000); // } // }; // t1.start(); // t2.start(); } // }