0

私は TCL の初心者であり、Cisco ルーターからの日付スタンプに基づいてログ メッセージをグループ化するための支援が必要です。

更新: サンプル ログの変更。DD が 1 桁の場合、余分なスペースがあることがわかりました。例: "1"

サンプルログ: ロギングを表示

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 }
4

2 に答える 2

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
于 2013-03-07T10:57:37.317 に答える
1

連想配列を使用するだけです — array(sic!) またはdict(Tcl 8.5 で登場)。

スキャンする前に、配列は空です。ログ ファイルをスキャンしてそこからテキスト行を解析すると (実際のファイル形式によっては、splitまたはregexpまたはstring rangeなどで実行できます)、グループ化に一致するエントリがあるかどうかを確認します。条件は配列に既に存在します。そうでない場合は、いくつかのデータ構造を配列に挿入し、いくつかの初期値を入力します。一致するエントリが存在する場合は、それに関連付けられているデータ構造を新しいデータで更新します。

実際のデータ構造については... s についてarrayは、2 要素listの s を使用します。それらの要素には、それぞれ「アップ」イベントと「ダウン」イベントの数が保持されます。dictイオナリは入れ子にすることができるので、この可能性を利用できます。

あなたのログファイルが実際に何についてのものであるかについて明確な考えを持っていないことに注意してください.連想配列の要素は他の値を保持する必要があるかもしれません.

于 2013-03-07T06:44:38.977 に答える