ReadEventLog: Wie benutzen ??



  • Hi,

    also bevor ich jetzt ganz verzweifel' !
    Ich will den Application-Log mit meiner Anwendung lesen und Fehler auswerten (also keine Warnungen oder Infos im Log). Also kontrollieren, ob in den letzten Tagen Fehler aufgetreten sind und wenn ja, welche genau.

    Ein Versuch von mir:

    hEvents = OpenEventLog(NULL, "Application");
    if (!hEvents)
    {
        ...
    }
    
    while (dwStatus == ERROR_SUCCESS)
    {
        if (ReadEventLog(hEvents, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0, pEvRec, dwBufSize, &dwBytesRead, &dwBytesNextRecord))
        {
            if (++nCnt > 100)    // wie auch immer...
                break;
            if (pEvRec->EventType == EVENTLOG_ERROR_TYPE)		// handle only errors in the log...
            {
                LPCTSTR lpszName = reinterpret_cast<LPCTSTR>(reinterpret_cast<LPBYTE>(pEvRec) + sizeof(EVENTLOGRECORD));
                if (_tcscmp(lpszName, "Windows Search") >= 0 && ++nWinSearchCnt > 5)
                    continue;
                if (GetMessageString(lpszName, pEvRec, dwBytesRead, strTempLine))
                {
                    ...
    

    Wieso kriege ich, obwohl an einem Tag etliche Fehler aufgetreten sind, nur sehr wenige zurück und wieso startet die Funktion nicht beim aktuellsten Record ?? 😕

    Oder ist das eine Windows-interne Geschichte ?
    Wer kann mir da helfen ? Verstehe diesen Sch... einfach nicht !!



  • Hallo,

    Wieso kriege ich, obwohl an einem Tag etliche Fehler aufgetreten sind, nur sehr wenige zurück und wieso startet die Funktion nicht beim aktuellsten Record ??

    Weil du es so programmiert hast 🙂

    Ok, genauer:

    der erste wird übersprungen, weil du gleich den Zeiger über den ersten Eintrag verschiebst:

    LPCTSTR lpszName = reinterpret_cast<LPCTSTR>(reinterpret_cast<LPBYTE>(pEvRec) + sizeof(EVENTLOGRECORD));
    

    bevor du irgendwas damit anstellen willst.

    Zu wenig zurück? Kann an dwBufSize liegen, aber da man nicht sieht, wie groß das ist, bleibt alles, wenn auch vielleicht berechtigte, Spekulation. 😉

    MfG,

    Probe-Nutzer



  • Hi,

    danke für deine Antwort !! 👍

    ok, dann erstmal nur zum Cast: Wie komme ich dann an den Namen der Quelle ?
    Hast du da einen Vorschlag dazu ??

    Diese Casterei ist nicht so meine Sache...



  • sorry, da habe ich einen falschen Zeiger gesehen, für den Zugriff auf den Namen der Ereignisquelle ist das hier:

    LPCTSTR lpszName = reinterpret_cast<LPCTSTR>(reinterpret_cast<LPBYTE>(pEvRec) + sizeof(EVENTLOGRECORD));
    

    schon korrekt..., auch an der Stelle, wo es passiert.

    Aber: wie sieht denn dein Vorgehen aus, um in der Schleife zum nächsten Ereigniseintrag zu gelangen? Das ist in deinem gezeigten Ausschnitt nicht zu erkennen. Es sollte ungefähr so aussehen wie:

    pEvRec = reinterpret_cast<EVENTLOGRECORD *>
                    ( reinterpret_cast<LPBYTE>(pEvRec) + pEvRec->Length);
    

    MfG,

    Probe-Nutzer



  • Hey, ok dann stimmte der Cast !

    Was ich jetzt nicht verstehe:
    ich dachte, ich muss ReadEventLog in einer Schleife ausführen, also dass ich nach jedem Aufruf auf dem nächsten Eintrag steh.
    Wenn ich das aber nicht mache, und deinen 2. Vorschlag befolge, dann passts das soweit, ich kriege ein Eintrag nach dem Anderen !

    Heißt das, ich muss nur ReadEventLog einmal ausführen und dann durch den Buffer "wandern" sozusagen ?
    So siehts aus und ich glaube, ich hab das die ganze Zeit falsch verstanden ! 🙂

    Muss mir nur noch eine "Formulierung" überlegen, wie ich am besten den Buffer durchlaufen kann...

    Korrigier mich bitte, wenn ich irgendwo falsch liege !
    Aber erstmal wieder ein Danke von mir ! 👍



  • So, also natürlich enthält der Buffer mehrere Records, die man durchlaufen muss.
    Steht ja auch in der MSDN, dass ReadEventLog soviel liest wie in den Buffer passt !

    So könnte es z.B. aussehen:

    DWORD CReporting::GetNewestRecordNumber(HANDLE hEventLog)
    {
        DWORD dwOldestRec = 0, dwNumberRecs = 0, dwNewestRec = 0;
    
        if (!GetOldestEventLogRecord(hEventLog, &dwOldestRec) || !GetNumberOfEventLogRecords(hEventLog, &dwNumberRecs))
            dwNewestRec = 0;
    
        dwNewestRec = dwOldestRec + dwNumberRecs - 1;
        return dwNewestRec;
    }
    
    // ...
    DWORD dwStartRecord = GetNewestRecordNumber(hEvents);
    if (ReadEventLog(hEvents, EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ, dwStartRecord, pEvRec, dwBufSize, &dwBytesRead, &dwBytesNextRecord))
    {
        while (pEvRec->Length > 0)
        {
            LPCTSTR lpszName = reinterpret_cast<LPCTSTR>(reinterpret_cast<LPBYTE>(pEvRec) + sizeof(EVENTLOGRECORD));
            // Timestamp auswerten, Messagestring füllen usw...
            // ...
            dwStartRecord = pEvRec->RecordNumber - 1;
            pEvRec = reinterpret_cast<PEVENTLOGRECORD>(reinterpret_cast<LPBYTE>(pEvRec) + pEvRec->Length);
        }
    }
    // ...
    

    Mal eine Nacht drüberschlafen bringt durchaus was ! 🙂

    Auf jeden Fall vielen Dank !!
    Ohne Hilfe hätt' ich bestimmt noch ein Stück gebraucht, um dahin zu kommen, obwohl ja eig. alles dokumentiert ist. 😃


Log in to reply