鄙人正在做一个项目,该项目是负责采集网络设备信息的。
项目中有很多种采集任务,其中包括syslog的采集,syslog是通过telnet采集回来并与以前的采集生成的log文件比较,并进行追加。syslog采集一段时间后,cpu占用越来越高。
syslog采集任务 需要进行I/o操作,是n个设备在循环中依次执行这是Syslog任务类:里面收集设备信息,并调用 SyslogFetchingTask.run()进行syslog采集
public class SysLogBackUpTask extends Thread{
public static PropertiesHandle ph = PropertiesHandle.getPropertiesHandle("ziyuan.properties"); private DataUtil du;
public SysLogBackUpTask(){
du = DataUtil.getDataUtil(); start();
}
public void run(){
List<NetRoutInfo> routs = null;
String timeNum =ph.getProperty("syslogTaskTime");
timeNum = timeNum==null?"5":timeNum;
Long sleepTime = Long.valueOf(timeNum)*60*1000;//间隔时间 SyslogFetchingTask sft =new SyslogFetchingTask();//syslog采集并分析类
while(true){ routs = du.getAllRoutByStatus(0);
System.out.println(routs.size()+"台设备激活,并进行syslog备份");
for(NetRoutInfo rout:routs){
System.out.println("rout:::"+rout.getRoutName()+"的采集开始"); try{ sft.setRout(rout);
sft.run();
Thread.sleep(100);
}catch(Exception e){
System.out.println(rout.getRoutName()+" ");
e.printStackTrace();
continue;
}
}
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
routs.clear();
}
}
}
下面是SyslogFetchingTask.java是syslog采集任务的真正执行者
public class SyslogFetchingTask { private NetRoutInfo rout;
private String fileName;
private String fileContent="";
private HashMap<String,StringBuffer> needAppend;//用于保存每个log文件应追加的内容 key=log文件名
// value =每个文件应追加的内容
public SyslogFetchingTask(){
}
public void setRout(NetRoutInfo rout){//设置采集的目标设备
this.rout = rout;
if(this.needAppend!=null){
this.needAppend.clear();
}else{
this.needAppend = new HashMap<String,StringBuffer>();
}
} public void run(){
String cmd = getTheLogCommandOfRout();
String cmdValue=null;
char startFlag = getTheStatementStartFlag();
if(cmd!=null){
cmdValue =TelnetHelper.getTheValueOfCommandExed(rout,cmd);
}else {
return;
}
analyseValue(cmdValue,startFlag);//分析出有哪些内容应该添加
appendToFile();//添加到文件
}
private String getTheLogCommandOfRout(){
int fa =rout.getFactory();
switch(fa){
case 0: return "dis logbuffer";//华为
case 1: return "show log";//思科
}
return null;
}
private char getTheStatementStartFlag(){
int fa =rout.getFactory();
switch(fa){
case 0: return '%';//华为
case 1: return '*';//思科
}
return ' ';
}
/**
*
* 解析采集到的log数据
*
* @param cmdValue
* @param startFlag
*/
private void analyseValue(String cmdValue,char startFlag){
// System.out.println("cmdValue::"+cmdValue);
if(cmdValue==null)return;
Date date = new Date();
Date d = null;
boolean isAppend=false;
// boolean startRecord=false;
int startIndex=0;
String filename=null;
String[] strArr =cmdValue.split("\r\n");
int type=0;//规定log是哪种格式。 0-格式为:以 startflag开头(%),时间格式为 MMM d HH:mm:ss yyyy; 1-格式为每句中包含双startflag(即是%%),时间格式为MMM d yyyy HH:mm:ss
// ArrayList<String> content = new ArrayList<String>();
for(int i=0;i<strArr.length;i++){
if(strArr[i]==null||strArr[i].trim().length()==0){
continue;
}
if(strArr[i].trim().charAt(0)==startFlag){
startIndex = i;
type=0;
break;
}else if(strArr[i].trim().indexOf(startFlag+startFlag)!=-1){
startIndex = i;
type=1;
break;
}
}
String[] st = null;
String temp = null;
for(int i=strArr.length-1;i>=startIndex;i--){//判断是否有需要添加到log日志中的
if(strArr[i]!=null&&strArr[i].trim().length()<=0)continue;
if(strArr[i].trim().charAt(0)==startFlag){//如果采集的日志数据包含了startFlag
if(rout.getFactory()==0){
st =strArr[i].trim().split(" "+(date.getYear()+1900)+" ");
}else if(rout.getFactory()==1){
st =strArr[i].trim().split(": %");
}
if(st==null||st.length<=0)return;
temp = st[0].trim();
temp = temp.substring(1);//去掉startFlag
if(rout.getFactory()==0){
d = DateUtil.getDateFromFormatString(temp, "MMM d HH:mm:ss", "en");
}else if(rout.getFactory()==1){
d = DateUtil.getDateFromFormatString(temp, "MMM d HH:mm:ss.SSS", "en");
}
filename =getFileName(d);
if(this.fileName==null||!this.fileName.equals(filename)){//如果刚开始解析或不存在这个log文件
this.fileContent = getFileContent(filename);
setFileName(filename);
if(needAppend.get(filename)==null){//如果 文件名与应追加内容 映射map中 不存在该文件名,则新建映射
needAppend.put(filename, new StringBuffer());
}
}
// System.out.println("fileContent:::"+fileContent);
// System.out.println(" this.fileContent.indexOf(strArr[i].trim()):::"+ this.fileContent.indexOf(strArr[i].trim()));
if(this.fileContent!=null&&this.fileContent.indexOf(strArr[i].trim())!=-1){
isAppend = false;
continue;//如果已经存在该语句,则不追加
}
this.needAppend.get(filename).append(strArr[i].trim());
this.needAppend.get(filename).append("\r\n");
// this.fileContent=this.fileContent+strArr[i].trim()+"\r\n";
isAppend = true;
}else{//如果该句中不带有 时间标志,则追加到上次时间中
if(this.fileName==null){//则说明刚开始解析该logbuffer,而且是logbuffer中无用的信息,则省略掉
continue;
}else{//说明是logbuffer 中有用的信息,但并不以时间标志开始,则将其追加到上次时间标志对应的文件
//因为log的规律是首先出现日期,再出现log内容
this.fileContent = getFileContent(this.fileName);
if(needAppend.get(this.fileName)==null){//如果 文件名与应追加内容 映射map中 不存在该文件名,则新建映射
needAppend.put(this.fileName, new StringBuffer());
}
if(isAppend){//如果上个带有时间标志的追加了,则追加 this.needAppend.get(this.fileName).append(strArr[i].trim());
this.needAppend.get(this.fileName).append("\r\n");
// this.fileContent=this.fileContent+strArr[i].trim()+"\r\n";
}
}
}
}
strArr = null;
cmdValue = null;
this.fileName = null;
this.fileContent = null;
}
/**
*
* 更新syslog文件的内容
*
*/
private void appendToFile(){
Set<String> names =this.needAppend.keySet();
for(String name:names){
// System.out.println("name append::"+needAppend.get(name).toString());
FileUtil.appendFileContent(name, needAppend.get(name).toString());
}
this.needAppend.clear();
this.needAppend = null;
}
/**
*
* 返回文件名称
*
* @param date
* @return
*/
private String getFileName(Date date){
String path =PropertiesHandle.getResuouceInfo("SysLogDir");
String deviceName = rout.getRoutName();
path = path+deviceName+System.getProperty("file.separator");
FileUtil.createFolder(path);
String timeStr =DateUtil.getTimeStrInFormat(date, "MM月");
String fileName = path+"log-"+deviceName+"-"+timeStr+".log";
return fileName;
}
/**
* @param file
* @return
*/
private String getFileContent(String file){
if(file!=null&&this.fileName!=null&&file.equals(this.fileName))return this.fileContent;
StringBuffer sb = new StringBuffer("");
FileReader fr = null;
try {
fr = new FileReader(file);
int ch =fr.read();
while(ch!=-1){
sb.append((char)ch);
ch = fr.read();
}
fr.close();
fr = null;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
return sb.toString();
// e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(fr!=null){
try {
fr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
fr = null;
}
}
return sb.toString();
} public String getFileName() {
return fileName;
} public void setFileName(String fileName) {
this.fileName = fileName;
}
}
大家帮我看看是什么原因造成CPU占用率过高的,在下在此谢过了
项目中有很多种采集任务,其中包括syslog的采集,syslog是通过telnet采集回来并与以前的采集生成的log文件比较,并进行追加。syslog采集一段时间后,cpu占用越来越高。
syslog采集任务 需要进行I/o操作,是n个设备在循环中依次执行这是Syslog任务类:里面收集设备信息,并调用 SyslogFetchingTask.run()进行syslog采集
public class SysLogBackUpTask extends Thread{
public static PropertiesHandle ph = PropertiesHandle.getPropertiesHandle("ziyuan.properties"); private DataUtil du;
public SysLogBackUpTask(){
du = DataUtil.getDataUtil(); start();
}
public void run(){
List<NetRoutInfo> routs = null;
String timeNum =ph.getProperty("syslogTaskTime");
timeNum = timeNum==null?"5":timeNum;
Long sleepTime = Long.valueOf(timeNum)*60*1000;//间隔时间 SyslogFetchingTask sft =new SyslogFetchingTask();//syslog采集并分析类
while(true){ routs = du.getAllRoutByStatus(0);
System.out.println(routs.size()+"台设备激活,并进行syslog备份");
for(NetRoutInfo rout:routs){
System.out.println("rout:::"+rout.getRoutName()+"的采集开始"); try{ sft.setRout(rout);
sft.run();
Thread.sleep(100);
}catch(Exception e){
System.out.println(rout.getRoutName()+" ");
e.printStackTrace();
continue;
}
}
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
routs.clear();
}
}
}
下面是SyslogFetchingTask.java是syslog采集任务的真正执行者
public class SyslogFetchingTask { private NetRoutInfo rout;
private String fileName;
private String fileContent="";
private HashMap<String,StringBuffer> needAppend;//用于保存每个log文件应追加的内容 key=log文件名
// value =每个文件应追加的内容
public SyslogFetchingTask(){
}
public void setRout(NetRoutInfo rout){//设置采集的目标设备
this.rout = rout;
if(this.needAppend!=null){
this.needAppend.clear();
}else{
this.needAppend = new HashMap<String,StringBuffer>();
}
} public void run(){
String cmd = getTheLogCommandOfRout();
String cmdValue=null;
char startFlag = getTheStatementStartFlag();
if(cmd!=null){
cmdValue =TelnetHelper.getTheValueOfCommandExed(rout,cmd);
}else {
return;
}
analyseValue(cmdValue,startFlag);//分析出有哪些内容应该添加
appendToFile();//添加到文件
}
private String getTheLogCommandOfRout(){
int fa =rout.getFactory();
switch(fa){
case 0: return "dis logbuffer";//华为
case 1: return "show log";//思科
}
return null;
}
private char getTheStatementStartFlag(){
int fa =rout.getFactory();
switch(fa){
case 0: return '%';//华为
case 1: return '*';//思科
}
return ' ';
}
/**
*
* 解析采集到的log数据
*
* @param cmdValue
* @param startFlag
*/
private void analyseValue(String cmdValue,char startFlag){
// System.out.println("cmdValue::"+cmdValue);
if(cmdValue==null)return;
Date date = new Date();
Date d = null;
boolean isAppend=false;
// boolean startRecord=false;
int startIndex=0;
String filename=null;
String[] strArr =cmdValue.split("\r\n");
int type=0;//规定log是哪种格式。 0-格式为:以 startflag开头(%),时间格式为 MMM d HH:mm:ss yyyy; 1-格式为每句中包含双startflag(即是%%),时间格式为MMM d yyyy HH:mm:ss
// ArrayList<String> content = new ArrayList<String>();
for(int i=0;i<strArr.length;i++){
if(strArr[i]==null||strArr[i].trim().length()==0){
continue;
}
if(strArr[i].trim().charAt(0)==startFlag){
startIndex = i;
type=0;
break;
}else if(strArr[i].trim().indexOf(startFlag+startFlag)!=-1){
startIndex = i;
type=1;
break;
}
}
String[] st = null;
String temp = null;
for(int i=strArr.length-1;i>=startIndex;i--){//判断是否有需要添加到log日志中的
if(strArr[i]!=null&&strArr[i].trim().length()<=0)continue;
if(strArr[i].trim().charAt(0)==startFlag){//如果采集的日志数据包含了startFlag
if(rout.getFactory()==0){
st =strArr[i].trim().split(" "+(date.getYear()+1900)+" ");
}else if(rout.getFactory()==1){
st =strArr[i].trim().split(": %");
}
if(st==null||st.length<=0)return;
temp = st[0].trim();
temp = temp.substring(1);//去掉startFlag
if(rout.getFactory()==0){
d = DateUtil.getDateFromFormatString(temp, "MMM d HH:mm:ss", "en");
}else if(rout.getFactory()==1){
d = DateUtil.getDateFromFormatString(temp, "MMM d HH:mm:ss.SSS", "en");
}
filename =getFileName(d);
if(this.fileName==null||!this.fileName.equals(filename)){//如果刚开始解析或不存在这个log文件
this.fileContent = getFileContent(filename);
setFileName(filename);
if(needAppend.get(filename)==null){//如果 文件名与应追加内容 映射map中 不存在该文件名,则新建映射
needAppend.put(filename, new StringBuffer());
}
}
// System.out.println("fileContent:::"+fileContent);
// System.out.println(" this.fileContent.indexOf(strArr[i].trim()):::"+ this.fileContent.indexOf(strArr[i].trim()));
if(this.fileContent!=null&&this.fileContent.indexOf(strArr[i].trim())!=-1){
isAppend = false;
continue;//如果已经存在该语句,则不追加
}
this.needAppend.get(filename).append(strArr[i].trim());
this.needAppend.get(filename).append("\r\n");
// this.fileContent=this.fileContent+strArr[i].trim()+"\r\n";
isAppend = true;
}else{//如果该句中不带有 时间标志,则追加到上次时间中
if(this.fileName==null){//则说明刚开始解析该logbuffer,而且是logbuffer中无用的信息,则省略掉
continue;
}else{//说明是logbuffer 中有用的信息,但并不以时间标志开始,则将其追加到上次时间标志对应的文件
//因为log的规律是首先出现日期,再出现log内容
this.fileContent = getFileContent(this.fileName);
if(needAppend.get(this.fileName)==null){//如果 文件名与应追加内容 映射map中 不存在该文件名,则新建映射
needAppend.put(this.fileName, new StringBuffer());
}
if(isAppend){//如果上个带有时间标志的追加了,则追加 this.needAppend.get(this.fileName).append(strArr[i].trim());
this.needAppend.get(this.fileName).append("\r\n");
// this.fileContent=this.fileContent+strArr[i].trim()+"\r\n";
}
}
}
}
strArr = null;
cmdValue = null;
this.fileName = null;
this.fileContent = null;
}
/**
*
* 更新syslog文件的内容
*
*/
private void appendToFile(){
Set<String> names =this.needAppend.keySet();
for(String name:names){
// System.out.println("name append::"+needAppend.get(name).toString());
FileUtil.appendFileContent(name, needAppend.get(name).toString());
}
this.needAppend.clear();
this.needAppend = null;
}
/**
*
* 返回文件名称
*
* @param date
* @return
*/
private String getFileName(Date date){
String path =PropertiesHandle.getResuouceInfo("SysLogDir");
String deviceName = rout.getRoutName();
path = path+deviceName+System.getProperty("file.separator");
FileUtil.createFolder(path);
String timeStr =DateUtil.getTimeStrInFormat(date, "MM月");
String fileName = path+"log-"+deviceName+"-"+timeStr+".log";
return fileName;
}
/**
* @param file
* @return
*/
private String getFileContent(String file){
if(file!=null&&this.fileName!=null&&file.equals(this.fileName))return this.fileContent;
StringBuffer sb = new StringBuffer("");
FileReader fr = null;
try {
fr = new FileReader(file);
int ch =fr.read();
while(ch!=-1){
sb.append((char)ch);
ch = fr.read();
}
fr.close();
fr = null;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
return sb.toString();
// e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(fr!=null){
try {
fr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
fr = null;
}
}
return sb.toString();
} public String getFileName() {
return fileName;
} public void setFileName(String fileName) {
this.fileName = fileName;
}
}
大家帮我看看是什么原因造成CPU占用率过高的,在下在此谢过了
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货