Client Delete Unused Transactions

AVIcode.DotNet.SystemCenter.Client.DeleteUnusedTransactionsWA (WriteActionModuleType)

Element properties:

TypeWriteActionModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
InputTypeSystem.BaseData
OutputTypeSystem.BaseData

Member Modules:

ID Module Type TypeId RunAs 
DeleteWA WriteAction Microsoft.Windows.ScriptWriteAction Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalDaysint$Config/IntervalDays$Interval DaysIn case if discovery of a transaction happened more that 'Interval Days' ago, a transaction will be removed from monitoring.
TimeoutSecondsint$Config/TimeoutSeconds$Timeout SecondsModule execution timeout (measured in seconds).

Source Code:

<WriteActionModuleType ID="AVIcode.DotNet.SystemCenter.Client.DeleteUnusedTransactionsWA" Accessibility="Internal">
<Configuration>
<xsd:element name="IntervalDays" type="xsd:integer"/>
<xsd:element name="TimeoutSeconds" type="xsd:integer"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalDays" Selector="$Config/IntervalDays$" ParameterType="int"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation>
<Composite>
<MemberModules>
<WriteAction ID="DeleteWA" TypeID="Windows!Microsoft.Windows.ScriptWriteAction">
<ScriptName>AVIcodeClientDeleteUnusedTransactionsWA.vbs</ScriptName>
<Arguments>$Config/IntervalDays$</Arguments>
<ScriptBody><Script>
On Error Resume Next

SetLocale("en-us")
HandleErrorContinue("Cannot set en-us locale")

Const Source = "AVIcode uX Monitoring Management Pack for OpsMgr 2007"

Dim WShell : Set WShell = CreateObject("wscript.shell")
Dim FSO : Set FSO = CreateObject("Scripting.FileSystemObject")
HandleError("CreateObject('Scripting.FileSystemObject')")

Dim programmFilesFolder : programmFilesFolder = GetProgrammFilesFolder()
HandleError("GetProgrammFilesFolder()")

Dim AVIcodeInstallPath : AVIcodeInstallPath = programmFilesFolder &amp; "\AVIcode\Intercept\SCOM2007\EnterpriseMP\"

Dim Args : Set Args = WScript.Arguments
if Args.Count &lt; 1 then
WScript.Quit
end if

Dim Days : Days = Args(0)

ReadLogFiles Days

