[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