从日志文件中过滤SIP消息

时间:2013-01-28 13:36:48

标签: regex perl

我使用VoIP解决方案作为日常工作。我经常从我管理的设备上获取SIP消息调试。但是,大多数情况下,这些日志包含的调用次数超出了我需要分析的次数,所以如果我可以过滤掉它们会很棒。

我想要一个工具,如果我给它一个日志文件和我需要的Call-Id,可以过滤日志文件以仅包含那些SIP消息。

不幸的是,SIP消息不止一行,所以我使用grep的经验不足以让它工作。

我开始在Perl中编写一些东西,但是除了检查我是否有适当数量的参数,我没有得到。 Perl是最好的语言吗?我在这里列出了一部分输入:

Jan 28 11:39:37.525 CET: //1393628/D5CC0586A87B/SIP/Msg/ccsipDisplayMsg:
Received: 
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.218.16.2:5060;branch=z9hG4bKB22001ED5
From: "Frankeerapparaat Secretariaat" <sip:089653717@10.210.2.49>;tag=E7E0EF64-192F
To: <sip:022046187@10.210.2.49>;tag=25079324~19cc0abf-61d9-407f-a138-96eaffee1467-27521338
Date: Mon, 28 Jan 2013 10:39:32 GMT
Call-ID: D5CCA1AE-686D11E2-A881ED01-8DFA6D70@10.218.16.2
CSeq: 102 INVITE
Allow: INVITE, OPTIONS, INFO, BYE, CANCEL, ACK, PRACK, UPDATE, REFER, SUBSCRIBE, NOTIFY
Allow-Events: presence
Supported: replaces
Supported: X-cisco-srtp-fallback
Supported: Geolocation
Session-Expires:  1800;refresher=uas
Require:  timer
P-Preferred-Identity: <sip:022046187@10.210.2.49>
Remote-Party-ID: <sip:022046187@10.210.2.49>;party=called;screen=no;privacy=off
Contact: <sip:022046187@10.210.2.49:5060>
Content-Type: application/sdp
Content-Length: 209

v=0
o=CiscoSystemsCCM-SIP 2000 1 IN IP4 10.210.2.49
s=SIP Call
c=IN IP4 10.210.2.1
t=0 0
m=audio 16844 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=ptime:20
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15

Jan 28 11:39:37.529 CET: //1393628/D5CC0586A87B/SIP/Msg/ccsipDisplayMsg:
Sent: 
ACK sip:022046187@10.210.2.49:5060 SIP/2.0
Via: SIP/2.0/UDP 10.218.16.2:5060;branch=z9hG4bKB2247150A
From: "Frankeerapparaat Secretariaat" <sip:089653717@10.210.2.49>;tag=E7E0EF64-192F
To: <sip:022046187@10.210.2.49>;tag=25079324~19cc0abf-61d9-407f-a138-96eaffee1467-27521338
Date: Mon, 28 Jan 2013 10:39:36 GMT
Call-ID: D5CCA1AE-686D11E2-A881ED01-8DFA6D70@10.218.16.2
Max-Forwards: 70
CSeq: 102 ACK
Authorization: Digest username="Genk_AC_1",realm="infraxnet.be",uri="sip:022046187@10.210.2.49:5060",response="9546733290a96d1470cfe29a7500c488",nonce="5V/Jt8FHd5I8uaoahshiaUud8O6UujJJ",algorithm=MD5
Allow-Events: telephone-event
Content-Length: 0


Jan 28 11:39:37.529 CET: //1393627/D5CC0586A87B/SIP/Msg/ccsipDisplayMsg:
Sent: 
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.8.11:5060;branch=z9hG4bK24ecaaaa6dbd3
From: "Frankeerapparaat Secretariaat" <sip:3717@192.168.8.11>;tag=e206cc93-1791-457a-aaac-1541296cf17c-29093746
To: <sip:022046187@192.168.8.28>;tag=E7E0F8A4-EA3
Date: Mon, 28 Jan 2013 10:39:32 GMT
Call-ID: fedc8f80-10615564-45df0-b08a8c0@192.168.8.11
CSeq: 101 INVITE
Allow: INVITE, OPTIONS, BYE, CANCEL, ACK, PRACK, UPDATE, REFER, SUBSCRIBE, NOTIFY, INFO, REGISTER
Allow-Events: telephone-event
Remote-Party-ID: <sip:022046187@192.168.8.28>;party=called;screen=no;privacy=off
Contact: <sip:022046187@192.168.8.28:5060>
Supported: replaces
Supported: sdp-anat
Server: Cisco-SIPGateway/IOS-15.3.1.T
Session-Expires:  1800;refresher=uas
Require: timer
Supported: timer
Content-Type: application/sdp
Content-Disposition: session;handling=required
Content-Length: 247

v=0
o=CiscoSystemsSIP-GW-UserAgent 7276 9141 IN IP4 192.168.8.28
s=SIP Call
c=IN IP4 192.168.8.28
t=0 0
m=audio 30134 RTP/AVP 8 101
c=IN IP4 192.168.8.28
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=ptime:20

我设想的程序会带两个或多个参数:日志文件,然后是我感兴趣的任何Call-ID调用。然后它会过滤掉相关的消息并将其打印到stdout。

请注意,单个SIP消息可能包含空行。仅当显示新时间戳时,才会启动下一条消息。

2 个答案:

答案 0 :(得分:0)

试试这个

if ($subject =~ m/(?im)(Call-ID: (.+))$/) {
    $result = $2;
} else {
    $result = "";
}

答案 1 :(得分:0)

也许以下内容会有所帮助:

use strict;
use warnings;

my %callIDs = map { $_ => 1 } splice @ARGV, 1, @ARGV - 1;
my $recordPrinted;

local $/ = '';

while (<>) {
    if ( /Call-ID:\s+(.+)/ and $callIDs{$1} ) {
        $recordPrinted = 1;
        print;
        next;
    }

    print if $recordPrinted and /\brtpmap\b/;

    $recordPrinted = 0;
}

用法:perl scriptName.pl logFile callID [callID]

发送脚本参数时,它们会以@ARGV结尾。 splice从1开始接收(并移除)元素以构建散列键。第0个元素是日志文件名。

local $/ = '';设置段落模式,即一次读取由空行分隔的整个文本块。正则表达式捕获Call-ID,如果该ID存在密钥,则打印该行。此外,设置一个标志以指示已经打印了“记录”,因为该记录可能还有另一个“块”。

如果已打印记录并且发现记录的第二部分(rtpmap)中出现字段,则会打印该块。