Hi Tim,
fine tool to get an overview of command usage !
I made a small enhancement, because due to security reasons we don't use rsh but ssh for remote administration of filers...
Feel free to use this enhanced script below in the future.
Norbert
=================== enhanced cmd summary script begin ============================ #!/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 cmd_summary.pl # # or on Windows: # # cd F: # where F: is the mounted root volume # cd \etc # perl cmd_summary.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. # # The output of the command will look like this: # ############################################################################ # System tweety (ID 0033611543) is running NetApp Release 7.0.1 # count=167 rsh=sysconfig -a # count=28 rsh=version # count=11 rsh=options autosupport.enable # count=167 ssh=sysconfig -a # count=28 ssh=version # count=571 api=options-get # count=100 api=options-set # count=23 cons=version ############################################################################ # # The lines in this output specify the frequency count of things invoked in # three categories: rsh (commands submitted using rsh), cons (commands # submitted using telnet or on the serial console), and api (things executed # using the ONTAPI API interface). # fourth category added: ssh (commands submitted using ssh) #
my %rshusage; my %sshusage; 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 ( /SSH INPUT COMMAND/ ) { my $s = $_; $s =~ s/.*SSH INPUT COMMAND is //; my @words = split(/[\s;]/,$s); my $cmd = $words[0]." ".$words[1]; if ( $words[0] ne "" ) { if ( not defined $sshusage{$cmd} ) { $sshusage{$cmd} = 1; } else { $sshusage{$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 { $sshusage{$b} <=> $sshusage{$a} } keys %sshusage ) { print("count=$sshusage{$key} ssh=$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"); =================== enhanced cmd summary script end ============================
-----Ursprüngliche Nachricht----- Von: owner-toasters@mathworks.com [mailto:owner-toasters@mathworks.com] Im Auftrag von Tim Thompson Gesendet: Mittwoch, 24. Mai 2006 00:00 An: toasters@mathworks.com Betreff: command usage summary, 2006
The following is a request similar to one made here a little over a year ago. The recent survey about advanced commands was very useful, and reminded us that it would be good to refresh and augment our data about command usage. 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).
We would greatly appreciate it if anyone using Data ONTAP could run this script on as many filers as possible and send the output to usage@netapp.com (a special address set up to collect this data). Usage is described in the comments at the top of the script.
If you don't feel comfortable running a script you've received through email, you can run the identical script that you can find in the Toolchest section of NetApp's NOW site: http://now.netapp.com/NOW/download/tools/cmd_summary/
Thanks very much for your help.
...Tim Thompson...Network Appliance, Inc...tjt@netapp.com...
#!/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 cmd_summary.pl # # or on Windows: # # cd F: # where F: is the mounted root volume # cd \etc # perl cmd_summary.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. # # The output of the command will look like this: # ############################################################################ # System tweety (ID 0033611543) is running NetApp Release 7.0.1 # count=167 rsh=sysconfig -a # count=28 rsh=version # count=11 rsh=options autosupport.enable # count=571 api=options-get # count=100 api=options-set # count=23 cons=version ############################################################################ # # The lines in this output specify the frequency count of things invoked in # three categories: rsh (commands submitted using rsh), cons (commands # submitted using telnet or on the serial console), and api (things executed # using the ONTAPI API interface).
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);