使用drools计算文本日志中事件的持续时间

时间:2012-01-28 00:45:47

标签: drools

我们正在尝试使用Drools来处理来自日志文件的大量文本数据。我正在努力了解如何正确测量活动时间。

有问题的事件从一个日志行开始,但可以通过成功完成或异常中止完成。这就是我在捕获时遇到的问题。以下是日志条目的外观(当其他日志行被过滤掉时):

Jan 24 06:50:29 app[623]:  CallOriginateCmd
Jan 24 07:19:27 app[616]:  Client ended the call 
Jan 24 09:00:18 app[623]:  CallOriginateCmd
Jan 24 09:34:48 app[616]:  Client ended the call 
Jan 24 11:03:56 app[623]:  CallOriginateCmd
Jan 24 12:56:58 app[616]:  Client ended the call 
Jan 24 15:48:11 app[623]:  CallOriginateCmd
Jan 24 16:13:24 app[616]:  Client ended the call 
Jan 24 17:16:16 app[623]:  CallOriginateCmd
Jan 24 18:48:51 app[616]:  Client ended the call 
Jan 25 06:09:01 app[623]:  CallOriginateCmd
Jan 25 06:09:24 app[623]:  Failure: timeout sending Config 
Jan 25 06:09:26 app[623]:  CallOriginateCmd
Jan 25 06:09:50 app[623]:  Failure: timeout sending Config 

我正在尝试制作规则,将1月24日06:50:29通话与07:19:27终止,1月25日06:09:01通话以及06:09:24失败等联系起来。我的下面的规则不会创建一个具有我想要的正确开始/结束时间的Call()对象。

以下是我的代码大纲:

rule "Found Call Start"
    when
        LogEntry( message matches ".*CallOriginateCmd.*", logTimestamp : timestamp )
    then
        Call call = new Call();
        call.setStarttime( logTimestamp );
        call.setPartial ( true );
        insert( call );
        AnalysisLog.debug( logTimestamp, "Call Started" );
end

rule "Found Call End"
    when
        LogEntry( message matches ".*Client ended the call.*", logTimestamp : timestamp )
        call : Call( partial == true )
    then
        call.setEndtime( logTimestamp );
        call.setPartial( false );
        call.setFailure( false );
        update( call );
        AnalysisLog.debug( logTimestamp, "Call Ended." );
end

rule "Found Call Failure"
    when 
        LogEntry( message matches ".*timeout sending Config.*", logTimestamp : timestamp )
        call : Call( partial == true )
    then
        call.setEndtime( logTimestamp );
        call.setPartial( false );
        call.setFailure( true );
        update( call );
        AnalysisLog.debug( logTimestamp, "Call Failed." );
end

上面的输出是:

Jan 17 22:53:04: Call Started
Jan 18 02:10:23: Call Failed.
Jan 17 23:09:23: Call Started
Jan 18 02:10:23: Call Failed.
Jan 17 23:25:39: Call Started

虽然只有日志中的最后一个呼叫应该匹配,但每个呼叫似乎都匹配失败。

我以为代码:

call : Call( partial == true )
在“when”子句中将start + end或start + abort链接在一起,但这显然不会这样做。

相反,我想我需要在“when”子句中找到一种方法来查找logTimestamp最接近调用Starttime的调用。这可能吗?

TIA

2 个答案:

答案 0 :(得分:1)

我没有在你的日志中看到任何相关字段,所以我假设消息总是连续的?即,消息开始呼叫,下一条消息完成或未通过呼叫。如果是这种情况,有很多方法可以做到,但你可以尝试这样的事情:

rule "Found Call End"
    when
        $s : LogEntry( message matches ".*CallOriginateCmd.*" )
        $e : LogEntry( message matches ".*Client ended the call.*" )
        not LogEntry( timestamp > $s.timestamp && timestamp < $e.timestamp )
    then
        Call call = new Call();
        call.setStarttime( $s.getTimestamp() );
        call.setEndtime( $e.getTimestamp() );
        call.setFailure( false );
        retract( $s );
        retract( $e );
        insert( call );
        AnalysisLog.debug( logTimestamp, "Call Ended." );
end

为您的呼叫失败方案编写类似的规则。如果日志中存在相关字段,则只需添加约束以关联正确的LogEntries。

答案 1 :(得分:0)

您是否检查过Drools Fusion,您将能够将LogEntry作为事件处理,允许您使用时间运算符来检查启动调用事件是否在结束调用事件之前发生。 Drools fusion还将为您提供自动事件生命周期管理。除了技术问题,我仍然试图了解你的主要目标是什么。 干杯