Below are two scripts developed by MKAdvantage to help with an ITM deployment. The first updates the time dimension for ITM and the other helps with log cleanup. DISCLAMER: The material contained in this page is presented "as is" without warranty.
#!/usr/bin/perl
#
# create-time-dimension-sql.pl
#
# Bryan A. Ignatow
# MKAdvantage, Inc.
# May/June 2011
#
# Create the SQL statement to update the ITM TERM Time Dimension.
# An example statement looks like:
#
# CALL IBM_TRAM.CREATE_TIME_DIMENSION('2010-12-31-00.00.00.000000',
# '2012-12-31-00.00.00.000000', 60);
#
# This statement is passed to the db2 command for execution.
#
# The start time is fixed, and the end time will be calculated as
# 18 months from the current date. This is expected to be run
# once a month to extend the time dimension a month at a time.
#
#
use DateTime;
#
# Constants
# StartDate: The starting date of the Time Dimension range
# MonthIncrement: The number of months to increment from the current date
#
my $StartDate = '2010-12-31-00.00.00.000000';
my $MonthIncrement = 18;
my $SQLStatementTemplate = 'CONNECT TO WAREHOUS\nCALL IBM_TRAM.CREATE_TIME_DIMENSION(\'%s\', \'%s\', 60);';
#
# Variables
#
my ($dt, $EndDate, $SQLStatement);
#
# create a DateTime object set to the current date and time,
# with no particular timezone
#
$dt = DateTime->now( time_zone => 'floating' );
#
# Add 18 months
#
$dt->add( months => $MonthIncrement );
#
# Print the future date
#
$EndDate = sprintf("%d-%02d-%02d-00.00.00.000000",
$dt->year, $dt->month, $dt->day);
#
# Construct the SQL Statement and print it
#
$SQLStatement = sprintf($SQLStatementTemplate, $StartDate, $EndDate);
print($SQLStatement);
#
# End of file
#
Here is the next script which does log file cleanup
#!/usr/bin/perl
#
# itm-log-cleanup.pl
#
# Bryan A. Ignatow
# MKAdvantage, Inc.
# May/June 2011
#
# Handle the special rotation of ITM log files that have unique names.
#
# Check all *.inv files in the ITM logs directory and if file associated
# with the last line in the file has a modification time in the last day,
# remove any other files as listed in the file that have modifcations
# times older than 30 days ago.
#
# This script can be run from the command line or executed as part
# of other log rotation (like under Redhat Enterprise Linux / CentOS):
#
# /etc/logrotate.d/itm:
# /opt/IBM/ITM/logs/candle_installation.log /opt/IBM/ITM/logs/kpacma.log {
# missingok
# notifempty
# weekly
# rotate 4
# compress
# postrotate
# /usr/local/bin/itm-log-cleanup.pl 2> /dev/null || true
# endscript
# }
#
#
use strict;
use warnings;
use DateTime;
use File::stat;
use Time::localtime;
#
# Constants
# ITMLogs: Log directory to search
# FileAgeCheck: The number of hours old the last file line has to be
# FilePurgeLimit: The minimum number of days old a file to be deleted is
#
my $ITMLogDir = '/opt/IBM/ITM/logs';
my $FileAgeCheck = 24;
my $FilePurgeLimit = 30;
#
# Variables
#
my ($dt, $agecheckdt, $purgelimitdt);
my ($invfile, @invfiles, $logfile, $linecount, %logfiles);
my ($lastfile, $modtime, $filedt, %keepfiles, $canpurge, @purgelist, %invmod);
my (@knownlist);
my ($printflag, $filemode, $fileuid, $filegid);
#
# Create a DateTime object set to the current date and time,
# with no particular timezone. Then create two comparison times
# for the age of the current file (last line) and the age of the
# purlimit limit. We're not concerned if they are a second or so
# different since we are dealing with hours and days.
#
$dt = DateTime->now();
$agecheckdt = DateTime->now->subtract( hours => $FileAgeCheck );
$purgelimitdt = DateTime->now->subtract( days => $FilePurgeLimit );
#
# Get the list of *.inv files to work
#
foreach $invfile (<$ITMLogDir/*.inv>) {
push(@invfiles,$invfile);
}
#
# For each *.inv file, get the lines (which are filenames)
#
if ($#invfiles == -1) {
warn "Warning: No log inventory files found in $ITMLogDir";
} else {
%logfiles = ();
foreach $invfile (@invfiles) {
$linecount = 1;
open(INVFILE, "<$invfile") ||
die "Error: Unable to open log inventory file $invfile\n$!";
while ($logfile = <INVFILE>) {
chomp($logfile);
$logfiles{$invfile}{$linecount++} = $logfile;
}
close(INVFILE);
}
}
#
# For each *.inv file, check the date of the last file and if ok, check
# to see which files we will be purging (if any).
#
@purgelist = ();
%invmod = ();
foreach $invfile (@invfiles) {
$lastfile = 1;
$canpurge = 1;
$invmod{$invfile} = 0;
foreach $linecount (sort {$a<=>$b} keys %{$logfiles{$invfile}}) {
#
# If file exists - check dates and build keep hash & purge list
#
if (-f $logfiles{$invfile}{$linecount}) {
#
# Get file modification time
#
$modtime = stat($logfiles{$invfile}{$linecount})->mtime;
$filedt = DateTime->from_epoch( epoch => $modtime );
#
# If this is the latest file, check its mod time
#
if ($lastfile) {
#
# If mod time is older than the age check date
# don't purge any files from this INV file.
#
if (DateTime->compare($filedt, $agecheckdt)
== -1) {
$canpurge = 0;
}
$lastfile = 0;
$keepfiles{$invfile}{$linecount} =
$logfiles{$invfile}{$linecount};
#
# If this is an older file and we are purging files in
# this INV file
#
} elsif ($canpurge) {
#
# If mod time is older than the purge check
# date, then add this file to the purge list
#
if (DateTime->compare($filedt, $purgelimitdt)
== -1) {
push(@purgelist,
$logfiles{$invfile}{$linecount});
$invmod{$invfile} = 1;
#
# Otherwise, keep it
#
} else {
$keepfiles{$invfile}{$linecount} =
$logfiles{$invfile}{$linecount};
}
#
# Otherwise, just put it back on the keep hash
#
} else {
$keepfiles{$invfile}{$linecount} =
$logfiles{$invfile}{$linecount};
}
#
# If file does not exist - ignore and move on
#
} else {
warn "Warning: File $logfiles{$invfile}{$linecount} does not exist\n";
}
}
}
#
# Look for files that have been orphaned from the INV files or are loosely
# associated with them.
#
foreach $invfile (@invfiles) {
#
# Build a list of log files we know about for this INV file
#
@knownlist = ();
foreach $linecount (sort {$a<=>$b} keys %{$logfiles{$invfile}}) {
push(@knownlist,$logfiles{$invfile}{$linecount});
}
#
# Get a list of all files matching the pattern of the INV file name
# and look for ones that we don't know about.
#
if ($invfile =~ /(\S+)\.inv$/) {
foreach $logfile (<$1_*.log>, <$1_*.pid*>) {
#
# If the file we have is not in the known list,
# check its mod time
#
if (not(grep { $_ eq $logfile } @knownlist)) {
$modtime = stat($logfile)->mtime;
$filedt = DateTime->from_epoch( epoch => $modtime );
#
# If mod time is older than the purge limit date
# then nothing appears to be actively writing
# to this log file, so we add it to the purge
# list.
#
if (DateTime->compare($filedt, $purgelimitdt)
== -1) {
push(@purgelist, $logfile);
}
}
}
} else {
warn "Warning: Unexpected filename format for INV file: $invfile\n";
}
}
#
# Remove the files on the purge list
#
$printflag = 0;
print "\n\nFiles being kept:\n";
foreach $invfile (@invfiles) {
#
# If the INV file was modified, output the new results
#
if ($invmod{$invfile}) {
if ($printflag) {
print "\n\t$invfile :\n";
} else {
$printflag=1;
print "\t$invfile :\n";
}
$filemode = sprintf("%04o",stat($invfile)->mode & 07777);
$fileuid = stat($invfile)->uid;
$filegid = stat($invfile)->gid;
print "\t\t(Mode $filemode, UID $fileuid, GID $filegid)\n";
open(INVFILE, ">$invfile") ||
die "Error: Unable to open the INV file $invfile for writing\n$!";
foreach $linecount (sort {$b<=>$a} keys %{$keepfiles{$invfile}}) {
print "\t\t$keepfiles{$invfile}{$linecount}\n";
print INVFILE "$keepfiles{$invfile}{$linecount}\n";
}
close (INVFILE);
chmod (oct($filemode), $invfile);
chown ($fileuid, $filegid, $invfile);
#
# Otherwise do nothing, since we don't need to write out the same
# file we read in
#
} else {
if ($printflag) {
print "\n\t$invfile (Unmodified)\n";
} else {
$printflag=1;
print "\t$invfile (Unmodified)\n";
}
}
}
print "\n\nFiles being removed (" . ($#purgelist+1) . "):\n";
foreach $logfile (@purgelist) {
print "\t$logfile\n";
unlink($logfile);
}
#
# End of file
#