process and memory monitoring in mom 2005 [revisited]…
awhile back, a long while back, as it turns out, i wrote a couple of scripts that you could inject as responses in mom 2005 to generate a list of top cpu or memory processes. here are the links to the old posts, in case you’ve forgotten about it.
mom: monitoring cpu spikes the right way
mom: memory processes
anyway, i realized today while daydreaming in between meetings and outage summaries, that i could write the information directly to the alert stream. it’s so simple i could kick myself.
all i needed was one additional line. now look at this… this is the old way i did it.
sMessage = "The processes using greater than " & Z & "k of memory are:" & VbCrLf & VbCrLf For i = 0 To x - 1 If aProcess(0,i) > z Then sMessage = sMessage & aProcess(1,i) & " : " & aProcess(0,i) & VbCrLf End If Next sMessage = sMessage & VbCrLf & "(There are " & x & " processes running at this time.)" CreateEvent 40150,EVENT_TYPE_INFORMATION,"Memory Processes Script",sMessage
basically, you’d run this as a response script to a condition that was occurring. you’d have to look at both alerts to see what was going on. however, i found that since it’s executing as a response, it’s a part of the overall alert. i’m sure someone had already written about that… but it just now made sense.
here it is revised:
Set oAlert = ScriptContext.Alert ... sMessage = "The processes using greater than " & Z & "k of memory are:" & VbCrLf & VbCrLf For i = 0 To x - 1 If aProcess(0,i) > z Then sMessage = sMessage & aProcess(1,i) & " : " & aProcess(0,i) & VbCrLf End If Next sMessage = sMessage & VbCrLf & "(There are " & x & " processes running at this time.)" oAlert.Description = oAlert.Description & VbCrLf & VbCrLf & "[Top Memory Processes]" & VbCrLf & sMessage
as you can see, i had to create the object for scriptcontext. instead of using the createevent function, i just write the alert object’s description with my additional information i’ve captured. :) instead of the standard, crappy information i get back from a mom performance counter, i now get back something that looks a little more polished…
Memory: Available MBytes: value = 276 [Top Memory Processes] The processes using greater than 14681k of memory are: myAntiVirus.exe : 119680 mySearch.exe : 284836 myPretendTestApp.exe : 16680 myApp1.exe : 53008 myApp2.exe : 28356 MOMService.exe : 17124 (There are 43 processes running at this time.)
i’ll post the links for the new scripts soon. in the mean time, here are the scripts, if you want to pull them off the site:
TOP MEMORY:
'========================================================================== 'NAME : Display Memory Processes 'AUTHOR : Marcus C. Oh 'DATE : 7/2/2008 'COMMENT : Run as a response script to a rule that checks CPU utilization ' : Lists processes utilizing % value of CPU over threshold ' : Updated to write the memory information into the alert stream '========================================================================== Const EVENT_TYPE_SUCCESS = 0 Const EVENT_TYPE_ERROR = 1 Const EVENT_TYPE_WARNING = 2 Const EVENT_TYPE_INFORMATION = 4 Const EVENT_TYPE_AUDITSUCCESS = 8 Const EVENT_TYPE_AUDITFAILURE = 16 Set oAlert = ScriptContext.Alert Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & ScriptContext.TargetNetbiosComputer & "\root\cimv2") Set oProcesses = oWMIService.ExecQuery("SELECT * FROM Win32_Process") Dim aProcess() x = 0 For Each oProcess In oProcesses ReDim Preserve aProcess(2,x) ' ReDim can only update the last dimension aProcess(0,x) = oProcess.WorkingSetSize / 1024 aProcess(1,x) = oProcess.Name x = x + 1 Next y = 0 For j = 0 To x - 1 y = y + aProcess(0,j) ' Count up the total memory used Next z = Round(y/x) ' Divide total memory used by total processed and round it up sMessage = "The processes using greater than " & Z & "k of memory are:" & VbCrLf & VbCrLf For i = 0 To x - 1 If aProcess(0,i) > z Then sMessage = sMessage & aProcess(1,i) & " : " & aProcess(0,i) & VbCrLf End If Next sMessage = sMessage & VbCrLf & "(There are " & x & " processes running at this time.)" oAlert.Description = oAlert.Description & VbCrLf & VbCrLf & "[Top Memory Processes]" & VbCrLf & sMessage Sub CreateEvent(iEventNumber,iEventType,sEventSource,sEventMessage) Set oEvent = ScriptContext.CreateEvent() oEvent.EventNumber = iEventNumber oEvent.EventType = iEventType oEvent.EventSource = sEventSource oEvent.Message = sEventMessage ScriptContext.Submit oEvent End Sub
TOP CPU:
'============================================================================= 'NAME : TopProcesses Script 'AUTHOR : Marcus C. Oh 'DATE : 7/2/2008 'COMMENT : Run as a response script to a rule that checks CPU utilization ' : Bastardized from Microsoft Windows Base OS CPU Overload Script ' : Lists processes utilizing % value of CPU over threshold ' : Modified to post to Alert stream '============================================================================= Const EVENT_TYPE_SUCCESS = 0 Const EVENT_TYPE_ERROR = 1 Const EVENT_TYPE_WARNING = 2 Const EVENT_TYPE_INFORMATION = 4 Const EVENT_TYPE_AUDITSUCCESS = 8 Const EVENT_TYPE_AUDITFAILURE = 16 Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & ScriptContext.TargetNetbiosComputer & "\root\cimv2") Set oAlert = ScriptContext.Alert lNumProcessors = GetNumProcessors() iPercentage = ScriptContext.Parameters.Get("Percentage") sMessage = ListCriticalProcesses(iPercentage,lNumProcessors) oAlert.Description = oAlert.Description & VbCrLf & VbCrLf & "[Top CPU Processes]" & VbCrLf & sMessage Sub CreateEvent(iEventNumber,iEventType,sEventSource,sEventMessage) Set oEvent = ScriptContext.CreateEvent() oEvent.EventNumber = iEventNumber oEvent.EventType = iEventType oEvent.EventSource = sEventSource oEvent.Message = sEventMessage ScriptContext.Submit oEvent End Sub Function WMIGetObject(ByVal sNamespace) Dim oWMI Dim e Set e = New Error On Error Resume Next Set oWMI = GetObject(sNamespace) e.Save On Error Goto 0 If IsEmpty(oWMI) Then ThrowScriptError "Unable to open WMI Namespace '" & sNamespace & "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", e End If Set WMIGetObject = oWMI End Function Function GetNumProcessors() Dim oReg, sValue Const HKEY_LOCAL_MACHINE = &h80000002 Const REGPATH_NUMBER_OF_CPUS = "SYSTEM\CurrentControlSet\Control\Session Manager\Environment\" Const REGKEY_NUMBER_OF_CPUS = "NUMBER_OF_PROCESSORS" Set oReg = WMIGetObject("winmgmts://" & ScriptContext.TargetNetbiosComputer & "/root/default:StdRegProv") oReg.GetStringValue HKEY_LOCAL_MACHINE, REGPATH_NUMBER_OF_CPUS, REGKEY_NUMBER_OF_CPUS, sValue GetNumProcessors = sValue End Function Function ListCriticalProcesses(Percentage,lNumProcessors) On Error Resume Next Dim oDictionary, oProcesses, oProcess Set oDictionary = CreateObject("Scripting.Dictionary") Set oProcesses = oWMIService.ExecQuery("SELECT * FROM Win32_PerfRawData_PerfProc_Process") For Each oProcess in oProcesses oDictionary.Item(oProcess.Name & oProcess.IDProcess & "%") = oProcess.PercentProcessorTime oDictionary.Item(oProcess.Name & oProcess.IDProcess & "#") = oProcess.Timestamp_Sys100NS Next Set oProcesses = Nothing ScriptContext.Sleep(500) Dim sProcesses, lNumProcesses Set oProcesses = oWMIService.ExecQuery("SELECT * FROM Win32_PerfRawData_PerfProc_Process") For Each oProcess In oProcesses lNumProcesses = lNumProcesses + 1 Dim fPercentProcessor If oDictionary.Exists(oProcess.Name & oProcess.IDProcess & "%") Then fPercentProcessor = (oProcess.PercentProcessorTime - CDbl(oDictionary.Item(oProcess.Name & oProcess.IDProcess & "%"))) / _ (oProcess.Timestamp_Sys100NS - CDbl(oDictionary.Item(oProcess.Name & oProcess.IDProcess & "#"))) * 100 If (fPercentProcessor > (Percentage * lNumProcessors)) And (oProcess.IDProcess <> 0) Then sProcesses = sProcesses & oProcess.Name & " (" & oProcess.IDProcess & ") :" & _ CInt(fPercentProcessor / lNumProcessors) & "%" & VbCrLf End If End If Next Set oProcesses = Nothing If Len(sProcesses) > 0 Then ListCriticalProcesses = "The processes using greater than " & Percentage & "% CPU at present are:" & vbCrLf & _ sProcesses & VbCrLf & _ "(There are " & lNumProcesses & " running at this time.)" End If Set oDictionary = Nothing End Function Function ThrowScriptErrorNoAbort(ByVal sMessage, ByVal oErr) Dim sErrDescription, sErrNumber sErrDescription = oErr.Description sErrNumber = oErr.Number On Error Resume Next Dim oScriptErrorEvent Set oScriptErrorEvent = ScriptContext.CreateEvent() With oScriptErrorEvent .EventNumber = 40000 .EventType = EVENT_TYPE_ERROR .Message = sMessage .SetEventParameter """Top Processes""" .SetEventParameter sMessage .SetEventParameter sErrDescription .SetEventParameter sErrNumber End With ScriptContext.Submit oScriptErrorEvent ScriptContext.Echo "ThrowScriptError('" & sMessage & "')" End Function Class Error Private m_lNumber Private m_sSource Private m_sDescription Private m_sHelpContext Private m_sHelpFile Public Sub Save() m_lNumber = Err.number m_sSource = Err.Source m_sDescription = Err.Description m_sHelpContext = Err.HelpContext m_sHelpFile = Err.helpfile End Sub Public Sub Raise() Err.Raise m_lNumber, m_sSource, m_sDescription, m_sHelpFile, m_sHelpContext End Sub Public Sub Clear() m_lNumber = 0 m_sSource = "" m_sDescription = "" m_sHelpContext = "" m_sHelpFile = "" End Sub Public Default Property Get Number() Number = m_lNumber End Property Public Property Get Source() Source = m_sSource End Property Public Property Get Description() Description = m_sDescription End Property Public Property Get HelpContext() HelpContext = m_sHelpContext End Property Public Property Get HelpFile() HelpFile = m_sHelpFile End Property End Class
I just came across your blog, this is exactly the type of stuff I need for our MoM 2005 env. Thank you, I'll be testing these script in dev before pushing to prod but I have a feeling they rock!
ReplyDeleteExcellent script, I will be using this. Who knew someone was still writing great stuff for MoM 2005. I think your blog is a goldmine.
ReplyDeleteglad you like it man. hope you find it works well for you...
ReplyDeletethe new TOP CPU script is causing the following error:
ReplyDeleteAn error occurred on line 18 while executing script 'Top Processes'
Source: Microsoft VBScript runtime error
Description: Class doesn't support Automation
maybe there's a line incorrect in your script. email your copy over to me. i'll have a look.
ReplyDelete