Hey, Scripting Guy! How can I monitor an application’s log file and issue an alert if the timestamp on that file hasn’t changed in the last 30 minutes?
— JA
Hey, JA. You know that’s a very interesting question, and one that – say, wait a second. You’re not JA from Stanwood, WA are you? Are you sure about that? Well, OK; we’ll take your word for it, and we’ll try to answer your question. But if you are from Stanwood, WA ….
Not that the Scripting Guy who writes this column has anything against Stanwood, WA, mind you; it’s just that the Scripting Guy who writes this column has something against Stanwood, WA. The other day this Scripting Guy found himself with a little time to kill in Stanwood, the Scripting Son having to arrive in town some 90 minutes prior to a doubleheader with the Skagit Sox. Being behind on his work, and having snuck out of the office at noon in order to get to Stanwood on time, the Scripting Guy who writes this column was glad to have 90 minutes to kill: that gave him just enough time to go get some ice cream before the game started.
Or so he thought. But here’s a tip for you: if you ever find yourself in Stanwood, WA, don’t bother looking for ice cream; they don’t have any. With seemingly-plenty of time on his hands the Scripting Guy who writes this column walked over to a nearby shopping center, one chockfull of stores and restaurants, none of which actually sold ice cream. (You know, real ice cream, like a hot fudge sundae.) At one point the Scripting Guy who writes this column saw a huge sign proclaiming Ice Cream; as he rounded the corner, however, he discovered that the place was locked up tight as a drum.
Note. So did the ice cream shop gone out of business, or did they simply lock the doors and pull the blinds when they saw this Scripting Guy headed their way? Good question …. |
Eventually the Scripting Guy who writes this column gave up on finding an old-fashioned hot fudge sundae and decided to get some ice cream at McDonald’s instead. “Oh, ice cream,” said the girl behind the counter. “We’re all out of ice cream ….”
Right ….
In the end, the Scripting Guy who writes this column never did get his ice cream, and the Scripting Son and his team went on to lose both ends of the doubleheader. Coincidence? We think not.
Oh, well; in the great good news/bad news scheme of life, that’s the bad news. The good news? With no hot fudge sundae to occupy his time, the Scripting Guy who writes this column was able to do something he hadn’t really planned on doing: write this column.
As you might expect, there are a number of different ways we could have approached the problem of monitoring a log file and issuing an alert if the timestamp on that file hasn’t changed in the last 30 minutes. After carefully weighing all these alternative approaches can we assume that the Scripting Guys chose the best possible method for carrying out this task? Heavens no. However, you can assume that the Scripting Guys chose the easiest possible method for carrying out this task:
strComputer = “.”Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
Set colFiles = objWMIService.ExecQuery _ (“Select * from CIM_Datafile Where Name = ‘C:\\Scripts\\Application.log'”)
For Each objFile in colFiles strOriginalTimestamp = objFile.LastModified Next
Wscript.Echo “Monitoring application log file: ” & Now Wscript.Echo
Do While True Wscript.Sleep 1800000 Set colFiles = objWMIService.ExecQuery _ (“Select * from CIM_Datafile Where Name = ‘C:\\Scripts\\Application.log'”)
For Each objFile in colFiles strLatestTimestamp = objFile.LastModified Next
If strLatestTimestamp <> strOriginalTimestamp Then strOriginalTimestamp = strLatestTimeStamp Else Wscript.Echo “ALERT: ” & Now Wscript.Echo “The application log file has not been modified in the last 30 minutes.” Wscript.Echo strOriginalTimestamp = strLatestTimeStamp End If Loop
Let’s see if we can explain how this works. To begin with, we connect to the WMI service on the local computer. This was one of the first decisions we had to make: do we use WMI to carry out this task, or do we use some alternate technology, such as the FileSystemObject? We opted to go with WMI, and for one simple reason: this enables us to write a script that can monitor a log file on a remote computer just as easily as it can monitor a log file on the local computer. Need to perform this task against a log file on the remote computer atl-fs-01? No problem; just assign the name of that computer to the variable strComputer:
strComputer = “atl-fs-01”
Our next step is to determine the last time the file was changed; we need to know the current value of the file’s LastModified property in order to tell whether or not that value (and thus the file itself) has changed in the past 30 minutes. With that in mind, we use this line of code to select all the instances of the CIM_Datafile class that have a Name (path) equal to C:\\Scripts\\Application.log:
Set colFiles = objWMIService.ExecQuery _ (“Select * from CIM_Datafile Where Name = ‘C:\\Scripts\\Application.log'”)
And yes, that is C:\\Scripts\\. Because the \ is a reserved character in WMI, any \ that appears in a WQL query needs to be “escaped;” that is, we need to preface it with another \.
Admittedly that’s a little strange. But nowhere near as strange as a town completely devoid of ice cream.
After making the connection we set up a For Each loop to loop through the collection of files returned by the query. (Needless to say, there can be only one such file in the collection.) We then use this line of code to assign the value of the LastModified property to a variable named strOriginalTimestamp:
strOriginalTimestamp = objFile.LastModified
All of that is required just to give us a starting point; now we need to do some real work. To that end, we set up a Do While loop designed to run forever and ever (or at least for as long as True is equal to True):
Do While True
What’s the first thing we do inside that loop? In a sense, nothing at all; the first thing we do is call the Sleep method and pause the script for 30 minutes:
Wscript.Sleep 1800000
Note. In case you’re wondering, the 1800000 represents 1,800,000 milliseconds. There are 1,000 milliseconds in a second; 60,000 milliseconds in a minute; and 1,800,000 milliseconds in 30 minutes (1,000 x 60 x 30). |
When those 30 minutes are up we check the current value of the log’s LastModified property; to do that, we reconnect to the file, then store the value of the LastModified property in a variable named strLatestTimestamp:
strLatestTimestamp = objFile.LastModified
That brings us to this line of code:
If strLatestTimestamp <> strOriginalTimestamp Then
What are we doing here? Well, here we’re comparing the original timestamp with the current timestamp. Suppose the two timestamps are different; what does that mean? That can only man one thing: the file must have been modified sometime during the past 30 minutes. Therefore, we simply assign the current timestamp (strLatestTimestamp) to the variable strOriginalTimestamp, loop around, pause the script for another 30 minutes, then perform this check again.
That was easy. Now, what if the two timestamps are identical? Again, there’s only one possible explanation: if the two timestamps are identical that means the file must not have been modified in the past 30 minutes. In that case, we use the following lines of code to echo a message back to the command window (and yes, like most monitoring scripts you really want to run this one in a command window under the CScript script host):
Wscript.Echo “ALERT: ” & Now Wscript.Echo “The application log file has not been modified in the last 30 minutes.” Wscript.Echo
That’s going to result in a message similar to this appearing onscreen:
ALERT: 7/20/2007 1:26:35 PM The application log file has not been modified in the last 30 minutes.
We then assign the current timestamp to the variable strOriginalTimestamp, loop around, pause the script for another 30 minutes, then perform the check again. This process continues until the end of time, or until you terminate the script or close the command window.
Whichever comes first. And we’re guessing all of those things will happen long before they get any ice cream in Stanwood.
Needless to say, you aren’t limited to echoing back an alert; if you want to you can send an email, write an event to the event log, or do pretty much anything else you want. We’ll leave that up to you.
We hope that answers your question, JA. If it turns out that you really are JA from Stanwood, WA then no doubt you have another question as well: you’re wondering if the Scripting Guy who writes this column will hold it against you just because he couldn’t find any ice cream in your town. Well, JA, the answer to your unasked question is this: you bet he does. But don’t worry; just send a hot fudge sundae to the following address and we’ll call it good:
The Scripting Guy Who Writes That Column
Microsoft Corporation
Building 42/4039
Redmond, WA 98052
P.S. Extra whipped cream, and no maraschino cherry. Thanks!
0 comments