A scripted SMS Trace

Summary: SMS Trace (trace32.exe) is the core tool in every SMS administrator's toolkit. But do you really have time to be watching logs fly by? Why not script what you need to watch for and thus let your console do the watching?

SMS Trace has always impressed me - what kind of wonderful developer magic makes it possible to display new lines as they're added to logs in real time? What is the mysterious API that makes that possible? As a scripter I always wanted to hook into trace32 so it would 'shout' when the event I wanted would happen (highlighting helps, but can quickly scroll away). Or translate lines as they go by (what does that GUID mean?). Or relate one log to another (what does the scheduler do after the distribution manager does its tasks?)

Well today things built up to the point where I could no longer ignore this possibility. I wasn't particularly optimistic that vbscript could work such magic, but I really can't afford to be manually chasing rare yet important scenarios. With a bit of research I found that SMS Trace isn't quite as magical as we might think.

It turns out that long ago in the UNIX world they developed a tool called Tail.exe to show the last lines. Then they added a "follow" function to show new lines as they were added to the file - sound familiar? Of course such tools are also available in the Windows world, and they're simple enough that the source code is often shared.

How do such tools work? Well it's actually pretty basic - check the file frequently (say every 1/4 second) to see if the file size has changed. If so, open it and jump to the point you last read. Read the rest of the file to the end-of-file. Display the results and repeat. Is that disappointing, or what? That's not magical. It sounds really inefficient (that's a lot of file opening for active logs), but it seems to work well, even in vbscript. I ran such code all day and it had no adverse effect on my console or server (I didn't monitor the network, but if SMS Trace does the same thing then we've been getting away with it for years).

I'll include the code in a moment, but first a bit of the envisioning thing: it won't take a lot of scripting skills to build the real solutions around this kind of code. For example, it's Patch Tuesday (or Patch Wednesday if you're outside of North America), and you build your patch packages and deploy them. What's next? You watch the packages to make sure they get out to all your DPs (and thus your clients). Generally that goes well, but can you afford to just assume that it will be fine? If you work for a small to medium organization with a fairly stable and predictable environment the answer should be Yes. For the rest of us, we monitor everything closely in real time - with SMS Trace. So what if one of us writes the script to do that watching and shares it? Everyone benefits! The same can be done for all the other common SMS activities. So I hope some of you will experiment with this idea and then start sharing.

Code time (fully working sample this time):

logfile = "replmgr.log"  'it changes a lot so it's a good example

Const ForReading = 1
Set fso = CreateObject("Scripting.FileSystemObject")

prev_size = fso.GetFile( logfile ).Size
while 1=1
  file_found = false
  while not file_found 'handle rollovers
    on error resume next
    current_size = fso.GetFile( logfile ).Size  'on file rollovers, when the file switches from .log to .lo_, this line could fail, momentarily
    if err=0 then
      on error goto 0
      if current_size < prev_size then prev_size = 0  'it must have rolled over but not been caught when checking the size
      file_found = true
    else
      on error goto 0
      prev_size = 0  'to guarantee no data loss we should get the end of the previous version of the file first
      try = try + 1
      if try=10 then wscript.echo "couldn't find file to get its size" : wscript.quit
      wscript.sleep 1000  'wait a second before looking for the next one
    end if
  wend

  'display changes in the file
  if current_size <> prev_size then
    Set f = fso.OpenTextFile(logfile, ForReading)
    f.skip( prev_size )  'this can be slow on large files, especially at times of large changes to the file, but not bad (2 or 3 seconds at worst?)
    new_data = f.read( current_size - prev_size )  'there are other ways to do this, but this seems to work best
    f.close
    new_lines = split( new_data, vbCRLF )
    for each new_line in new_lines
      if new_line<>"" then wscript.echo new_line
    next
  end if
  prev_size = current_size

  wscript.sleep 250  'pause before checking again
wend

And what does the output look like? Just like SMS Trace. Run them side by side and you'll see the same output at the same time. Occasionally the script will hesitate, but even then only for a few seconds. Of course the real point is for you to add value by adding logic to only show the lines you want. Or in a more meaningful format. Or whatever.

Published Monday, June 04, 2007 11:43 PM by pthomsen

Comments

Tuesday, June 05, 2007 2:24 AM by jgilbert

# re: A scripted SMS Trace

Cool post!!! I've always wondered how that worked. I'm going to play with it in my lab :-)

So could you do something like:

if new_line="<something important to me>" then wscript.echo "<the something important that just happened>" so you don't have to actually see every line, but just the specific lines you're looking for? I wonder how much that would slow it down if the script had to compare each new_line object against a list of wanted messages. I can foresee specific scripts for varying actions, hwinv for one. You could really tweak it to look at different log files for different messages...way cool.

I'm guessing this comes with the "Use cscript or you'll get a lot of pop ups" disclaimor?

Tuesday, June 05, 2007 9:53 AM by A scripted SMS Trace « This One IT Site

# A scripted SMS Trace &laquo; This One IT Site

Pingback from  A scripted SMS Trace &laquo; This One IT Site

Tuesday, June 05, 2007 10:35 AM by pthomsen

# re: A scripted SMS Trace

Yes, jgilbert (Jeff), you're exactly right (use it to find messages you're interested in (and don't display the rest)). And you'd have to add a LOT of logic to slow it down much (computers are fast, and everything is stored in memory, so there's no real bottlenecks).

And yes, cscript.exe is the way to execute this script, like almost all of my scripts.