Function CreateFileScript(filePath)
Dim f
wshell.CurrentDirectory = AVIcodeInstallPath
set f = FSO.OpenTextFile("DeleteUXTransaction.vbs", 2, True )
f.WriteLine(" 'Sample Parameters:")
f.WriteLine("'""My_Duwamish7"" ""@/Duwamish7/book.aspx"" ""duwamish7_book.aspx"" ""100""")
f.WriteLine("")
f.WriteLine("On Error Resume Next")
f.WriteLine(" ")
f.WriteLine("SetLocale(""en-us"")")
f.WriteLine("HandleErrorContinue(""Cannot set en-us locale"")")
f.WriteLine("")
f.WriteLine("Dim Args : Set Args = WScript.Arguments")
f.WriteLine("if Args.Count &lt; 3 then")
f.WriteLine(" WScript.Quit")
f.WriteLine("end if")
f.WriteLine("")
f.WriteLine("Dim ApplicationName : ApplicationName = Args(0)")
f.WriteLine("Dim PageName : PageName = Args(1)")
f.WriteLine("PageName = Right(PageName,Len(PageName)-1) 'Remove first @")
f.WriteLine("Dim InstanceName : InstanceName = Args(2)")
f.WriteLine("")
f.WriteLine("Dim WShell : Set WShell = CreateObject(""wscript.shell"")")
f.WriteLine("HandleError(""CreateObject('wscript.shell')"")")
f.WriteLine("")
f.WriteLine("RemoveTransactionFromMonitoring ApplicationName, PageName, InstanceName")
f.WriteLine(" ")
f.WriteLine("Sub RemoveTransactionFromMonitoring(ApplicationName, PageName, InstanceName)")
f.WriteLine(" On Error Resume Next")
f.WriteLine(" ")
f.WriteLine(" Dim Executor : Set Executor = CreateObject(""Agent.CSMStatisticCountersScripting.CExecutor"")")
f.WriteLine(" HandleError(""Cannot create 'Agent.CSMStatisticCountersScripting.CExecutor' object."")")
f.WriteLine(" ")
f.WriteLine(" Dim Properties : Set Properties = CreateObject(""Agent.CSMStatisticCountersScripting.CProperties"")")
f.WriteLine(" HandleError(""Cannot create 'Agent.CSMStatisticCountersScripting.CProperties' object."")")
f.WriteLine(" ")
f.WriteLine(" Executor.Init Properties")
f.WriteLine(" HandleError(""'Agent.CSMStatisticCountersScripting.CExecutor' cannot be initialized"")")
f.WriteLine(" ")
f.WriteLine(" Executor.Execute ""OpenTransactionConfig"", Properties")
f.WriteLine(" HandleError(""'Agent.CSMStatisticCountersScripting.CExecutor' cannot open transactions configuration file"")")
f.WriteLine(" ")
f.WriteLine(" properties (""pagename"") = PageName")
f.WriteLine(" properties (""appname"") = ApplicationName")
f.WriteLine(" properties (""instanceName"") = InstanceName")
f.WriteLine("")
f.WriteLine(" Executor.Execute ""RemoveTransactionCommand"", Properties")
f.WriteLine(" HandleError(""Cannot execute RemoveTransactionCommand command in SCScriptingLibrary."")")
f.WriteLine("")
f.WriteLine(" Executor.Execute ""SaveTransactionConfig"", Properties")
f.WriteLine(" HandleError(""Cannot execute Save command."") ")
f.WriteLine("End Sub ")
f.WriteLine("")
f.WriteLine("")
f.WriteLine("Sub HandleError(customMessage)")
f.WriteLine(" If Not (Err.number = 0) Then")
f.WriteLine(" LogError customMessage")
f.WriteLine(" Wscript.Quit 1")
f.WriteLine(" End If ")
f.WriteLine("End Sub")
f.WriteLine("")
f.WriteLine("Function HandleErrorContinue(customMessage)")
f.WriteLine(" HandleErrorContinue = False")
f.WriteLine(" If Not (Err.number = 0) Then")
f.WriteLine(" LogError customMessage")
f.WriteLine(" Err.Clear")
f.WriteLine(" HandleErrorContinue = True")
f.WriteLine(" End If")
f.WriteLine("End Function")
f.WriteLine("")
f.WriteLine("Sub LogError(customMessage)")
f.WriteLine(" Dim msg")
f.WriteLine(" If Not (Err.number = 0) Then")
f.WriteLine(" msg = Replace("" Error: #P1# Description: #P2# "", ""#P1#"", CStr(Err.number) )")
f.WriteLine(" msg = Replace(msg, ""#P2#"", Err.Description )")
f.WriteLine(" msg = customMessage &amp; VbCrLf &amp; msg &amp; VbCrLf")
f.WriteLine(" WScript.StdOut.Write msg")
f.WriteLine(" End If")
f.WriteLine("End Sub")
f.close

End Function

Sub ReadLogFiles(Days)
On Error Resume Next

Dim ForReading : ForReading = 1
Dim logsFolderStr : logsFolderStr = AVIcodeInstallPath &amp; "Temp\"

If FSO.FolderExists(logsFolderStr) = True Then
Dim logsFolder : Set logsFolder = FSO.GetFolder(logsFolderStr)
HandleError("Could not get folder: " &amp; logsFolderStr)

Dim filesColl : Set filesColl = logsFolder.Files
HandleError("Could not get files from folder: " &amp; logsFolderStr)

For Each file in filesColl
Dim fileNameStart : fileNameStart = Left(file.Name, 14)

If (fileNameStart = "uXTransaction_") Then
Dim fullFileName : fullFileName = logsFolderStr &amp; file.Name
Dim fil : set fil = fso.getFile(fullFileName)
HandleError("Cannot get file information: " &amp; fullFileName)
if fil.size &gt; 0 then
Dim content
Dim dateTime
Dim discoveryInterval

Dim Counter : Counter = 0
do
Err.Clear()
Dim textStream : Set textStream = FSO.OpenTextFile(fullFileName, ForReading, False)
HandleError("Could not open text file: " &amp; fullFileName)

content = textStream.ReadAll()
HandleError("Could not read content from file: " &amp; fullFileName)

dateTime = GetValueForElement(content, "[UPDATE_DATE]")
discoveryInterval = GetValueForElement(content, "[DISCOVERY_INTERVAL]")

