[R] Synthèse d'erreur dans l'observateur d'évènement

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Avatar du membre
jl56
Niveau 7
Niveau 7
Messages : 411
Enregistré le : mer. 24 oct. 2007 22:42
Localisation : 56000
Status : Hors ligne

[R] Synthèse d'erreur dans l'observateur d'évènement

#1

Message par jl56 »

bonjour à tous


Je désire créer un détecteur d’erreur dans observateur d’événement.
Pour envoyer un email par jour en cas d’erreur.

Sur l’ancien forum et sur le forum anglais j’avais trouvé ceci

Code : Tout sélectionner

 
  ;~ $Query_Clause = "Select * FROM Win32_NTLogEvent WHERE Logfile = 'System' AND SourceName = 'Print' AND EventCode = 6161" 
;~ test erreur system 
$Query_Clause = "Select * FROM Win32_NTLogEvent WHERE Logfile = 'System' AND Type = 'Erreur'" 
;~ $Query_Clause = "Select * FROM Win32_NTLogEvent WHERE Type = 'Erreur'" 
$objWMIService = ObjGet ( "winmgmts:{impersonationLevel = impersonate , ( Security ) }!\\" & @ComputerName & "\root\cimv2" ) 
If IsObj ( $objWMIService ) Then 
$colItems = $objWMIService.ExecQuery ( $Query_Clause ) 
If IsObj ( $colItems ) Then 
;~ initialisation du compteur 
$a = 0 
For $objEvent In $colItems 
$Output = "" 
if StringLeft ( $objEvent.TimeWritten , 8 ) = "20071105" then 
;~ je compte uniquement sur la date 05 11 2007 
$a = $a + 1 

$Output & = "Category: " & $objEvent.Category & @CRLF 
$Output & = "Computer Name: " & $objEvent.ComputerName & @CRLF 
$Output & = "Event Code: " & $objEvent.EventCode & @CRLF 
$Output & = "Message: " & $objEvent.Message & @CRLF 
$Output & = "Record Number: " & $objEvent.RecordNumber & @CRLF 
$Output & = "Source Name: " & $objEvent.SourceName & @CRLF 
$Output & = "Time Written: " & $objEvent.TimeWritten & @CRLF 
$Output & = "Event Type: " & $objEvent.Type & @CRLF 
$Output & = "User: " & $objEvent.User & @CRLF 
EndIf 
;~ If MsgBox ( 4 , "Entry Found:" , $Output & @CRLF & @CRLF & "Continue?" , 1 ) = 7 Then Exit 
Next 
MsgBox ( 0 , "nombre d'erreur le 05 11 2007 = > " , $a ) 
Else 
MsgBox ( 16 , "Error" , "$colItems is not an object." ) 
EndIf 
Else 
MsgBox ( 16 , "Error" , "$objWMIService is not an object." ) 
EndIf
J’ai compris le fonctionnement
Dans l’exemple je sélectionne les erreurs de la source system et le 05 11 2007
Et je compte le nombre d’erreur

