Josh-D. S. Davis

Xaminmo / Omnimax / Max Omni / Mad Scientist / Midnight Shadow / Radiation Master

Previous Entry Share Next Entry
Perl script to collect Tivoli Storage Manager V5 server data
Josh 201604 KWP
joshdavis
https://www-304.ibm.com/support/docview.wss?uid=swg21265179

To start the script in the background, you need to adjust the following variables:

my $server = "localhost"; # server stanza for UNIX, TCPSERVERADDRESS for MSWin32
my $tcpport = "1500"; # only used in MSWin32
my $administrator = "admin"; # the admin id
my $password = "password"; # guess what?

You can easily adjust the script to collect data as you like, the default set has been found helpful in analysis of TSM server performance.

Please note that the script is unsupported and usage is at your own risk.

Note: APAR IC72251 documents a problem that the SHOW THREADS command can crash the server. The script uses this command frequently on the Windows platform, so please make sure the fix for this is applied. See the link section for APAR details. On platforms other than Windows, the SHOW THREADS usage has been greatly reduced, however it is still recommended to apply the referenced fix.

#!/usr/bin/env perl
# collect monitoring output and write to timestamped files

use POSIX("strftime");

# Default values:
my $server = "localhost"; # server stanza for UNIX, TCPSERVERADDRESS for MSWin32
my $tcpport = "1500"; # only used in MSWin32
my $administrator = "admin"; # the admin id
my $password = "password"; # guess what?

my $sleeptime = "600"; # sleep between command output collection default 600 sec
my $iterations = "3"; # how often collect command output default 3
my $repeat = "2400"; # repeat every 40 minutes, if $continous = 0 default 2400 sec
my $continous = "1"; # continously collect docs
my $actlog = "1"; # collect activity log
my $summary = "1"; # collect summary records
my $timeout = "300"; # timeout for procstack

my $statsinterval = 30; # interval length (sec) for iostat (UNIX only)

# TSM commands to be run at intervals:
my @commands = ("SHOW TIME",
"SHOW LOGPINNED",
"SHOW LOCKS",
"SHOW RESQ",
"SHOW BUFV",
"SHOW BUFS",
"SHOW TXNT",
"SHOW DBTXNT",
"QUERY MOUNT",
"Q PROC",
"Q SE F=D",
"SHOW SESS F=D");

# End of user settable parameters

# Prompt the user for information
print "Note: this script will collect data in the foreground until it's cancelled\n";
print "Note: this script starts TSM server instrumentation, when cancelling this\n";
print " script you may wish to stop server instrumentation via the TSM\n";
print " command 'instrument end' such that it doesn't continue to run\n";
print " indefinately.\n";
print "\nPress enter to accept default values shown in brackets:\n\n";
$server = getResp("Enter the servername as found in dsm.opt or dsm.sys",$server);
if (($^O eq "MSWin32") || ($^O eq "Windows_NT") || ($^O eq "cygwin")) {
$tcpport = getResp("Enter the tcpport",$tcpport);
}
$administrator = getResp("Enter the TSM administrator login ID",$administrator);
$password = getResp("Enter the TSM administrator password (warning, it will echo to the screen)",$password);

my $statscmd = ""; # set below, do not change here

if (($^O eq "MSWin32") || ($^O eq "Windows_NT") || ($^O eq "cygwin")) {

push @commands, "SHOW THREADS";

$cmd = "dsmadmc -tcps=$server -tcpp=$tcpport -id=$administrator -pas=$password -scrollprompt=no";

if ( $ENV{'DSM_CONFIG'} eq "" ) {
$dsm_opt = "c:\\progra~1\\tivoli\\tsm\\baclient\\dsm.opt";
} else {
$dsm_opt = $ENV{'DSM_CONFIG'};
}
$tsmpath = "c:\\progra~1\\tivoli\\tsm\\baclient";

} else { #UNIX

$cmd = "dsmadmc -servername=$server -id=$administrator -pas=$password -scrollprompt=no";

$SIG{INT} = 'stopInstr'; #set control-C routine

if ($^O eq "aix") {

$fsclient = "/usr";

if ( $ENV{'DSM_CONFIG'} eq "" ) {
$dsm_opt = $fsclient . "/tivoli/tsm/client/ba/bin64/dsm.opt";
} else {
$dsm_opt = $ENV{'DSM_CONFIG'};
}
$tsmpath = $fsclient . "/tivoli/tsm/client/ba/bin64";
$procstack = "/usr/bin/procstack";
$procrun = "/usr/bin/procrun";
$statsiterations = int( $iterations * $sleeptime / $statsinterval);
$statscmd = "iostat -DlT $statsinterval $statsiterations";

} else {

$fsclient = "/opt";

if ( $ENV{'DSM_CONFIG'} eq "" ) {
$dsm_opt = $fsclient . "/tivoli/tsm/client/ba/bin/dsm.opt";
} else {
$dsm_opt = $ENV{'DSM_CONFIG'};
}
$tsmpath = $fsclient . "/tivoli/tsm/client/ba/bin";

if (($^O eq "linux") || ($^O eq "solaris")) {
if ( -x "/usr/bin/pstack" ) {
$procstack = "/usr/bin/pstack";
}
if ( -x "/usr/bin/gstack" ) {
$procstack = "/usr/bin/gstack";
}
}
$statsiterations = int( $iterations * $sleeptime / $statsinterval);
if ($^O eq "linux" and -x "/usr/bin/iostat" ) {
$statscmd = "iostat -xtk $statsinterval $statsiterations";
}
if ($^O eq "solaris") {
$statscmd = "iostat -xtc $statsinterval $statsiterations";
}
if ($^O eq "hpux") {
$statscmd = "iostat -t $statsinterval $statsiterations";
}

}

# $dsm_opt = "~/dsm.opt";

}

