Josh-Daniel S. Davis (joshdavis) wrote,
Josh-Daniel S. Davis
joshdavis

Perl script to collect Tivoli Storage Manager V6 server data

https://www-304.ibm.com/support/docview.wss?uid=swg21432937

Please make sure to run the script from a user with sufficient DB2 access rights (e.g. the instance user) with the DB2 environment properly initialized. Message DB21061E is thrown if the script fails to connect to the database.

Other than the V5 script documented with swg21265179, easiest the script is to be run on the Tivoli Storage Manager server box. If your installation paths are different to the default paths you need to adjust the path variables accordingly.

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.
APAR IC79957 documents a problem that there is a rare chance that SHOW DEDUPDELETEINFO might crash the server. The script has been modified so that the command is commented out. If you have the fix installed you can reactivate the command again.

#!/usr/bin/env perl
# collect monitoring output and write to timestamped files
# run this script as the DB2 instance owner

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 $instance = "tsminst1"; # DB2 instance name, if your DB2INSTANCE environment variable is set it
# will override this value
my $dbalias = "tsmdb1"; # DB2 database alias for TSM database

# Note: if you see the following error message in the db2 output files
# SQL10007N Message "-1390" could not be retrieved. Reason code: "3".
# make sure to adjust the $instance variable to match your environment

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 $collectstmt = "collectstmt=true"; # available with 6.3 and newer servers, default is false

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

# TSM commands to be run at intervals:
my @commands = ("SHOW TIME",
"SHOW BANNER",
"SHOW LOCKS",
"SHOW RESQ",
"SHOW TXNT",
"SHOW DEDUPTHREAD",
# if IC79957 is installed you can activate SHOW DEDUPDELETE again
# "SHOW DEDUPDELETE",
"Q DB F=D",
"Q DBSPACE",
"Q LOG F=D",
"QUERY MOUNT",
"Q PROC",
"Q SE F=D",
"SHOW SESS F=D");

# DB2 commands to be run at intervals:
my @db2commands = ("get snapshot for all applications",
"get snapshot for database on $dbalias",
"list application show detail" );
# consider adding: "get snapshot for dynamic sql on $dbalias" to the above list for more info about statements

# db2pd commands to be run at intervals:
my @db2pdcommands = ("-db $dbalias -bufferpools -runstats -reorgs index -cleaner -wlocks -osinfo -dirtypages summary -mempools -dbcfg",
"-logs -db $dbalias",
"-dbptnmem");

# 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);
$instance = getResp("Enter the DB2 instance name",$ENV{"DB2INSTANCE"});

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\\";
$db2cmdpath = "C:\\Progra~1\\Tivoli\\TSM\\db2\\BIN\\";
$db2pdcmdpath = "C:\\Progra~1\\Tivoli\\TSM\\db2\\BIN\\";
} 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";
$fsserver = "/opt";
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";
$fsserver = "/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";

$db2cmdpath = $fsserver . "/tivoli/tsm/db2/bin";
$db2pdcmdpath = $fsserver . "/tivoli/tsm/db2/adm";

}

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

my $path = $ENV{'PATH'};
$ENV{'PATH'} = $path . ";" . $tsmpath . ";" . $db2cmdpath . ";" . $db2pdcmdpath;
if ( $ENV{'DB2INSTANCE'} eq "" ) {
$ENV{'DB2INSTANCE'} = $instance;
}
$ENV{'DSM_DIR'} = $tsmpath;
$ENV{'DSM_CONFIG'} = $dsm_opt;

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

#`$cmd Q STA`;
#if ($?) {
# exit;
#}

@out=`db2 connect to $dbalias`;
print @out;

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 $collectstmt`;

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);

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

foreach $db2command (@db2commands)
{
@out=`db2 $db2command`;
print DB2OUT "@out\n\n";
}

print "Wrote $now-db2.txt\n";
close(DB2OUT);

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

foreach $db2pdcommand (@db2pdcommands)
{
@out=`db2pd $db2pdcommand`;
print DB2PDOUT "@out\n\n";
}

print "Wrote $now-db2pd.txt\n";
close(DB2PDOUT);

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/^ Server Version/) { # check for server
@fields = split(/\s+/,$_);
$version = $fields[3];
$version =~ s/\D+//g;
$release = $fields[5];
$release =~ s/\D+//g;
@lfields = split(/\./,$fields[7]);
$level = $lfields[0];
$slevel = $lfields[0];


if ( defined($collectstmt) ) {
if (($version > 6) || (($version == 6) && ($release > 2))) {
print "\n$collectstmt used for instrumentation statistics\n\n";
} else {
print "\nInstrumentation trace does not support COLLECTSTMT option at your server level\n\n";
undef($collectstmt);
}
}

}

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

}

close(FILE);

}
Tags: computers, ibm, tsm, work
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments