'Created By Scott Dunt - 
'Hewlett-Packard co. all rights reserved Copyright 2009
'This VBscript code will read in and reformat the 
'metrics dump file "jmx_metrics_WAS6.txt" from HP Diagnostics Java Probe 
'specifically for IBM WebSphere 6.x PMI Metrics

Const ForReading = 1
Const ForWriting = 2

'Create Windows script Host File System Object that is needed to read and Write Files
Set ofso = CreateObject("Scripting.FileSystemObject")

'File we Reformat and write the ======= PMI Tree and Available PMI Statistics ======= section to
Set Pmilog = FopenW("PMITree.txt") 

'File we reformat and write the ======= PMI Module Config Data ======= section to
Set PMIConfig = FopenW("PMIConfig.txt")

'Write out a 'results' log of script activity.
Set Rlog = FopenW("Results.log")   

Rlog.Writeline("****************************** Beginning of log " & Date & " " & Time)  	

'open the Raw dump file for read - input
Set fTextStream = FopenR("jmx_metrics_WAS6.txt")
Rlog.Writeline("Successfully Opened the jmx_metrics_was6.txt file")

PMITree = False	'Set Flag variable

Do While PMITree = False		'Scan the file until we find the PMI Tree header
  	PMIString = fTextStream.ReadLine		'Read in each line
  	If instr(PMIString, "======= PMI Tree") <> 0 Then 'Found the start of the PMI Secion of the file
  		Rlog.Writeline("Found the start of the PMI section in the log.  Moving to next phase of scan")
  		PMITree = True
  		PMIModule = False
  	End If
Loop 'PMITree

Rlog.Writeline("Entering 2nd phase of scan.. Looking for PMI Module while writing PMITree.txt file")

Do While PMIModule = False
  		'read each line (until PMI Module header), reformat it slightly and write to PMI Tree file
  		PMIString = fTextStream.ReadLine		'Read in each line
  		If instr(PmiString, "======= PMI Module ") <> 0 Then 
  			'If the line read contains "======= PMI Module " then close the 1st file. 			
  			Rlog.Writeline(" Found PMI Module - closing PMITree.txt file. Going to next phase")
  			PMIModule = True 'Done - reset the flag so we can exit the loop
  			PmiLog.Close
  		Else  'NOT PMI Module Line
  			If instr(PMIString, "Available Statistics:") <> 0 Then 'Found a stats line
  				StatsString =fTextStream.Readline
  				If len(StatsString) <> 0 Then		'Skip the blank lines in the input. 
  					pmistring = pmistring & statsstring
  				End if 'StatsString <> 0
  			End If 'Found Stats line
  		If Len(PMIString) <> 0 then
  			PmiLog.writeline(pmistring)
  		End if
  	 End If 'Pmi Module
Loop 'PMIModule


Do While fTextStream.AtEndOfStream <> True		'as long as we are not at the end of file, keep reading lines
	PMIString = fTextStream.ReadLine		'Read in each line
	If Len(PMIString) > 17 then					'if its a blank line, discard it. Also discard "PmiModuleConfig:" headers
		Pmiconfig.writeline(pmistring)			' and  write them to the PMIConfig.txt file.
	End If
Loop  ' End read to EOF
  
Pmiconfig.Close

Rlog.Writeline("Files scanned and created. Moving to formating of Metrics.config Entries" & vbnewline)

'Open - Create a new Metrics.config.txt file for Writing
Set MConfig = FopenW("Metrics.config.txt")

'Open - Re open the PMITree.txt file we created earlier, but for Reading
Set Pmilog = FopenR("PMITree.txt")     	

