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) ;
|
}
|
}
|
}
|
}
|
|
}
|