[interchange-cvs] interchange - heins modified 8 files
interchange-cvs at icdevgroup.org
interchange-cvs at icdevgroup.org
Sat Apr 16 12:02:12 EDT 2005
User: heins
Date: 2005-04-16 16:02:12 GMT
Added: extensions/benchtimes README catalog.cfg.add
Added: interchange.cfg.add
Added: extensions/benchtimes/bin benchtimes
Added: eg/usertag benchmark.tag sleep.tag
Removed: eg/usertag benchmark sleep
Log:
* Add "benchtimes" extension that easily allows you to analyze CPU eaters
for your Interchange catalog. Documented with README and pod for
the utility.
* Make the benchmark example usertag thread-safe.
* Add .tag extensions to the eg/usertag tags.
Revision Changes Path
1.1 interchange/extensions/benchtimes/README
rev 1.1, prev_rev 1.0
Index: README
===================================================================
benchtimes -- Simple Interchange extension to add benchmarking of catalogs
Installation:
1. Append interchange.cfg.add to your interchange.cfg file.
2. Append catalog.cfg.add to the catalog.cfg for any catalog
you want to benchmark.
3. Copy bin/benchtimes to a place where you can execute it.
You could possibly have to change the first line to point
to a proper perl, but almost any modern perl will do.
4. Periodically run "benchtimes CATDIR/logs/bench.log"
to summarize high usage. Do "perldoc bin/benchtimes"
for more information.
1.1 interchange/extensions/benchtimes/catalog.cfg.add
rev 1.1, prev_rev 1.0
Index: catalog.cfg.add
===================================================================
## Add these to your catalog.cfg file to do benchtimes
AutoLoad benchtimes_start
AutoEnd benchtimes_end
1.1 interchange/extensions/benchtimes/interchange.cfg.add
rev 1.1, prev_rev 1.0
Index: interchange.cfg.add
===================================================================
###
### Add this chunk to the end of your interchange.cfg file to enable
### benchtimes
###
UserTag benchtimes Order start display
UserTag benchtimes Routine <<EOR
sub {
my ($start, $display) = @_;
my @times = times();
if($start or ! defined $::Instance->{benchtimes_start}) {
$::Instance->{benchtimes_start} = 0;
$::Instance->{benchtimes_times} = [ @times ];
for(@times) {
$::Instance->{benchtimes_start} += $_;
}
}
my $current_total;
if($display or ! $start) {
my $benchtimes_times = $::Instance->{benchtimes_times};
for(@times) {
$current_total += $_;
}
unless ($start) {
$current_total = sprintf '%.3f', $current_total - $::Instance->{benchtimes_start};
for(my $i = 0; $i < 4; $i++) {
$times[$i] = sprintf '%.3f', $times[$i] - $benchtimes_times->[$i];
}
}
return $current_total;
}
return;
}
EOR
## You can change the location
Variable BENCHTIMES_LOG_FILE logs/bench.log
Variable BENCHTIMES_COUNTER logs/bench.counter
## Subroutine to start the logging process
GlobalSub benchtimes_start <<EOS
sub {
my @bench_things = qw( ip path session pid time count bench );
my %hash = (
ip => $CGI::remote_addr,
path => $CGI::request_uri,
session => $Vend::SessionID,
pid => $$,
time => time(),
);
$hash{count}
= $Vend::Session->{benchtimes_count}
= Vend::Interpolate::tag_counter($Global::Variable->{BENCHTIMES_COUNTER});
# Start the benchtimes
$Vend::Interpolate::Tag->benchtimes(1);
Vend::Util::logData(
$Global::Variable->{BENCHTIMES_LOG_FILE},
@hash{@bench_things}
);
return;
}
EOS
GlobalSub benchtimes_end <<EOS
sub {
my @bench_things = qw( ip path session pid time count bench );
my %hash = (
ip => $CGI::remote_addr,
path => $CGI::request_uri,
session => $Vend::SessionID,
pid => $$,
time => time(),
count => $Vend::Session->{benchtimes_count},
bench => $Vend::Interpolate::Tag->benchtimes(undef,1),
);
Vend::Util::logData(
$Global::Variable->{BENCHTIMES_LOG_FILE},
@hash{@bench_things}
);
return;
}
EOS
1.1 interchange/extensions/benchtimes/bin/benchtimes
rev 1.1, prev_rev 1.0
Index: benchtimes
===================================================================
#!/usr/bin/perl
=head1 NAME
benchtimes -- utility to analyze benchtimes logging for Interchange
=head1 SYNOPSIS
benchtimes [-n count] [-t timespec] file
=head1 DESCRIPTION
This small tool analyzes the CPU usage of Interchange by session id
and IP address. It shows the top users in seconds of time and number of hits.
=cut
use Getopt::Std;
use strict;
my %opt;
getopts('n:t:', \%opt);
use POSIX qw/strftime/;
my %session_time;
my %session_hits;
my %total_time;
my %total_hits;
my %total_elapsed;
my %earliest;
my %latest;
my %elapsed;
my %info;
# Parses a time specification such as "1 day" and returns the
# number of seconds in the interval, or undef if the string could
# not be parsed.
sub time_to_seconds {
my($str) = @_;
my($n, $dur);
($n, $dur) = ($str =~ m/(\d+)[\s\0]*(\w+)?/);
return undef unless defined $n;
if (defined $dur) {
local($_) = $dur;
if (m/^s|sec|secs|second|seconds$/i) {
}
elsif (m/^m|min|mins|minute|minutes$/i) {
$n *= 60;
}
elsif (m/^h|hour|hours$/i) {
$n *= 60 * 60;
}
elsif (m/^d|day|days$/i) {
$n *= 24 * 60 * 60;
}
elsif (m/^w|week|weeks$/i) {
$n *= 7 * 24 * 60 * 60;
}
else {
return undef;
}
}
$n;
}
=head1 OPTIONS
=over 4
=item -n count
The number of entries to display for each type. This
would display 16 of each:
benchtimes -n 16 /var/lib/interchange/foundation/logs/bench.log
Default is 10.
=item -t timespec
Determines how far back in time you want to go. Accepts a standard Interchange
time specification, i.e. "1 day" or "3 hours". This would summarize for
the past day:
benchtimes -t 1d /var/lib/interchange/foundation/logs/bench.log
Default is not set, meaning all log lines are analyzed.
=cut
my %start;
my $first = 0;
my $now = time();
if($opt{t}) {
my $minus = time_to_seconds($opt{t});
$first = $now - $minus;
}
while(<>) {
chomp;
my ($ip, $path, $sessionid, $pid, $time, $id, $bench) = split /\t/, $_;
next unless $time > $first;
if($bench) {
$session_hits{$sessionid}++;
$session_time{$sessionid} += $bench;
$total_hits{$ip}++;
$total_time{$ip} += $bench;
$info{$id} = "ip=$ip path=$path pid=$pid time=$bench";
unless($start{$id}) {
warn "Couldn't find start for $_\n";
}
elsif(! $time) {
warn "No end time for $_\n";
}
else {
$elapsed{$id} = $start{$id} - $time;
}
$total_elapsed{$ip} += $elapsed{$id};
$latest{$ip} = $time;
$latest{$sessionid} = $time;
}
else {
$start{$id} = $time;
$earliest{$ip} ||= $time;
$earliest{$sessionid} ||= $time;
}
}
my %display = (
session_time => \%session_time,
session_hits => \%session_hits,
total_hits => \%total_hits,
total_time => \%total_time,
);
my %fmt = (
session_time => '%9.3f seconds',
session_hits => '%6d hits',
total_hits => '%6d hits',
total_time => '%9.3f seconds',
);
my $started;
my $n = $opt{n} || 10;
no strict 'refs';
for my $tag (sort keys %display) {
my $ref = $display{$tag}
or warn "No reference found for $tag. Skip.\n", next;
print "\n" if $started++;
my @keys = sort { $ref->{$b} <=> $ref->{$a} } keys %$ref;
print "Displaying top $n by $tag\n";
print "---------------------------------\n";
for(my $i = 0; $i < $n; $i++) {
my $id = $keys[$i] or next;
my $early = strftime('%m-%d %H:%M:%S', localtime($earliest{$id}));
my $late = strftime('%m-%d %H:%M:%S', localtime($latest{$id}));
printf "%-20s $fmt{$tag} (from %s to %s)\n", $id, $ref->{$id}, $early, $late;
}
}
=head1 SEE ALSO
http://cvs.icdevgroup.org/cgi-bin/cvsweb/extensions/benchtimes
=head1 AUTHOR
Mike Heins, <mike (at domain) perusion.com>.
=head1 BUGS
None known at this time.
=cut
1.1 interchange/eg/usertag/benchmark.tag
rev 1.1, prev_rev 1.0
Index: benchmark.tag
===================================================================
UserTag benchmark Order start display
UserTag benchmark AddAttr
UserTag benchmark Routine <<EOR
sub {
my ($start, $display, $opt) = @_;
my @times = times();
my @bench_times;
if($start or ! defined $::Instance->{bench_start}) {
$::Instance->{bench_start} = 0;
$::Instance->{bench_times} = [ @times ];
for(@times) {
$::Instance->{bench_start} += $_;
}
}
my $current_total;
if($display or ! $start) {
my $bench_times = $::Instance->{bench_times};
for(@times) {
$current_total += $_;
}
unless ($start) {
$current_total = sprintf '%.3f', $current_total - $::Instance->{bench_start};
for(my $i = 0; $i < 4; $i++) {
$times[$i] = sprintf '%.3f', $times[$i] - $bench_times->[$i];
}
}
return $current_total if ! $opt->{verbose};
return "total=$current_total user=$times[0] sys=$times[1] cuser=$times[2] csys=$times[3]";
}
return;
}
EOR
1.1 interchange/eg/usertag/sleep.tag
rev 1.1, prev_rev 1.0
Index: sleep.tag
===================================================================
UserTag sleep Documentation <<EOD
Will cause a pause for the number of seconds specified. To pause
3 seconds, do:
[sleep 3]
EOD
UserTag sleep Order seconds
UserTag sleep Routine <<EOR
sub {
my $secs = shift || '10';
if($secs > 60) {
::logError("no sleeping for more than 60 seconds");
return;
}
$secs = int($secs);
sleep($secs);
return $secs;
}
EOR
More information about the interchange-cvs
mailing list