Mais je voudrais en faire une synthèse (j’avais trouver sur le net un programme qui fonctionnais comme ça, mais un jour, un poste a eu une erreur de disque cdrom et le programme à envoyé au moins 2000 emails dans l’heure !! c'a fait désordre)

Alors voila

J’ai par exemple un faux fichier observateur d’événement comme ci-dessous

05 11 2007 system erreur disque
O5 11 2007 system erreur virus
05 11 2007 system erreur disque
05 11 2007 system erreur dcom
05 11 2007 system erreur disque
05 11 2007 system erreur virus

Et je voudrais un état par jour du genre

Il y a le 05 11 2007 sur le poste machin
3 erreurs disque
2 erreurs virus
1 erreur dcom

Le nom des erreurs étant inconnu avant la synthèse
Ainsi que l’ordre d’apparition

Je sais comme dans l’exemple sélectionner par date
Je sais également éliminer des erreurs connus et pas intéressantes ex. print
Mais je ne vois comment trier et synthétiser les erreurs


Je ne vous demande pas une solution toute faite
Mais les outils ou fonction qui pourrai m’aider
Ou éventuellement un exemple de gestion de base de donnée ou tableau multi, enfin justement je ne sais pas quoi

Merci à tous

A+ jl56

ps genial le forumcolor par contre des retour chariot ne sont pas pris en compte
Avatar du membre
sylvanie
Niveau 11
Niveau 11
Messages : 1550
Enregistré le : jeu. 26 juil. 2007 21:31
Localisation : Paris
Status : Hors ligne

#2

Message par sylvanie »

Bonsoir,
voici une méthode, je n'ai pas traîté le nom de la machine, il reste donc un petit TODO ;) :

Code : Tout sélectionner

#include <Array.au3> 
$ficin = FileOpen ( "log_evt.txt" , 0 ) 
if $ficin = - 1 Then Exit 1 
$ficout = FileOpen ( "fic_log_parse.txt" , 2 ) 
;init de la date et d'une liste de concaténation de log 
$date = "" 
$liste_error = "" 
While 1 
$line = FileReadLine ( $ficin ) 
if @error = - 1 then ExitLoop 
$tab_split = StringRegExp ( $line , " ( \d{2} \d{2} \d{4} ) ( .* ) " , 3 ) ; récupère la date en indice 0 et la suite en indice 1 
if @error Then ContinueLoop ; erreur de pattern , on passe 
If Not IsArray ( $tab_split ) Then ContinueLoop ; le retour n'est pas un tableau , on passe 
If UBound ( $tab_split ) <> 2 Then ContinueLoop; la dimension est différente de 2 , on passe 
If ( $date <> $tab_split[0] ) Then 
; on vient de changer de date dans le fichier log 
; si la date d'avant n'est pas vide alors on update le fichier sortie 
if ( $date <> "" ) Then Write_log ( $ficout , $date , $liste_error ) 
$date = $tab_split[0] 
$liste_error = $tab_split[1] & @CRLF 
Else 
$liste_error & = $tab_split[1]&@CRLF 
EndIf 
WEnd 
;traitement éventuel du dernier paquet de log 
if ( $date <> "" ) Then Write_log ( $ficout , $date , $liste_error ) 
FileClose ( $ficin ) 
FileClose ( $ficout ) 
Exit 0 
Func Write_log ( $fichier_arg , $date_arg , $liste_arg ) 
local $tab_local , $local_ind , $local_dim , $tab_nom , $tab_cpt 
FileWriteLine ( $fichier_arg , "Il y a le " & $date_arg ) 
;décomosition par retour chariot 
$tab_local = StringSplit ( $liste_arg , @CRLF , 1 ) 
If Not IsArray ( $tab_local ) Then Return 0; erreur 
;on se débarasse de la ligne vide 
_ArrayPop ( $tab_local ) 
; on enleve la dimension d'indice 0 
_ArrayDelete ( $tab_local , 0 ) 
;tri du tableau 
_ArraySort ( $tab_local ) 
; fonction comptant le nombre de chaque occurence et réduisant le tableau 
$tab_local = _Array_reduce ( $tab_local ) 
If Not IsArray ( $tab_local ) Then Return 0; erreur 
$tab_nom = $tab_local[0] 
$tab_cpt = $tab_local[1] 
$local_dim = UBound ( $tab_cpt , 1 ) 
For $local_ind = 0 to $local_dim - 1 
FileWriteLine ( $fichier_arg , $tab_cpt[$local_ind] & " " & $tab_nom[$local_ind] ) 
Next 
Return 1 
EndFunc 
;fonction prenant en arg un tablea déjà trié et retournant un tableau réduit contenant en première dim ;le nom de l'erreur , et en 2eme dim son itération 
Func _Array_reduce ( $tab_local ) 
local $local_ind , $local_err = "" , $local_cpt = 0 
local $local_tab_nom = "" 
Local $local_tab_iterration = "" 
Local $tab_final 
If Not IsArray ( $tab_local ) Then return 0 
For $local_ind = 0 To UBound ( $tab_local ) - 1 
if $tab_local[$local_ind] = "" Then ContinueLoop ; saute le cas vide 
If $tab_local[$local_ind] <> $local_err Then ; on arrive à un nouveau type d'erreur ( vrai car le tableau est trié ! ) 
If $local_err <> "" Then ; si = "" alors on est dans le 1er cas d'init 
$local_tab_nom & = $local_err&@CRLF 
$local_tab_iterration & = $local_cpt&@CRLF 
EndIf 
$local_err = $tab_local[$local_ind]; local_err devient l'erreur en cours 
$local_cpt = 1 
Else 
$local_cpt += 1; sinon on incrémente l'occurence de 1 EndIf 
Next 
;dernier traitement 
If $local_err <> "" Then ; si = "" alors on est dans le 1er cas d'init 
$local_tab_nom & = $local_err&@CRLF 
$local_tab_iterration & = $local_cpt&@CRLF 
EndIf 
;transformation des 2 chaînes de résultat en tableau 
$local_tab_nom = StringSplit ( $local_tab_nom , @CRLF , 1 ) 
$local_tab_iterration = StringSplit ( $local_tab_iterration , @CRLF , 1 ) 
If $local_tab_nom[$local_tab_nom[0]] = "" Then ; on se débarasse des cas vides de fin 
_ArrayPop ( $local_tab_nom ) 
_ArrayPop ( $local_tab_iterration ) 
$local_tab_nom[0] -= 1 
$local_tab_iterration[0] -= 1 
EndIf 
;on se débarrase des dimension de début 
_ArrayDelete ( $local_tab_nom , 0 ) 
_ArrayDelete ( $local_tab_iterration , 0 ) 
Dim $tab_final[2] = [$local_tab_nom , $local_tab_iterration] 
Return $tab_final 
EndFunc



voici un exple de fichier log enrichie pour l'illustrer, le fameux log_evt.txt mentionné dans le code

Code : Tout sélectionner

05 11 2007 system erreur disque 
05 11 2007 system erreur virus 
05 11 2007 system erreur disque 
05 11 2007 system erreur dcom 
05 11 2007 system erreur disque 
05 11 2007 system erreur virus
06 11 2007 system erreur disque 
07 11 2007 system erreur virus 
08 11 2007 system erreur disque 
09 11 2007 system erreur dcom 
09 11 2007 system erreur disque 
09 11 2007 system erreur virus
 
Toi qui cherche à mettre le doigt sur la solution, appuie sur F1.
Avatar du membre
jl56
Niveau 7
Niveau 7
Messages : 411
Enregistré le : mer. 24 oct. 2007 22:42
Localisation : 56000
Status : Hors ligne

bonjour et merci forumcolor doit supprimer

#3

Message par jl56 »

bonjour

Merci pour ce travail et le temps que tu as passé pour le réalisé

je pense que forumcolor modifie le script

$local_cpt += 1; sinon on incrémente l'occurence de 1 EndIf

la évidement j'ai compris

par contre il y a plusieurs lignes

$local_tab_nom & = $local_err&@CRLF
$local_tab_iterration & = $local_cpt&@CRLF

et je ne sais pas quoi mettre derriere le &


peut tu stp recopier ton script sans forumcolor

merci encore

a+ jl56
Avatar du membre
sylvanie
Niveau 11
Niveau 11
Messages : 1550
Enregistré le : jeu. 26 juil. 2007 21:31
Localisation : Paris
Status : Hors ligne

#4

Message par sylvanie »

Code : Tout sélectionner

#include <Array.au3>
$ficin=FileOpen("log_evt.txt",0)
if $ficin=-1 Then Exit 1

$ficout=FileOpen("fic_log_parse.txt",2)
;init de la date et d'une liste de concaténation de log
$date=""
$liste_error=""
While 1
    $line=FileReadLine($ficin)
    if @error=-1 then ExitLoop
    $tab_split=StringRegExp($line,"(\d{2} \d{2} \d{4}) (.*)",3) ; récupère la date en indice 0 et la suite en indice 1
    if @error Then ContinueLoop ; erreur de pattern, on passe
    If Not IsArray($tab_split) Then ContinueLoop ; le retour n'est pas un tableau, on passe
    If UBound($tab_split)<>2 Then ContinueLoop; la dimension est différente de 2, on passe
    If ($date<>$tab_split[0]) Then
        ; on vient de changer de date dans le fichier log
        ; si la date d'avant n'est pas vide alors on update le fichier sortie
        if ($date<>"") Then Write_log($ficout,$date,$liste_error)
        $date=$tab_split[0]
        $liste_error=$tab_split[1]&@CRLF
    Else
        $liste_error&=$tab_split[1]&@CRLF
    EndIf
WEnd
;traitement éventuel du dernier paquet de log
if ($date<>"") Then Write_log($ficout,$date,$liste_error)
    
FileClose($ficin)
FileClose($ficout)
Exit 0

Func Write_log($fichier_arg,$date_arg,$liste_arg)
    local $tab_local,$local_ind,$local_dim,$tab_nom,$tab_cpt
    
    FileWriteLine($fichier_arg,"Il y a le "&$date_arg)
    ;décomosition par retour chariot
    $tab_local=StringSplit($liste_arg,@CRLF,1)
    If Not IsArray($tab_local) Then Return 0; erreur
    ;on se débarasse de la ligne vide
    _ArrayPop($tab_local)
    ; on enleve la dimension d'indice 0
    _ArrayDelete ( $tab_local, 0 )
    ;tri du tableau
    _ArraySort($tab_local)
    ; fonction comptant le nombre de chaque occurence et réduisant le tableau
    $tab_local=_Array_reduce($tab_local)
    If Not IsArray($tab_local) Then Return 0; erreur
    $tab_nom=$tab_local[0]
    $tab_cpt=$tab_local[1]
    $local_dim=UBound($tab_cpt,1)
    For $local_ind=0 to $local_dim-1
        FileWriteLine($fichier_arg,$tab_cpt[$local_ind]&" "&$tab_nom[$local_ind])
    Next
    Return 1
EndFunc

;fonction prenant en arg un tablea déjà trié et retournant un tableau réduit contenant en première dim 
;le nom de l'erreur, et en 2eme dim son itération
Func _Array_reduce($tab_local)
    local $local_ind,$local_err="",$local_cpt=0
    local $local_tab_nom=""
    Local $local_tab_iterration=""
    Local $tab_final
    If Not IsArray($tab_local) Then return 0
    For $local_ind=0 To UBound($tab_local)-1
        if $tab_local[$local_ind]="" Then ContinueLoop ; saute le cas vide
        If $tab_local[$local_ind]<>$local_err Then ; on arrive à un nouveau type d'erreur (vrai car le tableau est trié !)
            If $local_err<>"" Then ; si ="" alors on est dans le 1er cas d'init
                $local_tab_nom&=$local_err&@CRLF
                $local_tab_iterration&=$local_cpt&@CRLF
            EndIf
            $local_err=$tab_local[$local_ind]; local_err devient l'erreur en cours
            $local_cpt=1
        Else
            $local_cpt+=1; sinon on incrémente l'occurence de 1 
        EndIf
    Next
    ;dernier traitement
    If $local_err<>"" Then ; si ="" alors on est dans le 1er cas d'init
        $local_tab_nom&=$local_err&@CRLF
        $local_tab_iterration&=$local_cpt&@CRLF
    EndIf
    ;transformation des 2 chaînes de résultat en tableau
    $local_tab_nom=StringSplit($local_tab_nom,@CRLF,1)
    $local_tab_iterration=StringSplit($local_tab_iterration,@CRLF,1)
    If $local_tab_nom[$local_tab_nom[0]]="" Then  ; on se débarasse des cas vides de fin
        _ArrayPop($local_tab_nom)
        _ArrayPop($local_tab_iterration)
        $local_tab_nom[0]-=1
        $local_tab_iterration[0]-=1
    EndIf
    ;on se débarrase des dimension de début
    _ArrayDelete($local_tab_nom,0)
    _ArrayDelete($local_tab_iterration,0)
    Dim $tab_final[2]=[$local_tab_nom,$local_tab_iterration]
    Return $tab_final
EndFunc


 
pour :
[autoit]$local_tab_nom&=$local_err&@CRLF
$local_tab_iterration&=$local_cpt&@CRLF[/autoit]

ceux sont des concaténations abrégées :
exple a=a&b équivaut à a&=b
Toi qui cherche à mettre le doigt sur la solution, appuie sur F1.
Avatar du membre
jl56
Niveau 7
Niveau 7
Messages : 411
Enregistré le : mer. 24 oct. 2007 22:42
Localisation : 56000
Status : Hors ligne

[r] merci pour ton script c'a fonctionne super bravo

#5

Message par jl56 »

bonjour sylvanie

merci pour ton script
c'a fonctionne super bravo

je vais prendre un peu de temps pour comprendre le fonctionnement
et l'adapter

merci

a+ jl56

je ne connaissais pas la concaténations abrégée merci pour l'info
Avatar du membre
sylvanie
Niveau 11
Niveau 11
Messages : 1550
Enregistré le : jeu. 26 juil. 2007 21:31
Localisation : Paris
Status : Hors ligne

#6

Message par sylvanie »

attention à un détaille à pofiner, dont je viens de me rendre compte :
Il ne fait pas de nettoyage des espaces en trops en fin de chaîne, en gros dans l'exple que j'ai pris, pour le 05 11 2007, il y a 2 erreurs virus, mais comme j'ai fais un copier coller sans trop faire attention, j'ai mis des espaces en trops à la fin de "virus" et donc pour lui les deux chaîne sont différentes.

Dans l'absolut ce n'est pas très grave, car les sortie log, elles, sont bien formatées.
Sinon, pour être propre, on peu ajouter un StringStripWS sur le fichier entrée en mode 3 (enlève les espaces devant et dérière la chaîne en trops), mais bon ...
Toi qui cherche à mettre le doigt sur la solution, appuie sur F1.
Répondre