设为首页 收藏本站
查看: 1560|回复: 0

[经验分享] Apache Pivot + Scala编写的一个小应用:日志分析

[复制链接]

尚未签到

发表于 2017-1-10 08:19:47 | 显示全部楼层 |阅读模式
package org.apache.pivot.scala.log
import scala.reflect.BeanProperty
import io.Source
import org.apache.pivot.wtk.content.ListViewItemRenderer
import java.lang.String
import org.apache.pivot.wtkx.{WTKX, WTKXSerializer}
/*为了避免和scala.Application的名称冲突,这里修改了别名*/
import org.apache.pivot.wtk.{ Application => PivotApplication, _}
import org.apache.pivot.collections.{ArrayList, Map}
/**
* Created by IntelliJ IDEA.
* User: Administrator
* Date: 2010-8-26
* Time: 10:36:45
* To change this template use File | Settings | File Templates.
*/
/*日志记录Bean对象,由于Scala标准生成的字段不使用getter/setter的格式,
但是提供了注解 @scala.reflect.BeanProperty ,使得编译器可以生成标准的JavaBean对象的getter/setter接口
val 只生成了getter
var 同时生成了getter和setter */
class LogRecord ( @BeanProperty val threadName : String,
@BeanProperty val date : String,
@BeanProperty val time : String,
@BeanProperty val module : String,
@BeanProperty val level : String,
@BeanProperty val content : String){
/*
重载了 Any的 toString接口
override关键字是必须的,在java中使用的是注解 @override,但是java中@override并不是必须的。
省略了 函数还回值,由编译器进行类型推演得到
*/
override def toString()  = {
threadName +" "+date +" "+ time +" "+module +" "+level+" "+content
}
}
/*
LogRecord 类的半生对象
定义了 scala中的魔术接口 apply ,使得可以使用  LogRecord("sting 文本") 可以创建一个class LogRecord对象。
apply方法的调用由编译器自动调用,我们只负责定义即可
我们要解析的日志格式
threadName date    time     module       Level   content
DVOSMAIN 08/26/10 10:17:17 LOGINFO     : INFO  - Debug level: 2
DVOSMAIN 08/26/10 10:17:17 LOGINFO     : INFO  - *=ERROR WARNING EXCEPT
DVOSMAIN 08/26/10 10:17:17 LOGINFO     : INFO  - LM=*
*/
object LogRecord {
def apply( line : String  ) : LogRecord = {
/*生成一个 Regex对象,用于模式匹配*/
val logRegex = """([A-Za-z0-9]+) +([0-9/]*) +([0-9:]*) +([A-Z]*) +: *([A-Z_]+).*""".r
line match {
/*如果模式匹配成功,threadName,date,time,module,level 分配按次序绑定到模式匹配表达式中()的内容 */
case logRegex(threadName,date,time,module,level) =>
val logRecord: LogRecord = new LogRecord( threadName, date, time, module, level,line)
logRecord
/*模式匹配通配符,在没有匹配到的情况下,做通用处理。如果不添加,在匹配不到时会抛出 MatchError异常*/
case _ =>
val logRecord: LogRecord = new LogRecord("N/A","N/A","N/A","N/A","N/A","N/A")
logRecord
}
}
}
/*
Apache Pivot ListView ItemRenderer
重新定义了如何显示 LogRecord对象的 列表项目的渲染。
如果使用默认的,那么ListView显示对象时,直接调用对象的toString获得其字符串表示
*/
class LogListViewItemRenderer extends ListViewItemRenderer {
imageView.setVisible(false)
override def render(item: AnyRef, index: Int, listView: ListView, selected: Boolean, checked: Boolean, highlighted: Boolean, disabled: Boolean) = {
if ( item != null && item.isInstanceOf[LogRecord])
{
val log = item.asInstanceOf[LogRecord]
label.setText(log.content)

}
}

}
/**
定义主窗口界面代码,必须继承自 org.apache.pivot.Application
使用了 @WTKX注解,该注解属于 wtkx的命名对象的绑定语法,在从wtkx文件加载GUI时,
调用bind接口可以自动和wtkx文件中声明的wtkx:id对象进行绑定,无需在掉吗中调用 get("name")
*/
class MainWindow extends PivotApplication {
var window : Window   = null
@WTKX var textInputFilePath : TextInput  = null
@WTKX var browsePushButton : PushButton  = null
@WTKX var loadPushButton : PushButton   = null
@WTKX var textInputThreadName :TextInput   = null
@WTKX var textInputModule : TextInput    = null
@WTKX var textInputLevel : TextInput    = null
@WTKX var textInputContent : TextInput   = null
@WTKX var logListView : ListView = null

def resume = {}
def suspend = {}
def shutdown(optional: Boolean) = {
if ( window != null)
{
window.close
true
}
false
}
def startup(display: Display, properties: Map[String, String]) = {
val wtkxSerializer = new WTKXSerializer()
var matchString : String = null
/*从xml(wtkx)文件加载GUI*/
window = wtkxSerializer.readObject(this,"MainWindow.xml").asInstanceOf[Window]
wtkxSerializer.bind(this)
if ( properties containsKey "logfile")
{
textInputFilePath setText ( properties get "logfile")
}
/*给 Button添加事件处理函数*/
browsePushButton.getButtonPressListeners.add( function2Listener (browseButtonPressed ) )
loadPushButton.getButtonPressListeners.add( function2Listener(loadButtonPressed ))

window.open(display)
}
/*浏览按钮事件处理,打开一个文件浏览窗口,让用户选择文件,并在用户关闭对话框时,捕获用户选择的文件名*/
def browseButtonPressed( button : Button ) : Unit = {
val dialog : FileBrowserSheet = new   FileBrowserSheet(FileBrowserSheet.Mode.OPEN)
dialog.open( window, new SheetCloseListener() {
def sheetClosed(sheet: Sheet) = {
if ( sheet.getResult)
{
val fileBrowseSheet = sheet.asInstanceOf[FileBrowserSheet]
textInputFilePath.setText( fileBrowseSheet.getSelectedFile.getPath.toString)
}
}
})
}
/*从log文件加载内容,每一行是一个日志记录
for中使用了 if过滤器,只有条件符合了,才会进入for循环体。
scala没有提供continu,而是在 for中提供了条件过滤来替代
*/
def loadButtonPressed( button : Button ) : Unit = {
val logFile = Source.fromFile(textInputFilePath.getText)
val list = new ArrayList[LogRecord]
for ( line <- logFile.getLines ; logRecord = LogRecord(line.trim);
if ( textInputThreadName.getText == "" || textInputThreadName.getText.contains(logRecord.threadName) );
if ( textInputModule.getText == "" || textInputModule.getText.contains(logRecord.module));
if ( textInputLevel.getText == "" || textInputLevel.getText.contains(logRecord.level))){
list add logRecord
}
logListView.setListData( list)
}
/*按钮事件辅助接口,用于把一个 事件处理函数转换为ButtonPressListener对象,也可以采取更高级的内容,使用implicit,这里没有使用*/
def function2Listener( fun : Button => Unit ) :ButtonPressListener =  {
val listener = new ButtonPressListener()
{
def buttonPressed(button: Button) = {
fun(button)
}
}
listener
}
}
/*
主函数
符合Pivot主函数入口规则
*/
object LogAnalyse {
def main ( args : Array[String]) : Unit = {

DesktopApplicationContext.main( classOf[MainWindow], args)

}
}
  run:
  使用 java时:
  java  -classpath scala-library.jar;pivot-core-1.5.jar;pivot-tools-1.5.jar;pivot-wtk-1.5.jar;pivot-wtk-terra-1.5.jar;. org.apache.pivot.scala.log.LogAnalyse
  使用 scala时
  java  -classpath pivot-core-1.5.jar;pivot-tools-1.5.jar;pivot-wtk-1.5.jar;pivot-wtk-terra-1.5.jar;. org.apache.pivot.scala.log.LogAnalyse

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-326251-1-1.html 上篇帖子: org.apache.lucene.analysis.TokenStream.incrementToken()Z 错误 下篇帖子: apache mod_limitipconn限制每ip连接数
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表