Websphere : Jython script to return performance matrix details of Node
Here is a Jython script to return performance matrix detail of a node for following details :
Free and used JVM heap size,
Free and used Thread pools,
Free and used JDBC connection pools
Free and used Live sessions
[was61@Server1 .scripts]$ wsadmin.sh -f check_was.py -i heapsize -s Server_member1
WASX7209I: Connected to process “dmgr” on node Server1_Manager using SOAP connector; The type of process is: DeploymentManager
WASX7303I: The following options are passed to the scripting environment and are available as arguments that are stored in the argv variable: “[-i, heapsize, -s, Server_member1]”
heapsize: node=Server1_Node01 server=Server_member1 used=1024.0 MB (52.44%) free=928.6 MB
Download script from http://www.oracledbasupport.co.uk/wp-content/uploads/2010/08/Check-was Python Script.txt
The Jython script used is as below :
#———————————————————————-
# File Name: check_was.py
# Purpose: Display user requested information about
# WebSphere Application Server (WSAS) resources.
#
# Run “$WAS_HOME/Dmgr/bin/wsadmin.sh -conntype none -lang jython”
# wsadmin>print AdminConfig.list(‘Server’);
# dmgr(cells/Server1_Cell/nodes/Server1_Manager/servers/dmgr|server.xml#Server_1)
# ihs-prpc(cells/Server1_Cell/nodes/Server1_Node01/servers/ihs-prpc|server.xml#Server_1280149489851)
# server_member1(cells/Server1_Cell/nodes/Server1_Node01/servers/server_member1|server.xml#Server_1280159031517)
# server_member2(cells/Server1_Cell/nodes/Server1_Node01/servers/server_member2|server.xml#Server_1280159031764)
# nodeagent(cells/Server1_Cell/nodes/Server1_Node01/servers/nodeagent|server.xml#Server_1120677326772)
#
#———————————————————————-
”’Command: %(cmdName)s\n
Purpose: wsadmin script used to display user specified information about
WebSphere Application Server resources.\n
Usage: %(cmdName)s [options]\n
Required switches/options:
-i | –info <value> = Type of information being requested
-s | –serverName <value> = Target serverName\n
Optional switches/options:
-n | –nodeName <value> = Target nodeName\n
Information types/values:
connectionpool – Display Connection Pool details
heapsize – Display Heap Size details
threadpool – Display Thread Pool details
sessions – Display Session Details\n
\nNotes:
– Long form option values may be separated/delimited from their associated
identifier using either a space, or an equal sign (‘=’).\n
– Short form option values may be sepearated from their associated letter
using an optional space.\n
– Text containing blanks must be enclosed in double quotes.\n
Examples:
wsadmin -f %(cmdName)s.py -i heapeize -s server1 -n node01\n”’import os, re, sys, getopt;
__scriptName__ = ‘check_was’;
__version__ = ‘0.1’;
__updated__ = ’22 July 2010′;#———————————————————————
# Name: localMode()
# Role: Return true (1) if AdminControl object is unavailable, false
# (0) otherwise.
# Note: In localmode (i.e., -conntype none), this returns true (1)
#———————————————————————
def localMode() :
‘localMode() – Return true (1) if AdminControl object is unavailable, false (0) otherwise’
try :
host = AdminControl.getCell();
result = 0; # No, we’re connected
except :
result = 1; # Yes, –contype none
return result;#———————————————————————
# Name: beanNameAsDict()
# Role: Parse the specified MBean and return a dictionary of the name
# value pairs
#———————————————————————
def beanNameAsDict( bean ) :
‘beanNameAsDict() – Parse the specified MBean and return a dictionary of the name value pairs’
result = {};
for pair in bean.split( ‘:’, 1 )[ 1 ].split( ‘,’ ) :
n, v = pair.split( ‘=’, 1 );
result[ n ] = v;
return result;#———————————————————————
# Name: callerName
# Role: Utility routine used to determine, and return the name of the
# calling function.
# Note: Dependends on sys._getframe()
# See: http://code.activestate.com/recipes/66062/
#———————————————————————
def callerName() :
“callerName() – Returns the name of the calling routine (or ‘?’)”
return sys._getframe( 1 ).f_code.co_name;#———————————————————————
# Name: configurable()
# Role: Return true (1) if AdminConfig object is available, false (0) otherwise
#———————————————————————
def configurable() :
‘configurable() – Return true (1) if AdminConfig object is available, false (0) otherwise’
try :
host = AdminConfig.list( ‘Server’ );
result = 1; # True = AdminConfig object is available
except :
result = 0; # False = AdminConfig object not available
return result;#———————————————————————
# Name: configIdAsDict
# Role: Parse a config ID and return a dictionary of name/value pairs
# Note: Exception handler requires sys module
# The keys in the returned dictionary come from the configID, so
# are unlikely to match your defect expectations about exactly
# what values are used (e.g., ‘nodes’ instead of “Node”)
#———————————————————————
def configIdAsDict( configId ) :
‘configIdAsDict( configId ) – Given a configID, return a dictionary of the name/value components.’
funName = callerName(); # Name of this function
result = {}; # Result is a dictionary
hier = []; # Initialize to simplifiy checks
try : # Be prepared for an error
#—————————————————————–
# Does the specified configID match our RegExp pattern?
# Note: mo == Match Object, if mo != None, a match was found
#—————————————————————–
if ( configId[ 0 ] == ‘”‘ ) and ( configId[ -1 ] == ‘”‘ ) and ( configId.count( ‘”‘ ) == 2 ) :
configId = configId[ 1:-1 ];
mo = re.compile( r’^([\w ]+)\(([^|]+)\|[^)]+\)$’ ).match( configId );
if mo :
Name = mo.group( 1 );
hier = mo.group( 2 ).split( ‘/’ );
if mo and ( len( hier ) % 2 == 0 ) :
#—————————————————————
# hier == Extracted config hierarchy string
#—————————————————————
for i in range( 0, len( hier ), 2 ) :
( name, value ) = hier[ i ], hier[ i + 1 ];
result[ name ] = value;
if result.has_key( ‘Name’ ) :
print ”’%s: Unexpected situation – “Name” attribute conflict,
Name = “%s”, Name prefix ignored: “%s””’ % ( funName, result[ ‘Name’ ], Name );
else :
result[ ‘Name’ ] = Name;
else :
print ”’%(funName)s:
Warning: The specified configId doesn\’t match the expected pattern,
and is ignored.
configId: “%(configId)s””’ % locals();
except :
( kind, value ) = sys.exc_info()[ :2 ];
print ”’%(funName)s: Unexpected exception.\n
Exception type: %(kind)s
Exception value: %(value)s”’ % locals();
return result;#———————————————————————
# Name: heapsize()
# Role: Display information about the heap for the specified server
#———————————————————————
def heapsize( configID ) :
‘heapsize() – Display used and free stats for the JVM of the specified server’
cDict = configIdAsDict( configID );
jvm = AdminControl.queryNames( ‘type=JVM,process=%(servers)s,node=%(nodes)s,*’ % cDict );
if jvm :
used = AdminControl.getAttribute( jvm, ‘heapSize’ );
free = AdminControl.getAttribute( jvm, ‘freeMemory’ );
total = int( used ) + int( free );
percent = float( used ) * 100.0 / float( total );
print ‘heapsize: node=%s server=%s used=%.1f MB (%.2f%%) free=%.1f MB’ % ( cDict[ ‘nodes’ ], cDict[ ‘servers’ ], MB( used ), percent, MB( free ) );
else :
print ‘Specified server does not appear to be active: node=%(nodes)s server=%(servers)s’ % cDict;#———————————————————————
# Name: localMode()
# Role: Return true (1) if AdminControl object is unavailable, false
# (0) otherwise.
# Note: In localmode (i.e., -conntype none), this returns true (1)
#———————————————————————
def localMode() :
‘localMode() – Return true (1) if AdminControl object is unavailable, false (0) otherwise’
try :
host = AdminControl.getCell();
result = 0; # No, we’re connected
except :
result = 1; # Yes, –contype none
return result;#———————————————————————
# Name: main()
# Role: Perform the actual work of the script
#———————————————————————
def main( cmdName = None ) :
missingParms = ‘%(cmdName)s: Insufficient parameters provided.\n’;
ambigServer = ‘%(cmdName)s: Ambiguous server specified: %(serverName)s\n’;
badReqdParam = ‘%(cmdName)s: Invalid required parameter: %(key)s\n’;
badInfo = ‘%(cmdName)s: As yet unimplemented “info” request: %(info)s\n’;
badNode = ‘%(cmdName)s: Unknown node: %(nodeName)s\n’;
badServer = ‘%(cmdName)s: Unknown server: %(serverName)s\n’;
serverReqd = ‘%(cmdName)s: Missing required parameter: “serverName”.\n’;if not cmdName :
cmdName = __scriptName__;#——————————————————————-
# How many user command line parameters were specified?
#——————————————————————-
argc = len( sys.argv ); # Number of arguments
if ( argc < 2 ) : # If too few are present,
print missingParms % locals(); # tell the user, and
Usage( cmdName ); # provide the Usage info
else : # otherwise
Opts = parseOpts( cmdName ); # parse the command line#——————————————————————-
# Assign values from the user Options dictionary, to make value
# access simplier, and easier. For example, instead of using:
# Opts[ ‘nodeName’ ]
# we will be able to simply use:
# nodeName
# to access the value.
#——————————————————————-
for key in Opts.keys() :
val = Opts[ key ];
cmd = ‘%s=Opts[“%s”]’ % ( key, key );
# print cmd;
exec( cmd );#——————————————————————-
# Check required parameters
#——————————————————————-
if info not in [ ‘heapsize’, ‘sessions’, ‘connectionpool’, ‘threadpool’ ] :
print badInfo % locals();
Usage( cmdName );if not serverName :
print serverReqd % locals();
Usage( cmdName );#——————————————————————-
# Was the nodeName specified, and if so, does it exist?
#——————————————————————-
node = None;
if nodeName :
for nid in AdminConfig.list( ‘Node’ ).splitlines() :
if nid.startswith( nodeName + ‘(‘ ) :
node = nid;
if not node :
print badNode % locals();#——————————————————————-
# Does the specified serverName exist (within the scope of the
# specified node)?
# Note: A scope of None is identical to not specifying a scope
#——————————————————————-
servers = [];
for sid in AdminConfig.list( ‘Server’, node ).splitlines() :
if sid.startswith( serverName + ‘(‘ ) :
servers.append( sid );
if len( servers ) < 1 :
print badServer % locals();
sys.exit();
elif len( servers ) > 1 :
print ambigServer % locals();
nodes = [];
for sid in servers :
nodes.append( configIdAsDict( sid )[ ‘nodes’ ] );
print ‘Specify one of the following nodes using the –nodeName option: ‘ + ( ‘, ‘.join( nodes ) );
sys.exit();
server = servers[ 0 ];# print ‘Request for %s on %s’ % ( info, server );
if info == ‘heapsize’ :
heapsize( server );
else :
print ‘Not yet implemented: “%s”‘ % info#———————————————————————
# Name: MB()
# Role: Convert the specified (integer) value [bytes] into MegaBytes
#———————————————————————
def MB( val ) :
‘MB() – Convert specified integer (byte) value into MegaBytes’
return int( val ) / ( 1024.0 * 1024.0 );#———————————————————————
# Name: parseOpts()
# Role: Process the user specified (command line) options
#———————————————————————
def parseOpts( cmdName ) :
shortForm = ‘i:n:s:’;
longForm = ‘info=,nodeName=,serverName=’.split( ‘,’ );
badOpt = ‘%(cmdName)s: Unknown/unrecognized parameter%(plural)s: %(argStr)s\n’;
optErr = ‘%(cmdName)s: Error encountered processing: %(argStr)s\n’;
problem = ‘%(cmdName)s: Error option processing problem: %(opt)s\n’;try :
opts, args = getopt.getopt( sys.argv, shortForm, longForm );
except getopt.GetoptError :
argStr = ‘ ‘.join( sys.argv );
print optErr % locals();
Usage( cmdName );#——————————————————————-
# Initialize the Opts dictionary using the longForm key identifiers
#——————————————————————-
Opts = {};
for name in longForm :
if name[ -1 ] == ‘=’ :
name = name[ :-1 ]
Opts[ name ] = None;#——————————————————————-
# Process the list of options returned by getopt()
#——————————————————————-
for opt, val in opts :
if opt in ( ‘-i’, ‘–info’ ) : Opts[ ‘info’ ] = val
elif opt in ( ‘-n’, ‘–nodeName’ ) : Opts[ ‘nodeName’ ] = val
elif opt in ( ‘-s’, ‘–serverName’ ) : Opts[ ‘serverName’ ] = val
else :
print problem % locals();#——————————————————————-
# Check for unhandled/unrecognized options
#——————————————————————-
if ( args != [] ) : # If any unhandled parms exist => error
argStr = ‘ ‘.join( args );
plural = ”;
if ( len( args ) > 1 ) : plural = ‘s’;
print badOpt % locals();
Usage( cmdName );#——————————————————————-
# Return a dictionary of the user specified command line options
#——————————————————————-
return Opts;#———————————————————————
# Name: Usage()
# Role: Display usage information necessary to use this script.
#———————————————————————
def Usage( cmdName = None ) :
if not cmdName :
cmdName = __scriptName__;print __doc__ % locals(); # Script docstring contains usage info
sys.exit();#———————————————————————-
# Code execution begins
#———————————————————————-
if ( __name__ == ‘__main__’ ) or ( __name__ == ‘main’ ) :
if localMode() :
print ‘A connection to WebSphere Application Server is required.\n’;
Usage();
elif configurable() :
main();
else :
print ‘WebSphere Application Server scripting objects appear to be unavailable.\n’;
Usage();
else :
print ‘This script should be executed, not imported.\n’;
Usage( __name__ );
Leave a Reply
You must be logged in to post a comment.
This is a great script, just what I was after.
Worked first time.
Has anyone added the ‘Not coded yet’ bits?
connectionpool, threadpool and sessions.
I’ll give it a go and post the code if I sort it out.
Hi Hazza,
I stopped working with web sphere for some time and hence didn’t really look into this recently. It will be great to see an update from you.