Thank you very much. I 'll do my best to help you improve this module. Thank you.
----- Original Message ----- From: "Skylos the Doggie" <[EMAIL PROTECTED]> To: "Abd El-Hameed Mohammed" <[EMAIL PROTECTED]> Cc: "Ged Haywood" <[EMAIL PROTECTED]>; <[EMAIL PROTECTED]> Sent: Tuesday, October 07, 2003 5:39 PM Subject: Re: Apache bandwidth calculating > In Tue, 7 Oct 2003, Abd El-Hameed Mohammed wrote: > > > Thank you all. > > OK > > Let me ask again, are there any way to store a web site bandwidth statistics > > in a file or a database > > Yes. > > I adapted some of the Apache::AuthDBI module into a logging hook that > interfaces to a database via dbi via custom query(ies). You can use > tokens I've defined to insert just about any of the available retrievable > information from the objects available to a module into the custom > queries. You can use this to execute any custom query on a database with > time and bandwidth used, for instance thus allowing you to generate the > most detailed bandwidth statistics you could ever want, or as general as > you like. Group it how you please. > > This is not a fully tested module. Use at your own risk. Help me make > it better. > > Perldoc should work on it to help you figure out how to use the tokens. > > Ask if you hvae any questions, and please let me know of any suggestions > for improvements! > > With intrepidation, here is the code. > > Skylos > > --- > > package Apache::ActivityLogDBI; > > use Apache (); > use Apache::Constants qw( OK SERVER_ERROR ); > use DBI (); > use strict; > > # $Id: ActivityLogDBI.pm,v 0.01 2003/10/07 08:36:38 ask Exp $ > > require_version DBI 1.00; > > $ActivityLogDBI::VERSION = '0.01'; > > # 1: report about cache miss > # 2: full debug output > $ActivityLogDBI::DEBUG = 0; > > # configuration attributes, defaults will be overwritten with values from .htaccess. > > my %Config = ( > 'Activity_Log_DBI_data_source' => '', > 'Activity_Log_DBI_username' => '', > 'Activity_Log_DBI_password' => '', > ); > > # stores the configuration of current URL. > # initialized during authentication, eventually re-used for authorization. > my $Attr = { }; > > # rectify queries with the appropriate information > sub subvars { > my $r = shift; > my $query = shift; > my $dbh = shift; > > my $s = $r->server; > my $c = $r->connection; > > my $vals = { > CONNECTION_REMOTEHOST => sub { $c->remote_host(); }, > CONNECTION_REMOTEIP => sub { $c->remote_ip(); }, > CONNECTION_REMOTELOGNAME => sub { $c->remote_logname(); }, > CONNECTION_USER => sub { $c->user(); }, > CONNECTION_AUTHTYPE => sub { $c->auth_type(); }, > CONNECTION_ABORTED => sub { $c->aborted(); }, > > REQUEST_METHOD => sub { $r->method(); }, > REQUEST_BYTES => sub { $r->bytes_sent(); }, > REQUEST_HEADER => sub { $r->header_only(); }, > REQUEST_PROTOCOL => sub { $r->protocol(); }, > REQUEST_HOSTNAME => sub { $r->hostname(); }, > REQUEST_TIME => sub { my @d = localtime($r->time()); sprintf '%04d-%02d-%02d %02d:%02d:%02d', 1900+$d[5], 1+$d[4], $d[3], $d[2], $d[1], $d[0]; }, > REQUEST_URI => sub { $r->uri(); }, > REQUEST_FILENAME => sub { $r->filename(); }, > REQUEST_LOCATION => sub { $r->location(); }, > REQUEST_PATH_INFO => sub { $r->path_info(); }, > REQUEST_ARGS => sub { $r->args(); }, > > SERVER_DOCUMENTROOT => sub { $s->document_root(); }, > SERVER_SERVERROOT => sub { $s->server_root_relative(); }, > SERVER_SERVERPORT => sub { $s->get_server_port(); }, > SERVER_ADMIN => sub { $s->server_admin(); }, > SERVER_HOSTNAME => sub { $s->server_hostname(); }, > SERVER_ISVIRTUAL => sub { $s->server_is_virtual(); }, > SERVER_UID => sub { $s->uid(); }, > SERVER_GID => sub { $s->gid(); }, > SERVER_LOGLEVEL => sub { $s->loglevel(); }, > > }; > foreach (keys %{$vals}) { > if ($query =~ /$_/) { > my $value = $dbh->quote($vals->{$_}->()); > $query =~ s/$_/$value/g; > } > } > return $query; > } > > # log handler > sub log { > my ($r) = @_; > my ($key, $val, $dbh); > > my $prefix = "$$ ActivityLogDBI::log"; > > if ($ActivityLogDBI::DEBUG > 1) { > my ($type) = ''; > $type .= 'initial ' if $r->is_initial_req; > $type .= 'main' if $r->is_main; > print STDERR "==========\n$prefix request type = >$type< \n"; > } > > return OK unless $r->is_initial_req; # only the first internal request > > print STDERR "REQUEST:\n", $r->as_string if $ActivityLogDBI::DEBUG > 2; > > # get username > my ($user_sent) = $r->connection->user; > print STDERR "$prefix user sent = >$user_sent<\n" if $ActivityLogDBI::DEBUG > 1; > > # get configuration > while(($key, $val) = each %Config) { > $val = $r->dir_config($key) || $val; > $key =~ s/^Activity_Log_DBI_//; > $Attr->{$key} = $val; > printf STDERR "$prefix Config{ %-16s } = %s\n", $key, $val if $ActivityLogDBI::DEBUG > 1; > } > > my @queries; > my $temp = $r->dir_config(); > while(($key, $val) = each %{$temp}) { > next unless ($key =~ /^Activity_Log_DBI_Query/); > push @queries, $val; > printf STDERR "$prefix Config{ %-16s } = %s\n", $key, $val if $ActivityLogDBI::DEBUG > 1; > } > undef $temp; > > unless (scalar @queries) { > printf STDERR "$prefix No queries - return OK\n" if $ActivityLogDBI::DEBUG > 1; > return OK; > } > > # parse connect attributes, which may be tilde separated lists > my @data_sources = split(/~/, $Attr->{data_source}); > my @usernames = split(/~/, $Attr->{username}); > my @passwords = split(/~/, $Attr->{password}); > $data_sources[0] = '' unless $data_sources[0]; # use ENV{DBI_DSN} if not defined > > # connect to database, use all data_sources until the connect succeeds > my $j; > for ($j = 0; $j <= $#data_sources; $j++) { > last if ($dbh = DBI->connect($data_sources[$j], $usernames[$j], $passwords[$j])); > } > unless ($dbh) { > $r->log_reason("$prefix db connect error with data_source >$Attr->{data_source}<", $r->uri); > return SERVER_ERROR; > } > > foreach (@queries) { > # generate statement > my $statement = subvars $r, $_, $dbh; > print STDERR "$prefix statement: $statement\n" if $ActivityLogDBI::DEBUG > 1; > > # run statement > my $rows; > unless ($rows = $dbh->do($statement)) { > $r->log_reason("$prefix can not do statement: $DBI::errstr $DBI::lasth->{Statement}", $r->uri); > $dbh->disconnect; > return SERVER_ERROR; > } > > print STDERR "$prefix rows affected: $rows\n" if $ActivityLogDBI::DEBUG > 0; > > if ($dbh->err) { > $dbh->disconnect; > return SERVER_ERROR; > } > > } > $dbh->disconnect; > > printf STDERR "$prefix return OK\n" if $ActivityLogDBI::DEBUG > 1; > return OK; > } > > 1; > > __END__ > > > =head1 NAME > > ActivityLogDBI - Activity Logging via Perl's DBI > > > =head1 SYNOPSIS > > # Configuration in httpd.conf or startup.pl: > > PerlModule Apache::ActivityLogDBI > > PerlLogHandler ActivityLogDBI::log > > PerlSetVar Activity_Log_DBI_data_source dbi:driver:dsn > PerlSetVar Activity_Log_DBI_username db_username > PerlSetVar Activity_Log_DBI_password db_password > #DBI->connect($data_source, $username, $password) > > PerlSetVar Activity_Log_DBI_Query[...] custom queries > > Any active variables that start with Activity_Log_DBI_Query is executed > upon the triggering of the logging hook. Use the variable scoping for > sites and directories to overwrite lower level queries as necessary. > > =head1 DESCRIPTION > > This module allows custom logging against a database using Perl's DBI. For > supported DBI drivers see: > > http://dbi.perl.org/ > > =head1 LIST OF TOKENS > > =item * > Activity_Log_DBI_data_source (Database Authentication) > > The data_source value has the syntax 'dbi:driver:dsn'. This parameter is > passed to the database driver for processing during connect. The data_source > parameter (as well as the username and the password parameters) may be a > tilde ('~') separated list of several data_sources. All of these triples will > be used until a successful connect is made. This way several backup-servers can > be configured. if you want to use the environment variable DBI_DSN instead of > a data_source, do not specify this parameter at all. > > =item * > Activity_Log_DBI_username (Database Authentication) > > The username argument is passed to the database driver for processing during > connect. This parameter may be a tilde ('~') separated list. See the data_source > parameter above for the usage of a list. > > =item * > Activity_Log_DBI_password (Database Authentication) > > The password argument is passed to the database driver for processing during > connect. This parameter may be a tilde ('~') separated list. See the data_source > parameter above for the usage of a list. > > =item * > Activity_Log_DBI_Query[...] > > Any token beginning with 'Activity_Log_DBI_Query' will be added to a list of > queries that are executed on the DBI connection when the activity hook is > implimented. See MACROS below for macros that will automatically be substituted > in for values from the module environment. > > =head1 CONFIGURATION > > The module should be loaded upon startup of the Apache daemon. > Add the following line to your httpd.conf: > > PerlModule Apache::ActivityLogDBI > > A common usage is to load the module in a startup file via the PerlRequire > directive. See eg/startup.pl for an example. > > To enable debugging the variable $ActivityLogDBI::DEBUG must be set. This > can either be done in startup.pl or in the user script. Setting the variable > to 1, just reports about a cache miss. Setting the variable to 2 enables full > debug output. > > > =head1 PREREQUISITES > > Note that this module needs mod_perl-1.08 or higher, apache_1.3.0 or higher > and that mod_perl needs to be configured with the appropriate call-back hooks: > > PERL_LOG=1 PERL_STACKED_HANDLERS=1 > > > =head1 SECURITY > > In some cases it is more secure not to put the username and the password in > the .htaccess file. The following example shows a solution to this problem: > > httpd.conf: > > <Perl> > my($uid,$pwd) = My::dbi_pwd_fetch(); > $Location{'/foo/bar'}->{PerlSetVar} = [ > [ Activity_Log_DBI_username => $uid ], > [ Activity_Log_DBI_password => $pwd ], > ]; > </Perl> > > > =head1 MACROS > > =item * > CONNECTION_REMOTEHOST > > Output of the remote_host() method of the Connection object. > > =item * > CONNECTION_REMOTEIP > > Output of the remote_ip() method of the Connection object. > > =item * > CONNECTION_REMOTELOGNAME > > Output of the remote_logname() method of the Connection object. > > =item * > CONNECTION_USER > > Output of the user() method of the Connection object. > > =item * > CONNECTION_AUTHTYPE > > Output of the auth_type() method of the Connection object. > > =item * > CONNECTION_ABORTED > > Output of the aborted() method of the Connection object. > > =item * > REQUEST_METHOD > > Output of the method() method of the Request object. > > =item * > REQUEST_BYTES > > Output of the bytes_sent() method of the Request object. > > =item * > REQUEST_HEADER > > Output of the header_only() method of the Request object. > > =item * > REQUEST_PROTOCOL > > Output of the protocol() method of the Request object. > > =item * > REQUEST_HOSTNAME > > Output of the hostname() method of the Request object. > > =item * > REQUEST_TIME > > ISO formatted output of the time() method of the Request object. > > =item * > REQUEST_URI > > Output of the uri() method of the Request object. > > =item * > REQUEST_FILENAME > > Output of the filename() method of the Request object. > > =item * > REQUEST_LOCATION > > Output of the location() method of the Request object. > > =item * > REQUEST_PATH_INFO > > Output of the path_info() method of the Request object. > > =item * > REQUEST_ARGS > > Output of the args() method of the Request object. > > =item * > SERVER_DOCUMENTROOT > > Output of the document_root() method of the Request object. > > =item * > SERVER_SERVERROOT > > Output of the server_root_realative() method of the Request object. > > =item * > SERVER_SERVERPORT > > Output of the get_server_port() method of the Request object. > > =item * > SERVER_ADMIN > > Output of the server_admin() method of the Request object. > > =item * > SERVER_HOSTNAME > > Output of the server_hostname() method of the Server object. > > =item * > SERVER_ISVIRTUAL > > Output of the server_is_virtual() method of the Server object. > > =item * > SERVER_UID > > Output of the uid() method of the Server object. > > =item * > SERVER_GID > > Output of the gid() method of the Server object. > > =item * > SERVER_LOGLEVEL > > Output of the loglevel() method of the Server object. > > > =head1 SEE ALSO > > L<Apache>, L<mod_perl>, L<DBI> > > > =head1 AUTHORS > > =item * > Apache::ActivityLogDBI by David Ihnen <[EMAIL PROTECTED]> > > =item * > Code structure derived from Apache::AuthDBI by Edmund Mergl; now maintained and > supported by the modperl mailinglist. > > =item * > mod_perl by Doug MacEachern <[EMAIL PROTECTED]> > > =item * > DBI by Tim Bunce <[EMAIL PROTECTED]> > > > > =head1 COPYRIGHT > > The ActivityLogDBI module is free software; you can redistribute it and/or > modify it under the same terms as Perl itself. > > =cut > --- > > > ----- Original Message ----- > > From: "Ged Haywood" <[EMAIL PROTECTED]> > > To: "Abd El-Hameed Mohammed" <[EMAIL PROTECTED]> > > Cc: <[EMAIL PROTECTED]> > > Sent: Sunday, October 05, 2003 12:45 PM > > Subject: Re: Apache bandwidth calculating > > > > > > > Hi there, > > > > > > On Fri, 3 Oct 2003, Abd El-Hameed Mohammed wrote: > > > > > > > Do any one know where i can find the source of mod_bwlimited > > > > or any recources for modules like it. > > > > > > http://modules.apache.org/search > > > > > > Type the word "bandwidth" into the box. > > > > > > Try CPAN too, and you might want to look at > > > > > > http://www.modperlcookbook.org/chapters/ch13.pdf > > > > > > in which Geoff which mentions mod_throttle_access > > > (and brings us more-or-less back on-topic:). > > > > > > 73, > > > Ged. > > > > > > [This E-mail scanned for viruses using McAfee.] > > > > > > > > > > > > > > > - [EMAIL PROTECTED] > - The best part about the internet is nobody knows you're a dog. > (Peter Stiener, The New Yorker, July 5, 1993) > - Dogs like... TRUCKS! (Nissan commercial, 1996) > - PGP key: http://dogpawz.com/skylos/mykey.asc > >