Where I work, we run some pretty CPU-intensive reports. Users access the reports by clicking a web link, after which the server queries the hell out of database and then returns a neatly rendered PDF. Recently, we’ve run into some issues whereby the app server reaches its 5-minute timeout before the report server can spit back its PDF. The result is that the user’s session blows up and he has to start from scratch having never seen his report.
So for the last week, we’ve been hacking at a solution for this. The way it usually works throughout the day is the DBAs go and do their DBA thing by tweaking global this-that-or-the-other-parameter, and then they yell over the cubicle wall, “Ok, try it now!” Then one of the application guys clicks the link, starts a stopwatch (if he has one), and watches the clock mindlessly as it approaches the 5-minute session explosion threshold. We haven’t fixed the issue yet.
But since I had a few blocks of 5 minutes, and since I don’t have a stopwatch, I decided to create one with the tools at hand. And my tools were few because:
- The machine used to monitor the app for this exercise is a Windows machine with little or no dev tools beyond what’s out of the box
- I can’t download web software to this machine
That pretty much left me with a DOS prompt. But I like a challenge.
The code you see below is the quickest way I could come up with to tackle this. It uses Windows Script Host (WSH). I plan to write a follow-up to this post showing another way, which uses pure DOS.
The gist here is that when you kick this thing off, it’ll begin to spit out elapsed time updates to the console. See here:
'******************************** '* DESCRIPTION: WSH/VBS Stopwatch utility '* AUTHOR: http://www.DullSharpness.com '* Option Explicit 'Option Explicit forces variable declaration 'Declare some variables Dim Hour Dim Minute Dim Second Dim StartTime Dim Elapsed StartTime = Timer 'Start the Timer Wscript.Echo Time 'Print the current time Elapsed = Timer - StartTime 'Initialize Elapsed variable (not critical) 'Modify the next 2 lines for your needs; e.g. "Do While 1 = 1" will 'make it run indefinitely until you Ctrl+C out of it Do While Elapsed < 120 '120 means it'll only go for 2 minutes WScript.Sleep(1000) 'Pause for 1000 milliseconds before printing next update Elapsed = Timer - StartTime 'Calculate elapsed seconds WScript.Echo PrintHrMinSec(Elapsed) 'Print the time Loop Wscript.Echo Time 'Print the current time 'Main script ends here '*********************** '* This function calculates hours, minutes '* and seconds based on how many seconds '* are passed in and returns a nice format Public Function PrintHrMinSec(elap) Dim hr Dim min Dim sec Dim remainder elap = Int(elap) 'Just use the INTeger portion of the variable 'Using "\" returns just the integer portion of a quotient hr = elap \ 3600 '1 hour = 3600 seconds remainder = elap - hr * 3600 min = remainder \ 60 remainder = remainder - min * 60 sec = remainder 'Prepend leading zeroes if necessary If Len(sec) = 1 Then sec = "0" & sec If Len(min) = 1 Then min = "0" & min 'Only show the Hours field if it's non-zero If hr = 0 Then PrintHrMinSec = min & ":" & sec Else PrintHrMinSec = hr & ":" & min & ":" & sec End If End Function
Assuming you save this text to a file named “VBSTimer.vbs”, run it using:
cscript VBSTimer.vbs |
Things to note about this script:
- It utilizes very little CPU, and thus runs nicely in the background.
- It may fail after 2^15 (32,768) seconds or at some other notable power of 2 number. I’m not sure.
- You definitely want to run this using the CScript engine and NOT WScript. WScript causes an interactive MsgBox to pop up everytime it hits a “WScript.Echo” command, whereas CScript echoes passively to the DOS console.
- You can suppress the WSH version and copyright info by issuing the “//NOLOGO” switch on the command line when you run the script
Leave a comment if you find any of this useful, and enjoy!