my @out;
my $firstcycle = "true";
my $serverpid = 0;

my $path = $ENV{'PATH'};
$ENV{'PATH'} = $path . ";" . $tsmpath . ";";
$ENV{'DSM_DIR'} = $tsmpath;
$ENV{'DSM_CONFIG'} = $dsm_opt;

print "DSM_DIR: " . $tsmpath . "\nDSM_CONFIG: " . $dsm_opt . "\n\n";

my $begindate = strftime("%m/%d/%Y", localtime());
my $begintime = strftime("%H:%M:00", localtime());
my $begints = strftime("%Y-%m-%d %H:%M:%S.000000", localtime());
my $actlogname = strftime("%Y%m%d-%H%M", localtime()) . "-actlog.txt";
my $summaryname = strftime("%Y%m%d-%H%M", localtime()) . "-summaryrec.txt";

my $now;

while (1)
{

$now = strftime("%Y%m%d-%H%M", localtime());
my $begin = $now;
my $slept = 0;

# get the server pid for procstack command
if ($serverpid == 0) {
$serverpid = &get_pid();
}

if ($firstcycle eq "true") {
open (SYSTEMOUT, ">$now-system.txt") || die "Can't open SHOWOUT for writing\n";
@out=`$cmd QUERY SYSTEM`;
print SYSTEMOUT "@out\n\n";
close(SYSTEMOUT);
$firstcycle = "false";
}

open (SHOWOUT, ">$now-show.txt") || die "Can't open SHOWOUT for writing\n";

`$cmd instr begin`;

if ( $statscmd ne "" ) {
system( "$statscmd > $now-iostat.txt &" );
print "Redirecting iostat to $now-iostat.txt\n";
}

for ($i = 0; $i<$iterations;) {

foreach $command (@commands)
{
@out=`$cmd $command`;
print SHOWOUT "@out\n\n";
}

if (defined $procstack) {

if ($^O eq "aix") {

eval {
local $SIG{ALRM} = sub { die "alarm\n" };
alarm $timeout;
@out= `$procstack $serverpid`;
alarm 0;
};

} else {

@out= `$procstack $serverpid`;

}

if ($@) {
die unless $@ eq "alarm\n";

if (defined $procrun) {
`$procrun $serverpid`;
}

print SHOWOUT "$procstack $serverpid timed out after $timeout seconds.\n";

} else {
print SHOWOUT "@out\n\n";
}

if ($#out < 0) {
print "Reset of server pid\n";
$serverpid = 0;
}

}

close(SHOWOUT);

print "Wrote $now-show.txt\n";
close(SHOWOUT);

$i++;

if ($i < $iterations)
{
sleep($sleeptime);
$slept += $sleeptime;
$now = strftime("%Y%m%d-%H%M", localtime());
open (SHOWOUT, ">$now-show.txt") || die "Can't open SHOWOUT for writing\n";
}
}

open (INSTROUT, ">$begin-$now-instr.txt") || die "Can't open INSTROUT for writing\n";

@out=`$cmd instr end`;
print INSTROUT "@out\n\n";
print "Wrote $begin-$now-instr.txt\n";
close(INSTROUT);

if ($actlog) {
`$cmd query actlog begindate=$begindate begintime=$begintime > $actlogname`;

if (-e "$actlogname") {
print "Wrote $actlogname\n";
} else {
print "$actlogname not written!\n";
}
}

if ($summary) {
open (SUMMARY, ">$summaryname") || die "Can't open $summaryname for writing\n";

@out=`$cmd "select * from summary where start_time>=\'$begints\' or end_time>=\'$begints\'"`;
print SUMMARY "@out\n\n";
close(SUMMARY);
print "Wrote $summaryname\n";
}


$longsleep = $repeat - $slept;
if (!$continous) {
sleep($longsleep);
}
}

# Subroutines:

# Get a user response and return it
sub getResp
{
local ($prompt,$default) = @_;

print "$prompt [$default]:";
$| = 1;
$_ = ;
chomp;
return $_ ? $_ : $default;
}

# Stop instrumentation on the server
sub stopInstr
{
print "Interrupted, stopping instrumentation on the server before exiting...\n";
open (INSTROUT, ">$now-lastinstr.txt") || exit;

@out=`$cmd instr end`;
print INSTROUT "@out\n\n";
print "Wrote $now-lastinstr.txt\n";
close(INSTROUT);
exit;
}
sub get_pid() {

open(FILE,"$cmd SHOW THREADS |") || die "Can't open $cmd - $!";

while () {

print "$_";

if (m/^Server PID:/) { # grab server pid from SHOW THREADS output
@fields = split(/\s+/,$_);
close(FILE);
return $fields[2];
}

if ((m/^ANS8023E/) || (m/^ANS1217E/) || (m/^ANS0101E/)) { # Failure contacting the server/message repository error
close(FILE);
exit;
}

}

close(FILE);

}

  • 1
I like Perl! <3

Plus, there's a typo where it says indefinately :(

Edited at 2012-05-01 12:10 am (UTC)

I used to, but it's sort of evil when you don't use it much.

And yah, there were many such typos. I corrected some, and gave up. I'll blame it on a non-native English speaker who posted it at IBM.

Edited at 2012-05-01 04:19 pm (UTC)

  • 1
?

Log in

No account? Create an account