Kim Crosser
Kim Crosser

Reputation: 433

And/Or XPath query to select some Event Log records

I have googled lots of possible answers with no luck. I am trying to extract the following from the Event Log (pseudo-code):

select events
where
    event date/time between FromDateTime and ToDateTime
and
   ((Level<=2)  //  error, critical only
    or 
    ((Level<=x) and Provider[Name] in a specific list)  // any messages for these apps
   )

(The second "Level" expression is to allow the user to specify whether to include Informational messages or limit to Warnings and above, so I can't just discard it.)

The following is the (latest) expression I am trying to use - unsucessfully.

    string queryString = 
"*[System[TimeCreated[@SystemTime>='" + dFrom + "' and @SystemTime<='" + dTo + "']]] " +
" and " +
"(*[System[Level<=2]]" +
" or " +
" ( " + 
" *[System[Provider[@Name='<1st name>' or @Name='<2nd name>' or @Name='<3rd name>]] " + 
" and " +
"System[Level<=" + maxLevel.ToString() + "]]" +
")" +
");"

Am I trying to make an expression that is too hard for the Event Log query evaluator, or do I just have a simple error in the expression? I have been trying various forms of the expression. It appears that the "Level" filters are just being ignored, but why?

Upvotes: 1

Views: 1513

Answers (2)

Kim Crosser
Kim Crosser

Reputation: 433

*** ARRGGHH!! - I think I found it. The Event Log Level enumeration is:

1 - Critical alert
2 - Error
3 - Warning
4 - Informational
5 - Logs at all levels
  ... and ...
0 - Undefined - indicates logs at all levels

It turns out that some of the "Information" log entries from Microsoft components use Level 0 instead of 4, so these are being picked up by the filter. My assumption that log entries (especially Microsoft's) would use the appropriate Level was false.

I will need to explicitly look for (Level=1 or Level=2) - Level <= 2 will pick up various Microsoft "Information" log entries.

For anyone interested - the final working query is:

*[System[TimeCreated[@SystemTime>='2018-07-30T17:22:30.000Z' 
    and @SystemTime<='2018-07-30T20:22:30.000Z']  
and (Level=1 or Level=2 or
  (Provider[@Name='Application Error' or @Name='Application Hang']
  and (Level=1 or Level=2 or Level=3 or Level=4)))]]

Upvotes: 2

Mads Hansen
Mads Hansen

Reputation: 66783

There are two issues that I can see in the code that you had posted.

  • the single quote is not closed on the 3rd name: @Name='<3rd name>]] should be @Name='<3rd name>']]
  • the second filter for */System/Level should be *[System[Level<=" + maxLevel.ToString() + "]]] "

From your pseudo code and what you have shared, it looks like you could consolidate and move some of your logic inside of the predicate filter for */System and use an XPath such as:

string queryString = 
"*[System[TimeCreated[@SystemTime>='" + dFrom + "' and @SystemTime<='" + dTo + "']" +
"  and (Level<=2 or " +
"    (Provider[@Name='<1st name>' or @Name='<2nd name>' or @Name='<3rd name>'] " + 
"     and Level<=" + maxLevel.ToString() + "))" + 
"]];"

Upvotes: 0

Related Questions