.\Matthew Long

{An unsorted collection of thoughts}

SCOM : Revisiting the DayTimeExpression option of System.ExpressionFilter

Posted by Matthew on August 17, 2012

You may remember a few weeks ago I did an article on the flexibility and power of the System.ExpressionFilter. In that post I commented that I wouldn’t go into any depth on the DayTimeExpression expression type as you could accomplish most of the day/time comparison tasks with a System.ScheduleFilter instead.  Well, no sooner than writing that, I found myself authoring a workflow where that was not the case.

The customer was looking for a three state unit monitor, that had some complex health behavior:

  1. If the result of a scheduled Job was successful, switch to a Healthy state.
  2. If The result of the job is a Failure, switch to a Critical state.
  3. After 15 Minutes since the job has started, if it is not Successful or Failed, switch to a Warning State.
    1. After 30 minutes, if it has still not succeeded, go into a critical State.

Normally this kind of complex logic would be included as part of a custom script, however in this case we were using a built-in module to perform the query of our Job status, so it seemed very inefficient to then have to go into a script just to calculate the time differential (especially if due to the return code, the time calculation is irrelevant).

Why couldn’t we use a System.ScheduleFilter?

The normal approach when doing time comparisons is to use a System.ScheduleFilter to block the workflow from posting items to the appropriate health states in a MonitorType.  However, here we had a combination approach where we needed to use boolean AND and OR operators, which is something that the ScheduleFilter cannot provide, and the SCOM workflow engine only allows a single workflow branch to lead to a given Health State.

Our module didn’t return the current time as an additional property, so in order to get the current date I decided to just use the timestamp found on every Dataitem in a SCOM workflow.  This required a little bit of XPath knowledge however, as nearly all the XPath Query examples I’ve seen documented with SCOM are for accessing the child properties of a DataItem, not its own attributes.

So without further ado here are the Expressions I eventually came up with..

Healthy Expression

    <RegExExpression>
      <ValueExpression>
        <XPathQuery Type="String">//*[local-name()="StdOut"]
      </ValueExpression>
      <Operator>MatchesRegularExpression</Operator>
      <Pattern>^(.*SU)$</Pattern>
    </RegExExpression>

Nothing groundbreaking here, if at any time the result code matches the regular expression “SU” then we know our job succeeded (those of you who have done cross-platform monitoring with SCOM may recognize the XPath Query i’m using, however that’s not really the focus of this article).

Warning Filter

    <And>
      <Expression>
        <RegExExpression>
          <ValueExpression>
            <XPathQuery Type="String">//*[local-name()="StdOut"]
          </ValueExpression>
          <Operator>DoesNotMatchRegularExpression</Operator>
          <Pattern>^(.*SU|.*FA|[\s]*[\s]*)$</Pattern>
        </RegExExpression>
      </Expression>
      <Expression>
        <DayTimeExpression>
          <ValueExpression>
            <XPathQuery Type="DateTime">./@time</ValueExpression>
          <StartTime>79200
          <EndTime>80100
          <Days>62</Days>
          <InRange>true
        </DayTimeExpression>
      </Expression>
    </And>

The first part of our Warning expression (lines 2-9) is just checking that the Job status code is not one which instantly pushes us into another health state (remember, a return code of Failure is an automatic critical health state, regardless of time).  Lines 12-20 are what we are interested in here.  We’ve specified that we want to do a DayTime comparison, and we are going to compare the “./@time” XPath query against a time range.  I’ll come back to the XPath in a second, first let me explain the rest of the parameters.

  • StartTime is the start of the time range, specified in Seconds from Midnight.
  • EndTime is the end of the time range, specified in Seconds from Midnight.
  • Days is the usual Days of the week mask used by SCOM.  To specify which days are in the range, simply add up the corresponding values from the table below (so Mon through Friday is 62).
    • Sunday = 1
    • Monday = 2
    • Tuesday = 4
    • Wednesday = 8
    • Thursday = 16
    • Friday = 32
    • Saturday = 64
  • InRange is a boolean operator that specifies if this expression is TRUE if the input time is inside, or outside the time range specified.

So what i’ve done here is specified that the warning filter will match only for the 15-30 minute period after the job has started (remember this is a scheduled job, so it’s the same time each day), and only if the status code is not SU (Healthy) or FA (Critical).

The XPath Query on line 14 of “./@time” is a little weird, and is to do with the implementation of XPath in the ExpressionFilter module.  Essentially it’s already scoped to look at the elements within a workflow Data item, so we have to explicitly go back up the tree and say we want the Time attribute of the DataItem itself.  The value you use to perform your date time calculation must be in the DateTime format (2012-08-17T14:23:16.291Z) for this to succeed.  Thankfully the Time value on DataItems always is.

Critical Filter

    <Or>
      <Expression>
        <RegExExpression>
          <ValueExpression>
            //*[local-name()="StdOut"]
          </ValueExpression>
          <Operator>MatchesRegularExpression</Operator>
          <Pattern>^(.*FA|[\s]*[\s]*)$</Pattern>
        </RegExExpression>
      </Expression>
      <Expression>
        <And>
          <Expression>
            <RegExExpression>
              <ValueExpression>
                //*[local-name()="StdOut"]
              </ValueExpression>
              <Operator>DoesNotMatchRegularExpression</Operator>
              <Pattern>^(.*SU|[\s]*[\s]*)$</Pattern>
            </RegExExpression>
          </Expression>
          <Expression>
            <DayTimeExpression>
              <ValueExpression>
                <XPathQuery Type="DateTime">./@time</XPathQuery>
              </ValueExpression>
              <StartTime>78300</StartTime>
              <EndTime>80100</EndTime>
              <Days>62</Days>
              <InRange>false</InRange>
            </DayTimeExpression>
          </Expression>
        </And>
      </Expression>
    </Or>

And finally, we have the Critical health state Expression filter.  This uses an OR condition to short-circuit and allow us to instantly go to a critical health state if the job result is a failure without having to check the time.  Otherwise, we carry on and evaluate the AND expression and make sure that the job result isn’t a Success code and we are now outside our 30 minute window since the job started.  Note that the InRange parameter on line 30 is now false, so that the expression will only evaluate to true if the current time is outside our time window of 0-30 minutes since the job started.

And there we have it!  Unfortunately the SCOM 2007 Authoring console doesn’t allow you to use the wizard when trying to use DayTime/Exists expressions, so you’ll need to hit the “edit” button and get your hands dirty with XML yourself.  My suggestion would be to create your logic using the wizard with a placeholder line in place where you want your DayTimeExpression, and then to edit it by hand to include that line afterwards.  Just don’t try to open your ExpressionFilter in the wizard using the “configure” button afterwards, as it will break your expression.  You’ll have to keep using the edit button and editing it by hand.

As always, I hope that helped someone out, and feel free to post a comment if I haven’t made anything clear or you have practical example you’d like to work through.

Advertisements

One Response to “SCOM : Revisiting the DayTimeExpression option of System.ExpressionFilter”

  1. […] Matthew Long’s post on the useful DayTimeExpression module of the System.ExpressionFilter data filter is the only useful information I could find on its use, save for the MSDN documentation. However, in using the module, I’ve noticed what appears to be a bug in its implementation. […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s