Java实时监控日志文件并输出的方法详解
前言
最近有一个银行数据漂白系统,要求操作人员在页面调用远端Linux服务器的shell,并将shell输出的信息保存到一个日志文件,前台页面要实时显示日志文件的内容.这个问题难点在于如何判断哪些数据是新增加的,通过查看JDK的帮助文档,
java.io.RandomAccessFile可以解决这个问题.为了模拟这个问题,编写LogSvr和LogView类,LogSvr不断向mock.log日志文件写数据,而LogView则实时输出日志变化部分的数据.
代码1:日志产生类
packagecom.bill99.seashell.domain.svr; importjava.io.File; importjava.io.FileWriter; importjava.io.IOException; importjava.io.Writer; importjava.text.SimpleDateFormat; importjava.util.Date; importjava.util.concurrent.Executors; importjava.util.concurrent.ScheduledExecutorService; importjava.util.concurrent.TimeUnit; /** *title:日志服务器
*Description:模拟日志服务器
*CopyRight:CopyRight(c)2010
*Company:99bill.com
*Createdate:2010-6-18
*@authorTankZhang*@versionv0.12010-6-18 */ publicclassLogSvr{ privateSimpleDateFormatdateFormat= newSimpleDateFormat("yyyy-MM-ddHH:mm:ss"); /** *将信息记录到日志文件 *@paramlogFile日志文件 *@parammesInfo信息 *@throwsIOException */ publicvoidlogMsg(FilelogFile,StringmesInfo)throwsIOException{ if(logFile==null){ thrownewIllegalStateException("logFilecannotbenull!"); } WritertxtWriter=newFileWriter(logFile,true); txtWriter.write(dateFormat.format(newDate())+"\t"+mesInfo+"\n"); txtWriter.flush(); } publicstaticvoidmain(String[]args)throwsException{ finalLogSvrlogSvr=newLogSvr(); finalFiletmpLogFile=newFile("mock.log"); if(!tmpLogFile.exists()){ tmpLogFile.createNewFile(); } //启动一个线程每5秒钟向日志文件写一次数据 ScheduledExecutorServiceexec= Executors.newScheduledThreadPool(1); exec.scheduleWithFixedDelay(newRunnable(){ publicvoidrun(){ try{ logSvr.logMsg(tmpLogFile,"99billtest!"); }catch(IOExceptione){ thrownewRuntimeException(e); } } },0,5,TimeUnit.SECONDS); } }
代码2:显示日志的类
packagecom.bill99.seashell.domain.client; importjava.io.File; importjava.io.IOException; importjava.io.RandomAccessFile; importjava.util.concurrent.Executors; importjava.util.concurrent.ScheduledExecutorService; importjava.util.concurrent.TimeUnit; publicclassLogView{ privatelonglastTimeFileSize=0;//上次文件大小 /** *实时输出日志信息 *@paramlogFile日志文件 *@throwsIOException */ publicvoidrealtimeShowLog(FilelogFile)throwsIOException{ //指定文件可读可写 finalRandomAccessFilerandomFile=newRandomAccessFile(logFile,"rw"); //启动一个线程每10秒钟读取新增的日志信息 ScheduledExecutorServiceexec= Executors.newScheduledThreadPool(1); exec.scheduleWithFixedDelay(newRunnable(){ publicvoidrun(){ try{ //获得变化部分的 randomFile.seek(lastTimeFileSize); Stringtmp=""; while((tmp=randomFile.readLine())!=null){ System.out.println(newString(tmp.getBytes("ISO8859-1"))); } lastTimeFileSize=randomFile.length(); }catch(IOExceptione){ thrownewRuntimeException(e); } } },0,1,TimeUnit.SECONDS); } publicstaticvoidmain(String[]args)throwsException{ LogViewview=newLogView(); finalFiletmpLogFile=newFile("mock.log"); view.realtimeShowLog(tmpLogFile); } }
执行LogSvr类,LogSvr类会启动一个线程,每5秒钟向mock.log日志文件写一次数据,然后再执行LogView类,LogView每隔1秒钟读一次,如果数据有变化则输出变化的部分.
结果输出:
2010-06-1917:25:5499billtest! 2010-06-1917:25:5999billtest! 2010-06-1917:26:0499billtest! 2010-06-1917:26:0999billtest! 2010-06-1917:26:1499billtest! 2010-06-1917:26:1999billtest!
PS:
代码修改过,有朋友下载了我的代码,说如果是中文会乱码,将日志输出类的第30行的代码 System.out.println(tmp)改成System.out.println(newString(tmp.getBytes("ISO8859-1"))),就会正常显示中文.
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。