我有一个告警数据列表,其中每个告警都将使用名为eventId的唯一键进行标识。
对于每个唯一的eventId,我应该选择在警报上执行的最新操作。
执行的最新操作可以通过查看警报的lastUpdated字段来确定。
在下面的示例中,我有两个eventId为1001和1002的报警数据,并列出了对这些特定报警执行的操作。
代码如下:
use strict;
use warnings;
no warnings 'uninitialized';
use Data::Dumper;
use feature 'say';
my %selected;
{
local $/ = "";
while ( my $row = <DATA> ) {
next if ($row =~ /Total number of Alarm/);
my %row =
map { split / : /, $_, 2 }
split /\n/, $row;
my $id = $row{eventId};
$selected{$id} = \%row
if $row gt $selected{lastUpdated}
|| $row eq $selected{lastUpdated} && $row{Severity} eq 'CLEARED';
}
}
say "EventID,Node,Severity,State,LastUpdate";
foreach my $key (keys %selected){
my $e_id = $selected{$key};
say "$e_id->{eventId},$e_id->{Node},$e_id->{Severity},$e_id->{State},$e_id->{lastUpdated}";
}
__DATA__
Severity : HIGH
Node : N01
eventId : 1001
State : ACTIVE_UNACKNOWLEDGED
lastUpdated : 2020-09-30T12:30:32
Severity : HIGH
Node : N01
eventId : 1001
State : ACTIVE_UNACKNOWLEDGED
lastUpdated : 2020-09-30T12:35:33
Severity : CLEARED
Node : N01
eventId : 1001
State : CLEARED_ACKNOWLEDGED
lastUpdated : 2020-09-30T12:43:11
Severity : CLEARED
Node : N01
eventId : 1001
State : CLEARED_UNACKNOWLEDGED
lastUpdated : 2020-09-30T12:35:33
Severity : MEDIUM
Node : N02
eventId : 1002
State : ACTIVE_UNACKNOWLEDGED
lastUpdated : 2020-09-30T12:40:00
Severity : HIGH
Node : N02
eventId : 1002
State : ACTIVE_UNACKNOWLEDGED
lastUpdated : 2020-09-30T12:45:00
Total number of Alarm(s): 2以上脚本的输出:
EventID,Node,Severity,State,LastUpdate
1001,N01,CLEARED,CLEARED_UNACKNOWLEDGED,2020-09-30T12:35:33
1002,N02,HIGH,ACTIVE_UNACKNOWLEDGED,2020-09-30T12:45:00预期输出:
EventID,Node,Severity,State,LastUpdate
1001,N01,CLEARED,CLEARED_ACKNOWLEDGED,2020-09-30T12:43:11
1002,N02,HIGH,ACTIVE_UNACKNOWLEDGED,2020-09-30T12:45:00这里的条件是,如果特定的eventId在lastUpdated字段中有最新日期,并且存在CLEARED严重性,则需要考虑/打印此记录。否则,如果特定eventId的CLEARED严重性不存在,则应考虑在lastUpdated字段中具有最新日期的严重程度。如果清除/高/中/低严重性的lastUpdated是相同的,那么它应该选择已清除严重性的记录。
因此,对于事件1001,我们的最新日期是2020-09-30T12:43:11,但它选择的是2020-09-30T12:35:33,这是错误的。因为这是那个特定事件的最后一条记录。
如何根据lastUpdated选择特定的事件记录,并满足上面提到的严重程度条件。
发布于 2020-10-01 23:11:42
我认为你不太了解你的各种变量中有什么。例如,当您这样做时
if $row gt $selected{lastUpdated}你基本上是这样做的:
if "Severity : HIGH
Node : N01
eventId : 1001
State : ACTIVE_UNACKNOWLEDGED
lastUpdated : 2020-09-30T12:30:32" gt "2020-09-30T12:45:00";$row变量来自while条件中的readline语句:
while ( my $row = <DATA> ) {它从文件中读取整段文本(因为您使用的是段落模式$/ = "")。段落以双换行符、\n\n或文件结尾结束。
您最好的选择是将文件读取到内存中,然后进行比较。这段示例代码将向您展示如何将数据组织成合适的Perl数据结构。我将把如何比较这些值的逻辑留给您。
use strict;
use warnings;
use Data::Dumper;
my %log;
local $/ = ""; # paragraph mode
while (<>) {
next if /^Total number/;
my (%data) = split / : |\n/;
push @{$log{$data{eventId}}}, \%data;
}
print Dumper \%log使用您的数据,可以得到以下输出:
$VAR1 = {
'1001' => [
{
'eventId' => '1001',
'lastUpdated' => '2020-09-30T12:30:32',
'State' => 'ACTIVE_UNACKNOWLEDGED',
'Node' => 'N01',
'Severity' => 'HIGH'
},
{
'Severity' => 'HIGH',
'Node' => 'N01',
'State' => 'ACTIVE_UNACKNOWLEDGED',
'eventId' => '1001',
'lastUpdated' => '2020-09-30T12:35:33'
},
{
'eventId' => '1001',
'lastUpdated' => '2020-09-30T12:43:11',
'Severity' => 'CLEARED',
'State' => 'CLEARED_ACKNOWLEDGED',
'Node' => 'N01'
},
{
'Node' => 'N01',
'State' => 'CLEARED_UNACKNOWLEDGED',
'Severity' => 'CLEARED',
'eventId' => '1001',
'lastUpdated' => '2020-09-30T12:35:33'
}
],
'1002' => [
{
'lastUpdated' => '2020-09-30T12:40:00',
'eventId' => '1002',
'Severity' => 'MEDIUM',
'State' => 'ACTIVE_UNACKNOWLEDGED',
'Node' => 'N02'
},
{
'lastUpdated' => '2020-09-30T12:45:00',
'eventId' => '1002',
'Node' => 'N02',
'State' => 'ACTIVE_UNACKNOWLEDGED',
'Severity' => 'HIGH'
}
]
};这是一个散列,其中每个唯一的eventId都附加了一个记录数组。使用这种结构,您可以轻松地遍历各种eventId值,以找到最高/最低的lastUpdated或Severity。例如,您可以使用cmp (字符串大小)根据lastUpdated对eventIds进行排序:
for my $key (sort { $a <=> $b } keys %log) {
print "eventId: $key\n";
for my $record (sort { $a->{lastUpdated} cmp $b->{lastUpdated} } @{ $log{$key} }) {
# this will sort the hashes inside the array based on lastUpdated
print "\t$record->{lastUpdated}";
if ($record->{Severity} eq 'CLEARED') {
print "\tCLEARED";
}
print "\n";
}
}对于您提供的数据,这将打印出来
eventId: 1001
2020-09-30T12:30:32
2020-09-30T12:35:33
2020-09-30T12:35:33 CLEARED
2020-09-30T12:43:11 CLEARED
eventId: 1002
2020-09-30T12:40:00
2020-09-30T12:45:00由于我不清楚您的逻辑到底是什么,我将把这些细节留给您。
发布于 2020-10-01 21:55:50
我的解决方案是:
use strict;
use warnings;
use Data::Dumper;
local $/ = "\n\n";
my $events = {};
while( <DATA> ) {
my $hr = {};
while( /(\w+) *: *(.+)\n/g ) {
$hr->{$1} = $2;
}
if( exists $events->{ $hr->{eventId} } ) {
if( $events->{ $hr->{eventId} }->{lastUpdated} lt $hr->{lastUpdated} ) {
$events->{ $hr->{eventId} } = $hr;
}
}
elsif( $hr->{eventId} ) {
$events->{ $hr->{eventId} } = $hr;
}
}
print Dumper($events), "\n";https://stackoverflow.com/questions/64155295
复制相似问题