Do While Pmilog.AtEndOfStream <> True ' read and parse the PMI stats log
	
	'We will be creating Entries that look like this:
	'collector_name/metric_config = metric_id|metric_units|category_id
	'					OR
	' WebSphere6/servletSessionsModule.ExternalWriteSize=ExternalWriteSize|bytes|Servlet Session Manager
	
	PMIName = Pmilog.ReadLine		'Read in the PMI metric Name
	PMIStats = Pmilog.ReadLine		'Read in the Available Stats line that we merged previously
	If Len(PmiStats) > 21 Then ' This PMI entry has Stats we can process
		'need to handle compound names that contain ->
		Pnames = Split(PMIName, "->")
		PMIName = "WebSphere6/" ' Reuse this variable as we build up the PMI - JMX path to the metric
		CatName = "PMI" 'Build a hopefully unique catagory name for each category

		For Each PName in Pnames ' if the name as compound build the name substituting [] for ->
			PMIName = PMIName & "[" & Pname & "]"
			CatName = CatName & "_" & Pname
		Next	 'Pname
		
		' Now that we have the PMI name figured out lets process EACH statistic available		
		PMIStats = Mid(PMIStats, 22) 'Strip off the "available statistics" string we merged on to the front of the line
		Stats = Split(PMIStats,", ") 'split out each stat name based on the comma & space separator
		
		For Each Stat in Stats
			'and build a record for the metrics.config file for each entry..
			StatLine = PmiName & "." & Stat 
			'Note: After you have created the metric collector entry, you must add the
			'escape character "\" before each occurrence of a back-slash '\', space ' ', or
			'colon ':'.
			StatLine = Replace(StatLine,"\" , "\\") ' Check for and replace \ characters, need to do this before we insert our own \ characters
			StatLine = Replace(StatLine," " , "\ ") ' Check for and replace Spaces with \Space
			StatLine = Replace(StatLine,":" , "\:")	' Finally fix up the Colon characters.
			'This next statement calls the GetUnits routine as part of generating the final line for metrics.config
			'GetUnits scans the PMICOnfig.txt file to try and locate a description for this metric and 
			'also to try and determine the correct unit of measure to use for it.
			MConfig.writeline(StatLine & "=" & stat & "|" & GetUnits(stat) & "|" & Catname)
		Next 'Stat
	
	Else
		Rlog.writeline("skipping: " & PMIName & " No Available Statistics Found")
	End If ' Stats are available - Len(PMIStats > 21
	
Loop
'and a little clean up before we Exit the script.
MConfig.Close
Rlog.Close
Set ofso = Nothing

Function GetUnits(StatName)
GetUnits = "count"  'Set the Default return value if one is not found in the PMIConfig.txt file

'Open the PMIconfig.txt file for reading.
Set PMIStats = FopenR("PMIConfig.txt")

	Do While PMIStats.AtEndOfStream <> True		'as long as we are not at the end of file, keep reading lines
		PMILine = PMIStats.readline
		'Is this the Stats name we are looking for?  Otherwise keep reading until EOF to try and find one.
		
		if instr(PMILine, Pnames(0)) <> 0 Then ' We have found the right stats section for the metric
			PMILine = PMIStats.readline
			Do While instr(PMILine, "Stats type") = 0 'Being that we in the right Stats section keep scanning until we
																								'either find the right metric or until we hit another stats section.
				
				'Is this the metric name we are looking for?
					If instr(PMILine, StatName) <> 0 Then  ' found our particular Metric
						'now lets find the desciption of this item and add it as a comment 
						'very easy to do that here, because it is formated right before the unit..
						iPosDesc = instr(PMILine, "description=")
						iPosUnit = instr(PMIline, "unit=")
						'Generate a comment line in the metrics.config file with the description
						MConfig.writeline("# " & Mid(PmiLine, iPosDesc, IposUnit - iPosDesc))
						iEndUnit = instr(iPosUnit, PMILine, ",")
						sUnits = Mid(PMIline, iPosUnit + 5, iEndUnit-iPosUnit - 5) ' Get the Unit from the file
						'programmers NEVER seem to use the same spelling or case for things sooo..
						'correct the returned unit of measure to the format metric.config uses.
						Select Case sUnits
      				Case "BYTE"    			GetUnits = "bytes"
      				Case "Bytes"    		GetUnits = "bytes"
      				Case "KILOBYTE"   	GetUnits = "kilobytes"
      				Case "MILLISECOND"  GetUnits = "milliseconds"
      				Case "Milliseconds"  GetUnits = "milliseconds"
      				Case "ms"  					GetUnits = "milliseconds"
      				Case "unit.ms"  		GetUnits = "milliseconds"
      				Case "SECOND"  			GetUnits = "seconds"
      				Case "%"  					GetUnits = "percent"
       				Case Else      			If Instr(PMILine, "percent") <> 0 Then
       														'many metrics have the unit set to N/A when the description describes it as a 
       														'percentage. So Fix that problem as well
       														GetUnits = "percent"
       														Else
       															Rlog.Writeline("No supported Unit Type found for Metric " & StatName & " In Section " & Pnames(0))
       															GetUnits = "count" ' Default to count if unit was N/A or similar string
       														End if
   					End Select
						Exit Do	' If we found the particular metric we called for, then we're done.
					Else
					End if 'Statname
					PMIline = PMIStats.readline
				Loop ' Stats type
					Exit Do ' We only process 1 metric per call.. Actually only one name of one metric per call.
			End if	'Pnames0
Loop
PmiStats.Close

End Function 'GetUnits

Function FopenW (sFilename)

	On Error Resume Next			'Enable Error Handling incase the output file read only or other errors
	Set FopenW = ofso.CreateTextFile(sFilename, True)
  If err.Number <> 0 Then							'open on output file failed..
  	MsgBox "Error Opening File: " & VbNewLine & VbNewline & sFilename &_
  	VBNewline & Err.Description & " Error Number = " & err.Number & VBNewline, 16, "File Create Error"
  	Err.Clear							' Clear the error setting
  	On Error GoTo 0							'Disable On error Go to
  	Wscript.quit
  End If
  
End Function  ' FopenWrite

Function FopenR (sFilename)

   	On Error Resume Next			'Enable Error Handling incase the output file read only or other errors
   	Set FopenR = ofso.OpenTextFile(sFilename, ForReading)
   		If err.Number <> 0 Then							'open on output file failed..
    		MsgBox "Error Opening Input File: " & sFilename &_
    		VBNewline & Err.Description & " Error Number = " & err.Number & VBNewline & VbNewline &_
    		"Please Select A NEW file name or correct errors before restarting the query", 16, "File Write Error"
    		Err.Clear							' Clear the error setting
    		On Error GoTo 0							'Disable On error Go to
    		Wscript.quit
			End If
			
End Function 'FopenRead