首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据特定事件的上次更新日期从文件中选取一条记录

根据特定事件的上次更新日期从文件中选取一条记录
EN

Stack Overflow用户
提问于 2020-10-01 20:21:11
回答 2查看 65关注 0票数 1

我有一个告警数据列表,其中每个告警都将使用名为eventId的唯一键进行标识。

对于每个唯一的eventId,我应该选择在警报上执行的最新操作。

执行的最新操作可以通过查看警报的lastUpdated字段来确定。

在下面的示例中,我有两个eventId为1001和1002的报警数据,并列出了对这些特定报警执行的操作。

代码如下:

代码语言:javascript
复制
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

以上脚本的输出:

代码语言:javascript
复制
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

预期输出:

代码语言:javascript
复制
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

这里的条件是,如果特定的eventIdlastUpdated字段中有最新日期,并且存在CLEARED严重性,则需要考虑/打印此记录。否则,如果特定eventIdCLEARED严重性不存在,则应考虑在lastUpdated字段中具有最新日期的严重程度。如果清除/高/中/低严重性的lastUpdated是相同的,那么它应该选择已清除严重性的记录。

因此,对于事件1001,我们的最新日期是2020-09-30T12:43:11,但它选择的是2020-09-30T12:35:33,这是错误的。因为这是那个特定事件的最后一条记录。

如何根据lastUpdated选择特定的事件记录,并满足上面提到的严重程度条件。

EN

回答 2

Stack Overflow用户

发布于 2020-10-01 23:11:42

我认为你不太了解你的各种变量中有什么。例如,当您这样做时

代码语言:javascript
复制
if $row gt $selected{lastUpdated}

你基本上是这样做的:

代码语言:javascript
复制
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语句:

代码语言:javascript
复制
while ( my $row = <DATA> ) {

它从文件中读取整段文本(因为您使用的是段落模式$/ = "")。段落以双换行符、\n\n或文件结尾结束。

您最好的选择是将文件读取到内存中,然后进行比较。这段示例代码将向您展示如何将数据组织成合适的Perl数据结构。我将把如何比较这些值的逻辑留给您。

代码语言:javascript
复制
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

使用您的数据,可以得到以下输出:

代码语言:javascript
复制
$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值,以找到最高/最低的lastUpdatedSeverity。例如,您可以使用cmp (字符串大小)根据lastUpdated对eventIds进行排序:

代码语言:javascript
复制
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";
    }
}

对于您提供的数据,这将打印出来

代码语言:javascript
复制
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

由于我不清楚您的逻辑到底是什么,我将把这些细节留给您。

票数 2
EN

Stack Overflow用户

发布于 2020-10-01 21:55:50

我的解决方案是:

代码语言:javascript
复制
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";
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64155295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档