package com.dy.rtuMw.resource.rtuLog; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import com.dy.rtuMw.resource.ResourceUnit; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.dy.common.util.DateTime; import com.dy.common.queue.Queue; import com.dy.common.threadPool.ThreadPool; import com.dy.common.threadPool.TreadPoolFactory; public class RtuLogManager { private static final Logger log = LogManager.getLogger(RtuLogManager.class) ; private static final RtuLogManager instance = new RtuLogManager() ; private static final Queue logQueue = new Queue("rtuLogQueue") ; private static final Integer maxNodeAddWorkThread = 500 ;//缓存达到这个数量,将增加线程 private static final Integer maxWorkThread = 5 ;//最大工作线程数 private static final Object maxWorkThreadSynObj = new Object() ;//最大工作线程数 private static int workThread = 0 ;//工作线程数 private RtuLogManager(){ } @SuppressWarnings("unused") public static RtuLogManager getInstance(){ return instance ; } /** * 设置队列限制 * @param warnSize 队列节点数量 报警值 * @param maxSize 队列节点数量 最大值 */ @SuppressWarnings("unused") public void setQueueLimit(int warnSize, int maxSize){ logQueue.setLimit(warnSize, maxSize); } /** * 加入Rtu日志数据 * 在单线程中执行 * @param logNodeObj 日志队列节点对象 * @throws Exception 异常 */ public void pushRtuLog(RtuLogNode logNodeObj) throws Exception{ logQueue.pushTail(logNodeObj); //在单线程中执行 if(workThread <= 0){ startWorkThread() ; } } /** * 启动工作线程工作 */ private void startWorkThread(){ workThread ++ ; try { TreadPoolFactory.getThreadPoolShort().putJob(new ThreadPool.Job() { public void execute() { while(logQueue.size() > 0){ RtuLogNode node ; if(workThread > 1){ synchronized(logQueue){ node = (RtuLogNode)logQueue.pop() ; } }else{ node = (RtuLogNode)logQueue.pop() ; } if(node != null){ //日志文件存储 log(node.rtuAddr, node.content) ; } if(RtuLogManager.logQueue.size() > maxNodeAddWorkThread){ if(workThread < maxWorkThread){ synchronized(maxWorkThreadSynObj){ if(workThread < maxWorkThread){ startWorkThread() ; } } } } } workThread -- ; if(workThread < 0){ workThread = 0 ; } } /* * 强制停止execute方法中执行的死循环工作 */ @Override public void destroy() { //再将启动,防止无线程处理了 startWorkThread() ; } /** * execute方法中调用此方法判断是否结束死循环工作 */ @Override public boolean isDestroy() { return false; } }) ; }catch(Exception e){ log.error(e); workThread -- ; if(workThread < 0){ workThread = 0 ; } } } /** * 记录Rtu日志 * @param rtuAddr 控制器地址 * @param conent 日志内容 */ private void log(String rtuAddr , String conent){ File f = getFileForWrite(ResourceUnit.confVo.rtuLogDir , rtuAddr.trim()) ; if(f != null){ writeLog(f , DateTime.yyyy_MM_dd_HH_mm_ss() + " " + conent) ; }else{ log.error("不能得到地址为:" + rtuAddr + "的Rtu日志文件!") ; } } /** * 得到日志文件 * @param path 文件路径 * @param rtuAddr 控制器地址 * @return 日志文件 */ private File getFileForWrite(String path , String rtuAddr) { File dir = new File(path) ; if(!dir.exists()){ if(!dir.mkdirs()){ return null ; } } File f = new File(path + rtuAddr + ".log"); FileInputStream in = null; try { if (f.exists()) { in = new FileInputStream(f); if(in.available() >= ResourceUnit.confVo.rtuLogFileMaxSize){ in.close() ;//必须加上此语句 File oldestLog = new File(path + rtuAddr + ".log." + (ResourceUnit.confVo.rtuLogFileMaxCount - 1)) ; if(oldestLog.exists()){ if(!oldestLog.delete()){ return null ; } } for(int i = (ResourceUnit.confVo.rtuLogFileMaxCount - 2) ; i > 0 ; i--){ File oldLog = new File(path + rtuAddr + ".log." + i) ; if(oldLog.exists()){ if(!oldLog.renameTo(new File(path + rtuAddr + ".log." + (i + 1)))){ return null ; } if(!oldLog.delete()){ return null ; } } } if(!f.renameTo(new File(path + rtuAddr + ".log." + 1))){ return null ; } if(!f.delete()){ return null ; } f = new File(path + rtuAddr + ".log"); if(!f.exists()){ if(f.createNewFile()){ return f ; }else{ return null ; } } }else{ return f ; } }else{ if(f.createNewFile()){ return f ; }else{ return null ; } } } catch (Exception e) { log.error("得到Rtu(" + rtuAddr + ")日志文件时出错" , e) ; }finally{ try { if (in != null) { in.close(); } } catch (IOException e) { log.error("关闭Rtu日志文件(" + f.getName() + ")读入流时出错" , e) ; } } return null; } /** * 向文件中写入日志 * @param f 文件 * @param conent 日志内容 */ private void writeLog(File f, String conent) { if (f.exists()) { BufferedWriter out = null; try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f, true))); // 参数为true,表示追加内容 out.write(conent + "\n"); } catch (Exception e) { log.error("写入Rtu日志文件(" + f.getName() + ")时出错" , e) ; } finally { try { if (out != null) { out.close(); } } catch (IOException e) { log.error("关闭Rtu日志文件(" + f.getName() + ")写出流时出错" , e) ; } } } } }