0

我将使用 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

我设想的程序将采用 2 个或更多参数:日志文件,然后是我感兴趣的任何数量的呼叫 ID。然后它将仅过滤掉相关消息并将其打印到标准输出。

请注意,单个 SIP 消息可能包含一个空行。下一条消息仅在显示新时间戳时才开始。

4

2 回答 2

0

试试这个

if ($subject =~ m/(?im)(Call-ID: (.+))$/) {
    $result = $2;
} else {
    $result = "";
}
于 2013-01-28T14:01:35.207 回答
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. 从splice1 开始获取(并删除)元素以构建散列的键。第零个元素是日志文件名。

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

如果打印了一条记录并且找到了出现在记录的第二部分 (rtpmap) 中的字段,则打印该块。

于 2013-01-29T03:50:08.600 回答