If (Len(content) &lt;= 1) OR (NOT (Err = 0)) Then
WScript.Sleep Int(300 * Rnd)
Counter = Counter+1
End If
loop While (Err &lt;&gt; 0) AND (Counter &lt; 40)

If Counter &lt; 40 Then
' good
Else
' bad
If NOT (Err = 0) Then
HandleError("Could not get UPDATE_DATE or DISCOVERY_INTERVAL from file: " &amp; fullFileName)
Else
End If
End If

If discoveryInterval = "" Then
discoveryInterval = 86400
End If

If IsDate(dateTime) Then
Dim diff : diff = DateDiff("s", CDate(dateTime), Now())
HandleError("Err in DateDiff")

Dim secondsDiff : secondsDiff = CInt(Days) * 86400
Dim needDelete : needDelete = False

If (CLng(diff) &gt; CLng(secondsDiff)) Then
If (CLng(diff) &gt; CLng(discoveryInterval)) Then
ProcessTransaction content, fullFileName
needDelete = True
End If
End If
End If

textStream.Close()
HandleError("Failed to close the file: " &amp; fullFileName)

If needDelete = True Then
FSO.DeleteFile(fullFileName)
HandleError("Failed to delete the file: " &amp; fullFileName)
End If
End If
End If
Next

End If
End Sub

Function RemoveTransactionFromMonitoring(applicationName, pageName, instanceName)
On Error Resume Next

If CreateTransactionMutex() Then
Dim sPath : sPath = """" &amp; AVIcodeInstallPath &amp; "DeleteUXTransaction.vbs"" """ &amp; applicationName &amp; """ """ &amp; pageName &amp; """ """ &amp; instanceName
CreateFileScript(AVIcodeInstallPath &amp; "DeleteUXTransaction.vbs")

RemoveTransactionFromMonitoring = RunScriptx86(sPath)
Else
LogEvent "Cannot remove transaction '" &amp; instanceName &amp; "' from monitoring. Object Statistic Library in use.", 2
ReturnWithoutObject()
End If

CloseTransactionMutex()

End Function

Private Function ProcessTransaction(content, fileName)
On Error Resume Next

Dim applicationName : applicationName = GetValueForElement(content, "[APPLICATION_NAME]")
HandleError("Could not get applicationName from file: " &amp; fileName)

Dim pageName : pageName = GetValueForElement(content, "[PAGE_NAME]")
HandleError("Could not get pageName from file: " &amp; fileName)

Dim instanceName : instanceName = GetValueForElement(content, "[INSTANCE_NAME]")
HandleError("Could not get instanceName from file: " &amp; fileName)

RemoveTransactionFromMonitoring applicationName, pageName, instanceName
HandleError("Cannot delete transaction from monitoring.")
End Function

Private Function GetValueForElement(content, elementName)
On Error Resume Next

GetValueForElement = ""
Dim startElementName : startElementName = 0
startElementName = InStr(1, content, elementName, 1)
If (startElementName &gt; 0) Then
startElementName = startElementName + Len(elementName)
Dim endElementName : endElementName = InStr(startElementName, content, vbcrlf, 1)
if(endElementName &gt; 0) Then
GetValueForElement = Trim(Mid (content, startElementName, endElementName - startElementName))
End If
Else
Err.Raise 20000, Source, "Application log parsing. Cannot find element '" &amp; elementName &amp; "' in " &amp; content, 0, 0
End If
End Function

Function CorrectObjectName(nameStr)
On Error Resume Next

Dim correctName

