pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/resource/rtuLog/RtuLogManager.java
New file
@@ -0,0 +1,244 @@
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 content 日志内容
    */
   private void log(String rtuAddr , String content){
      Object[] res = getFileForWrite(ResourceUnit.confVo.rtuLogDir , rtuAddr.trim()) ;
      if(res[0] != null){
         writeLog((File)res[0] , DateTime.yyyy_MM_dd_HH_mm_ss() + "  " + content) ;
      }else{
         log.error("不能得到地址为:" + rtuAddr + "的Rtu日志文件!(信息编码" + res[1] + ")") ;
      }
   }
   /**
    * 得到日志文件
    * @param path 文件路径
    * @param rtuAddr 控制器地址
    * @return 日志文件
    */
   private Object[] getFileForWrite(String path , String rtuAddr) {
      File dir = new File(path) ;
      if(!dir.exists()){
         if(!dir.mkdirs()){
            return new Object[]{null, 1} ;
         }
      }
      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 new Object[]{null, 2} ;
                  }
               }
               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 new Object[]{null, 3} ;
                     }
                     if(!oldLog.delete()){
                        return new Object[]{null, 4} ;
                     }
                  }
               }
               if(!f.renameTo(new File(path + rtuAddr + ".log." + 1))){
                  return new Object[]{null, 5} ;
               }
               //2024-10-11 上面rename了,应该不用delete了
               //if(!f.delete()){
               //   return new Object[]{null, 6} ;
               //}
               f = new File(path + rtuAddr + ".log");
               if(!f.exists()){
                  if(f.createNewFile()){
                     return new Object[]{f, 7} ;
                  }else{
                     return new Object[]{null, 8} ;
                  }
               }
            }else{
               return new Object[]{f, 9} ;
            }
         }else{
            if(f.createNewFile()){
               return new Object[]{f, 10} ;
            }else{
               return new Object[]{null, 11} ;
            }
         }
      } 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 new Object[]{null, 12} ;
   }
   /**
    * 向文件中写入日志
    * @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) ;
            }
         }
      }
   }
}