To inform decisions about future products, we at Network Appliance would
like to get a feel for current command usage by customers,
particularly as used from scripts. Unfortunately, autosupport doesn't
contain the level of detail that we'd like to see. Attached below is a
perl script that will look at the auditlogs of a filer running Data
ONTAP and summarize command, sub-command, and api usage. Only a summary is
produced - it shouldn't contain any customer-sensitive information.
It will not put any load on the filer, and should consume only a minute
or so of CPU time on the machine running the perl script (depending on
how large your auditlog files are). Here's a small sample of the output:
count=24 rsh=vol options
count=9 rsh=vol status
count=6 rsh=version
count=5 rsh=sysconfig -a
count=3 rsh=vol create
count=3 rsh=reboot -t
count=11 cons=version
count=6 cons=options ldap
count=22 api=perf-object-instance-list-info
count=16 api=perf-object-counter-list-info
count=13 api=options-get
We would greatly appreciate it if anyone using Data ONTAP could run this
script and send the output to usage(a)netapp.com (a special address set up
to collect this data). Usage is described in the comments at the top of
the file. Thanks much.
...Tim Thompson...Network Appliance, Inc...tjt(a)netapp.com...
#----------------------------- cut here -----------------------------
#!/usr/local/bin/perl
#
# This script summarizes command and api usage on a
# Network Appliance filer running Data ONTAP. In other words, it counts
# how many times each command/sub-command has been used, by
# looking at the auditlogs.
#
# Usage on Unix is:
#
# cd /mnt/$FILER/etc # where /mnt/$FILER is the mounted root volume
# perl cmdsummary.pl
#
# or on Windows:
#
# cd F: # where F: is the mounted root volume
# cd \etc
# perl cmdsummary.pl
#
# In other words, change directories to the /etc directory of the
# filer's root volume, and run this script. The script looks at
# the messages file and all the auditlog files, and summarizes
# command and api usage.
my %rshusage;
my %consusage;
my %apiusage;
my $system = "";
my $anyerr = 0;
foreach $f (<messages log/auditlog*>) {
if ( ! open(FF, $f) ) {
print STDERR "Error: unable to open $f - $!\n\n"
."This program must be run in the "
."'etc' directory of the filer's root volume.\n\n";
$anyerr = 1;
next
}
while (<FF>) {
if ( /kern.log.rotate:/ || /log_rotate:/ ) {
chop;
$system = $_;
$system =~ s/.*System /System /;
}
elsif ( /RSH INPUT COMMAND/ ) {
my $s = $_;
$s =~ s/.*RSH INPUT COMMAND is //;
my @words = split(/[\s;]/,$s);
my $cmd = $words[0]." ".$words[1];
if ( $words[0] ne "" ) {
if ( not defined $rshusage{$cmd} ) {
$rshusage{$cmd} = 1;
} else {
$rshusage{$cmd} += 1;
}
}
}
elsif ( /IN:console shell:/ ) {
my $s = $_;
$s =~ s/.*console shell://;
my @words = split(/\s/,$s);
my $cmd = $words[0]." ".$words[1];
if ( $words[0] ne "" ) {
if ( not defined $consusage{$cmd} ) {
$consusage{$cmd} = 1;
} else {
$consusage{$cmd} += 1;
}
}
}
elsif ( /Java_Thread.*:API:in:/ && ! /relog syslog/ ) {
chop;
my $api = $_;
$api =~ s/[^<]*<//;
$api =~ s/\/?>.*//;
if ( not defined $apiusage{"Java-$api"} ) {
$apiusage{"Java-$api"} = 1;
} else {
$apiusage{"Java-$api"} += 1;
}
}
elsif ( /:API:in:/ && ! /relog syslog/ ) {
chop;
my $api = $_;
$api =~ s/.*\/admin\'><//;
$api =~ s/.*version="..."><//;
$api =~ s/\/?>.*//;
if ( not defined $apiusage{$api} ) {
$apiusage{$api} = 1;
} else {
$apiusage{$api} += 1;
}
}
}
}
if ( $system ne "" ) {
print("$system\n");
}
foreach $key ( sort { $rshusage{$b} <=> $rshusage{$a} } keys %rshusage ) {
print("count=$rshusage{$key} rsh=$key\n");
}
foreach $key ( sort { $consusage{$b} <=> $consusage{$a} } keys %consusage ) {
print("count=$consusage{$key} cons=$key\n");
}
foreach $key ( sort { $apiusage{$b} <=> $apiusage{$a} } keys %apiusage ) {
print("count=$apiusage{$key} api=$key\n");
}
exit($anyerr);
#----------------------------- end of script -----------------------------