correctName = Replace(nameStr, "/", "_")
correctName = Replace(correctName, "#", "")
correctName = Replace(correctName, "(", "")
correctName = Replace(correctName, ")", "")
correctName = Replace(correctName, "\\", "")
correctName = Replace(correctName, """", "")
correctName = Replace(correctName, "'", "")
correctName = Replace(correctName, ":", "")
correctName = Replace(correctName, "?", "")
correctName = Replace(correctName, "&lt;", "")
correctName = Replace(correctName, "&gt;", "")
correctName = Replace(correctName, "|", "")
correctName = Replace(correctName, "*", "")

correctName = Left(correctName, 127)

CorrectObjectName = correctName
End Function

Function CreateTransactionMutex()
On Error Resume Next
Dim fileName : fileName = AVIcodeInstallPath &amp; "StatisticMutex.tmp"
Dim Counter : Counter = 0
do
Err.Clear()
Set fileMutex = fso.OpenTextFile(FileName, 2 , True)
If NOT (Err = 0) Then
WScript.Sleep Int(300 * Rnd)
Counter = Counter+1
End If
loop While (Err &lt;&gt; 0) AND (Counter &lt; 100)
If Counter &lt; 100 Then
CreateTransactionMutex = True
Else
CreateTransactionMutex = False
End If
End Function

Function CloseTransactionMutex()
On Error Resume Next
if NOT(isEmpty(fileMutex)) AND NOT(isNull(fileMutex)) Then
fileMutex.Close()
If NOT (Err = 0) Then
Err.Clear()
End If
End If
End Function

Function RunScriptx86(scriptName)
On Error Resume Next
Dim WinDir : WinDir = wshell.ExpandEnvironmentStrings("%windir%")
HandleError("Cannot expand environment variable %windir%")
Dim cScriptFileName : cScriptFileName = WinDir &amp; "\SysWOW64\cscript.exe"
If NOT FSO.FileExists(cScriptFileName) Then
cScriptFileName = WinDir &amp; "\System32\cscript.exe"
End If
Dim oExec
Set oExec = WShell.Exec(cScriptFileName &amp; " " &amp; scriptName)
HandleError("Cannot start process '" &amp; cScriptFileName &amp; " " &amp; scriptName &amp; "'")
Dim scriptOutput : scriptOutput = ""

Do While oExec.Status = 0
WScript.Sleep 100
Loop
If Not oExec.StdOut.AtEndOfStream Then
'for exclude cscript.exe header
oExec.StdOut.ReadLine()
oExec.StdOut.ReadLine()
oExec.StdOut.ReadLine()
if (oExec.ExitCode = 0) Then
scriptOutput = Trim(scriptOutput &amp; oExec.StdOut.ReadLine())
Else
scriptOutput = Trim(scriptOutput &amp; oExec.StdOut.ReadAll())
LogEvent "Script Failed: " &amp; cScriptFileName &amp; " " &amp; scriptName &amp; "; OutPut:" &amp; scriptOutput, 1
ReturnWithoutObject()
End if
End If
RunScriptx86 = scriptOutput
End Function

Function GetProgrammFilesFolder()
GetProgrammFilesFolder = wshell.ExpandEnvironmentStrings("%ProgramFiles(x86)%")
if GetProgrammFilesFolder = "%ProgramFiles(x86)%" Then
GetProgrammFilesFolder = wshell.ExpandEnvironmentStrings("%ProgramFiles%")
End If
End Function

Sub HandleError(customMessage)
If Not (Err.number = 0) Then
LogError customMessage
Wscript.Quit 0
End If
End Sub

Function HandleErrorContinue(customMessage)
HandleErrorContinue = False
If Not (Err.number = 0) Then
LogError customMessage
Err.Clear
HandleErrorContinue = True
End If
End Function

Sub LogError(customMessage)
Dim msg
If Not (Err.number = 0) Then
msg = Replace(" Error: #P1# Description: #P2# ", "#P1#", CStr(Err.number) )
msg = Replace(msg, "#P2#", Err.Description )
msg = customMessage &amp; VbCrLf &amp; msg &amp; VbCrLf
If UCase(Hex(Err.number)) = UCase("80041006") Then
msg = msg &amp; "WMI Error. Not enough memory for the operation." &amp; VbCrLf
End If
WScript.StdOut.WriteLine msg
msg = msg &amp; " [" &amp; ScriptInfo() &amp; "]"
LogEvent msg, 1
End If
End Sub

Function ScriptInfo()
Dim commandLineInfo : commandLineInfo = WScript.ScriptFullName
Dim argument
For Each argument In WScript.Arguments
commandLineInfo = commandLineInfo &amp; " """ &amp; argument &amp; """"
Next
ScriptInfo = commandLineInfo
End Function

Sub LogEvent (message, eventType)
Dim errorEventId : errorEventId = 20000
Dim oAPI0 : Set oAPI0 = CreateObject("MOM.ScriptAPI")
Call oAPI0.LogScriptEvent("AVIcode uX Monitoring Management Pack for OpsMgr 2007", errorEventId, eventType, message)
End Sub
</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="DeleteWA"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.BaseData</OutputType>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>