TCL:如何根据日期戳将日志消息组合在一起

时间:2013-03-06 22:15:39

标签: networking logging tcl cisco-ios

我是TCL的新手,需要一些协助,根据Cisco路由器的日期戳将日志消息分组在一起。

更新:更改样本日志。已经发现DD是单个数字时有一个额外的空间。例如“1”

Samplelog:show logging

THREADID: Feb  1 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Feb  1 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Feb  1 HH:MM:SS.SSS  : %TYPE-OF-VAIRBLE: OFFLINE
THREADID: Feb  1 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Feb  3 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: UP
THREADID: Feb  3 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: UP
THREADID: Feb  4 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Feb  4 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Mar 15 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: UP
THREADID: Mar 15 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Mar 15 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Mar 16 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: UP
THREADID: Mar 16 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN
THREADID: Mar 16 HH:MM:SS.SSS : %TYPE-OF-VAIRBLE: DOWN

期望的输出

Feb 01 || 3 down
Feb 04 || 2 down
Mar 15 || 2 down
Mar 16 || 2 down

使用新逻辑更新了新代码以尝试解决额外空间,尽管这不能按预期工作。

set y [read -nonewline [set f [open "tmp.txt" r]]];

array set counts [list];
foreach message [split $y "\n"] {
    # This gets the status, ie: DOWN/UP/OFFLINE.
    set status [lindex [split $message] end]; # will assign last field
    set mon [lindex [split $message] 1]; # number represents the filed number
    set day [lindex [split $message] 2];
    if {$day ==""} {
        set day [lindex [split $message] 3];
     } else {
        set day [lindex [split $message] 2]
    }
        # +number represents the counter
    if {[info exists counts($mon,$day,$status)]} {
            set counts($mon,$day,$status) [expr {$counts($mon,$day,$status)+1}] 
    } else {
            set counts($mon,$day,$status) 1
    }   
}

# sort based for down type events

puts "\n\n MMM DD || Cnt Status"
puts " ====================="

foreach count [lsort -increasing -unique [array names counts]] {

    foreach {mon day status} [split $count ","] { break; }
    if {$status =="down"} {
    puts " $mon $day || [set counts($count)] \t $status"
    }
}

if {[info exists f]} { close $f }

2 个答案:

答案 0 :(得分:1)

只需使用关联数组 - array(sic!)或dict(出现在Tcl 8.5中)。

在扫描之前,您的阵列是空的,当您扫描日志文件并从中解析文本行时(取决于实际的文件格式,可以使用splitregexpstring range等),您检查数组中是否已存在与您的分组条件匹配的条目。如果没有,则将一些数据结构插入到数组中,并填充一些初始值。如果存在匹配条目,则使用新数据更新与其关联的数据结构。

对于实际的数据结构......对于array,我会使用两个元素list - 其元素分别包含“向上”和“向下”事件的数量。 dict离子可以嵌套,所以你可以使用这种可能性。

请注意,我并不清楚您的日志文件的真正含义,因此关联数组的元素可能会保留其他一些值,但总体思路仍然存在:它是一个关联的任务阵列。

答案 1 :(得分:1)

试试这个 - 您需要将“file.txt”更改为您的日志文件。

set y [read -nonewline [set f [open "file.txt" r]]];

array set counts [list];
foreach message [split $y "\n"] {
        # This gets the status, ie: DOWN/UP/OFFLINE.
        set status [lindex [split $message] end];
        set id [lindex [split $message] 3];
        if {[info exists counts($id,$status)]} {
                set counts($id,$status) [expr {$counts($id,$status)+1}]
        } else {
                set counts($id,$status) 1
        }
}

foreach count [lsort -increasing -unique [array names counts]] {
        foreach {name status} [split $count ","] { break; }
        puts "MMM $name || [set counts($count)] $status"
}

if {[info exists f]} { close $f }

此输出(对于您给出的示例日志)给出:

MMM 01 || 3 DOWN
MMM 01 || 1 OFFLINE
MMM 03 || 2 UP
MMM 04 || 2 DOWN