Regex 从日志文件中筛选SIP消息

Regex 从日志文件中筛选SIP消息,regex,perl,Regex,Perl,我的日常工作是使用VoIP解决方案。我经常从我管理的设备上调试SIP消息。然而,大多数时候,这些日志包含的调用比我需要分析的要多,所以如果我能过滤掉它们就太好了 我想要一个工具,如果我给它一个日志文件和我需要的呼叫Id,它可以过滤日志文件,只包括那些SIP消息 不幸的是,SIP消息不止一行,所以我对grep的经验不足以让它工作 为此,我开始用Perl编写一些程序,但除了检查是否有适当数量的参数,我没有得到。Perl是实现这一点的最佳语言吗?我在这里包含了一部分输入: Jan 28 11:39:3

我的日常工作是使用VoIP解决方案。我经常从我管理的设备上调试SIP消息。然而,大多数时候,这些日志包含的调用比我需要分析的要多,所以如果我能过滤掉它们就太好了

我想要一个工具,如果我给它一个日志文件和我需要的呼叫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
Jan 28 11:39:37.525 CET://1393628/D5CC0586A87B/SIP/Msg/ccsipDisplayMsg:
收到:
SIP/2.0 200正常
Via:SIP/2.0/UDP 10.218.16.2:5060;分支=Z9HG4BB22001ED5
摘自:“法兰克福公寓秘书处”;标签=E7E0EF64-192F
致:;标签=25079324~19cc0abf-61d9-407f-a138-96eaffee1467-27521338
日期:2013年1月28日星期一10:39:32 GMT
呼叫ID:D5CCA1AE-686D11E2-A881ED01-8DFA6D70@10.218.16.2
CSeq:102邀请
允许:邀请、选项、信息、再见、取消、确认、恶作剧、更新、参考、订阅、通知
允许事件:存在
支持:替换
支持:X-cisco-srtp-fallback
支持:地理定位
届会结束:1800;复习者=无人机
要求:定时器
P-首选标识:
远程方ID:;一方=被叫方;屏幕=否;隐私=关闭
联系人:
内容类型:应用程序/sdp
内容长度:209
v=0
o=IP4 10.210.2.49中的CISCOSystems CCM SIP 2000 1
s=SIP呼叫
c=在IP4 10.210.2.1中
t=0
m=音频16844 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=时间:20
a=rtpmap:101电话事件/8000
a=fmtp:101 0-15
一月28日11:39:37.529 CET://1393628/D5CC0586A87B/SIP/Msg/ccsipDisplayMsg:
发送:
确认sip:022046187@10.210.2.49:5060 SIP/2.0
Via:SIP/2.0/UDP 10.218.16.2:5060;分支=Z9HG4BKB247150A
摘自:“法兰克福公寓秘书处”;标签=E7E0EF64-192F
致:;标签=25079324~19cc0abf-61d9-407f-a138-96eaffee1467-27521338
日期:2013年1月28日星期一10:39:36 GMT
呼叫ID:D5CCA1AE-686D11E2-A881ED01-8DFA6D70@10.218.16.2
最大前锋:70
CSeq:102确认
授权:Digest username=“Genk\u AC\u 1”,realm=“infraxnet.be”,uri=“sip:022046187@10.210.2.49:5060“,response=“9546733290a96d1470cfe29a7500c488”,nonce=“5V/jt8fhd5i8uaoahshiaoud8o6uuujjj”,算法=MD5
允许事件:电话事件
内容长度:0
一月28日11:39:37.529 CET://1393627/D5CC0586A87B/SIP/Msg/ccsipDisplayMsg:
发送:
SIP/2.0 200正常
Via:SIP/2.0/UDP 192.168.8.11:5060;分支=Z9HG4BK24ECAAA6DBD3
摘自:“法兰克福公寓秘书处”;标签=e206cc93-1791-457a-aaac-1541296cf17c-29093746
致:;标签=E7E0F8A4-EA3
日期:2013年1月28日星期一10:39:32 GMT
呼叫ID:fedc8f80-10615564-45df0-b08a8c0@192.168.8.11
CSeq:101邀请
允许:邀请、选项、再见、取消、确认、恶作剧、更新、参考、订阅、通知、信息、注册
允许事件:电话事件
远程方ID:;一方=被叫方;屏幕=否;隐私=关闭
联系人:
支持:替换
支持:sdp anat
服务器:Cisco SIPGateway/IOS-15.3.1.T
届会结束:1800;复习者=无人机
要求:定时器
支持:定时器
内容类型:应用程序/sdp
内容配置:会话;处理=必需
内容长度:247
v=0
o=IP4 192.168.8.28中的CiscoSystemsSIP GW用户代理7276 9141
s=SIP呼叫
c=在IP4 192.168.8.28中
t=0
m=音频30134 RTP/AVP 8 101
c=在IP4 192.168.8.28中
a=rtpmap:8 PCMA/8000
a=rtpmap:101电话事件/8000
a=fmtp:101 0-15
a=时间:20
我设想的程序将接受2个或更多参数:日志文件,然后是我感兴趣的任意数量的调用ID。然后,它将只过滤出相关的消息并将其打印到stdout


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

试试这个

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

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

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;
}
使用严格;
使用警告;
我的%callIDs=map{$\=>1}拼接@ARGV,1,@ARGV-1;
我的$recordPrinted;
本地$/='';
而(){
if(/Call ID:\s+(.+)/和$callIDs{$1}){
$recordPrinted=1;
印刷品;
下一个
}
如果$recordPrinted和/\brtpmap\b/,则打印;
$recordPrinted=0;
}
用法:
perl scriptName.pl日志文件callID[callID]

当您发送脚本参数时,它们最终会出现在
@ARGV
中。
splice
从1上获取(并删除)元素以构建哈希键。第0个元素是日志文件名

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


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

您试图筛选的呼叫id在哪里?在每个SIP消息块中都有一个“呼叫id:…”线路。这就是我想要过滤的。哇,谢谢。这正是我需要的。我不认为我会发现所有的perl特性都能让这一点变得如此优雅。我已经看了大约10分钟了,现在才开始完全理解它。@TomRibbens-不客气!我很高兴它能为你工作。显然它不适用于带有CRLF行终止符的文件。我会调查的。