| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | ####################################################################### | 
| 2 |  |  |  |  |  |  | # Apache::ParseLog | 
| 3 |  |  |  |  |  |  | # | 
| 4 |  |  |  |  |  |  | #    Module to parse and process the Apache log files | 
| 5 |  |  |  |  |  |  | # | 
| 6 |  |  |  |  |  |  | #    See the manpage for the usage | 
| 7 |  |  |  |  |  |  | # | 
| 8 |  |  |  |  |  |  | #    Written by Akira Hangai | 
| 9 |  |  |  |  |  |  | #    For comments, suggestions, opinions, etc., | 
| 10 |  |  |  |  |  |  | #    email to: akira@discover-net.net | 
| 11 |  |  |  |  |  |  | # | 
| 12 |  |  |  |  |  |  | #    Copyright 1998 by Akira Hangai. All rights reserved. | 
| 13 |  |  |  |  |  |  | #    This program is free software; You can redistribute it and/or | 
| 14 |  |  |  |  |  |  | #    modify it under the same terms as Perl itself. | 
| 15 |  |  |  |  |  |  | ####################################################################### | 
| 16 |  |  |  |  |  |  | package Apache::ParseLog; | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | require 5.005; | 
| 19 | 9 |  |  | 9 |  | 23903 | use Carp; | 
|  | 9 |  |  |  |  | 17 |  | 
|  | 9 |  |  |  |  | 937 |  | 
| 20 | 9 |  |  | 9 |  | 52 | use vars qw($VERSION); | 
|  | 9 |  |  |  |  | 16 |  | 
|  | 9 |  |  |  |  | 112542 |  | 
| 21 |  |  |  |  |  |  | $VERSION = "1.02"; | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | require Exporter; | 
| 24 |  |  |  |  |  |  | @ISA = qw(Exporter); | 
| 25 |  |  |  |  |  |  | @EXPORT = qw(countryByCode statusByCode sortHashByValue); | 
| 26 |  |  |  |  |  |  | @EXPORT_OK = qw(countryByCode statusByCode sortHashByValue); | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | =head1 NAME | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | Apache::ParseLog - Object-oriented Perl extension for parsing Apache log files | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 33 |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  | use Apache::ParseLog; | 
| 35 |  |  |  |  |  |  | $base = new Apache::ParseLog(); | 
| 36 |  |  |  |  |  |  | $transferlog = $base->getTransferLog(); | 
| 37 |  |  |  |  |  |  | %dailytransferredbytes = $transferlog->bytebydate(); | 
| 38 |  |  |  |  |  |  | ... | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | Apache::ParseLog provides an easy way to parse the Apache log files, | 
| 43 |  |  |  |  |  |  | using object-oriented constructs. The data obtained using this module | 
| 44 |  |  |  |  |  |  | are generic enough that it is flexible to use the data for your own | 
| 45 |  |  |  |  |  |  | applications, such as CGI, simple text-only report generater, feeding | 
| 46 |  |  |  |  |  |  | RDBMS, data for Perl/Tk-based GUI application, etc. | 
| 47 |  |  |  |  |  |  |  | 
| 48 |  |  |  |  |  |  | =head1 FEATURES | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | =over 4 | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | =item 1 | 
| 53 |  |  |  |  |  |  |  | 
| 54 |  |  |  |  |  |  | B | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | Because all of the work (parsing logs, constructing regex, matching and | 
| 57 |  |  |  |  |  |  | assigning to variables, etc.) is done inside this module, you can easily | 
| 58 |  |  |  |  |  |  | create log reports (unless your logs need intense scrutiny). Read on this | 
| 59 |  |  |  |  |  |  | manpage as well as the L<"EXAMPLES"> section to see how easy it is to | 
| 60 |  |  |  |  |  |  | create log reports with this module. | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  | Also, this module does not require C compiler, and it can (should) run on | 
| 63 |  |  |  |  |  |  | any platforms supported by Perl. | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | =item 2 | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | B | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | The Apache Web Server 1.3.x's new LogForamt/CustomLog feature (with | 
| 70 |  |  |  |  |  |  | mod_log_config) is supported. | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | The log format specified with Apache's F directive in the | 
| 73 |  |  |  |  |  |  | F file will be parsed and the regular expressions will be | 
| 74 |  |  |  |  |  |  | created dynamically inside this module, so re-writing your existing | 
| 75 |  |  |  |  |  |  | code will be minimal when the log format is changed. | 
| 76 |  |  |  |  |  |  |  | 
| 77 |  |  |  |  |  |  | =item 3 | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | B | 
| 80 |  |  |  |  |  |  |  | 
| 81 |  |  |  |  |  |  | Tranditionally, the hit count is calculated based on the number of B | 
| 82 |  |  |  |  |  |  | requested by visitors (the simplest is the the total number of lines of | 
| 83 |  |  |  |  |  |  | the log file calculated as the "total hit"). | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | As such, the hit count obviously can be misleading in the sense of "how | 
| 86 |  |  |  |  |  |  | many visitors have actually visited my site?", especially if the | 
| 87 |  |  |  |  |  |  | pages of your site contain many images (because each image is counted as | 
| 88 |  |  |  |  |  |  | one hit). | 
| 89 |  |  |  |  |  |  |  | 
| 90 |  |  |  |  |  |  | Apache::ParseLog provides the methods to obtain such traditional data, | 
| 91 |  |  |  |  |  |  | because those data also are very important for monitoring your web | 
| 92 |  |  |  |  |  |  | site's activities. However, this module also provides the methods to | 
| 93 |  |  |  |  |  |  | obtain the B, i.e., the actual number of "people" | 
| 94 |  |  |  |  |  |  | (well, IP or hostname) who visited your site, by date, time, and date | 
| 95 |  |  |  |  |  |  | and time. | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | See the L<"LOG OBJECT METHODS"> for details about those methods. | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | =item 4 | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | B | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | The new pre-compiled regex feature introduced by Perl 5.005 is used (if | 
| 104 |  |  |  |  |  |  | you have the version installed on your machine). | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | For the pre-compiled regex and the new quote-like assignment operator (qr), | 
| 107 |  |  |  |  |  |  | see perlop(1) and perlre(1) manpages. | 
| 108 |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  | =back | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | =cut | 
| 112 |  |  |  |  |  |  |  | 
| 113 |  |  |  |  |  |  | ####################################################################### | 
| 114 |  |  |  |  |  |  | # Local variables | 
| 115 |  |  |  |  |  |  | local($HOST, $LOGIN, $DATETIME, $REQUEST, $OSTATUS, $LSTATUS, $BYTE, $FILENAME, $ADDR, $PORT, $PROC, $SEC, $URL, $HOSTNAME, $REFERER, $UAGENT); | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | my(%COUNTRY_BY_CODE) = map { | 
| 118 |  |  |  |  |  |  | chomp; | 
| 119 |  |  |  |  |  |  | my(@line) = split(/:/); | 
| 120 |  |  |  |  |  |  | $line[0] => $line[1] | 
| 121 |  |  |  |  |  |  | } ; | 
| 122 |  |  |  |  |  |  |  | 
| 123 |  |  |  |  |  |  | my(%STATUS_BY_CODE) = ( | 
| 124 |  |  |  |  |  |  | 100 => "Continue", | 
| 125 |  |  |  |  |  |  | 101 => "Switching Protocols", | 
| 126 |  |  |  |  |  |  | 200 => "OK", | 
| 127 |  |  |  |  |  |  | 201 => "Created", | 
| 128 |  |  |  |  |  |  | 202 => "Accepted", | 
| 129 |  |  |  |  |  |  | 203 => "Non-Authoritative Information", | 
| 130 |  |  |  |  |  |  | 204 => "No Content", | 
| 131 |  |  |  |  |  |  | 205 => "Reset Content", | 
| 132 |  |  |  |  |  |  | 206 => "Partial Content", | 
| 133 |  |  |  |  |  |  | 300 => "Multiple Choices", | 
| 134 |  |  |  |  |  |  | 301 => "Moved Permanently", | 
| 135 |  |  |  |  |  |  | 302 => "Moved Temporarily", | 
| 136 |  |  |  |  |  |  | 303 => "See Other", | 
| 137 |  |  |  |  |  |  | 304 => "Not Modified", | 
| 138 |  |  |  |  |  |  | 305 => "Use Proxy", | 
| 139 |  |  |  |  |  |  | 400 => "Bad Request", | 
| 140 |  |  |  |  |  |  | 401 => "Unauthorized", | 
| 141 |  |  |  |  |  |  | 402 => "Payment Required", | 
| 142 |  |  |  |  |  |  | 403 => "Forbidden", | 
| 143 |  |  |  |  |  |  | 404 => "Not Found", | 
| 144 |  |  |  |  |  |  | 405 => "Method Not Allowed", | 
| 145 |  |  |  |  |  |  | 406 => "Not Acceptable", | 
| 146 |  |  |  |  |  |  | 407 => "Proxy Authentication Required", | 
| 147 |  |  |  |  |  |  | 408 => "Request Time-out", | 
| 148 |  |  |  |  |  |  | 409 => "Conflict", | 
| 149 |  |  |  |  |  |  | 410 => "Gone", | 
| 150 |  |  |  |  |  |  | 411 => "Length Required", | 
| 151 |  |  |  |  |  |  | 412 => "Precondition Failed", | 
| 152 |  |  |  |  |  |  | 413 => "Request Entity Too Large", | 
| 153 |  |  |  |  |  |  | 414 => "Request-URI Too Large", | 
| 154 |  |  |  |  |  |  | 415 => "Unsupported Media Type", | 
| 155 |  |  |  |  |  |  | 500 => "Internal Server Error", | 
| 156 |  |  |  |  |  |  | 501 => "Not Implemented", | 
| 157 |  |  |  |  |  |  | 502 => "Bad Gateway", | 
| 158 |  |  |  |  |  |  | 503 => "Service Unavailable", | 
| 159 |  |  |  |  |  |  | 504 => "Gateway Time-out", | 
| 160 |  |  |  |  |  |  | 505 => "HTTP Version not supported", | 
| 161 |  |  |  |  |  |  | ); | 
| 162 |  |  |  |  |  |  |  | 
| 163 |  |  |  |  |  |  | my(%M2N) = ( | 
| 164 |  |  |  |  |  |  | 'Jan' => '01', | 
| 165 |  |  |  |  |  |  | 'Feb' => '02', | 
| 166 |  |  |  |  |  |  | 'Mar' => '03', | 
| 167 |  |  |  |  |  |  | 'Apr' => '04', | 
| 168 |  |  |  |  |  |  | 'May' => '05', | 
| 169 |  |  |  |  |  |  | 'Jun' => '06', | 
| 170 |  |  |  |  |  |  | 'Jul' => '07', | 
| 171 |  |  |  |  |  |  | 'Aug' => '08', | 
| 172 |  |  |  |  |  |  | 'Sep' => '09', | 
| 173 |  |  |  |  |  |  | 'Oct' => '10', | 
| 174 |  |  |  |  |  |  | 'Nov' => '11', | 
| 175 |  |  |  |  |  |  | 'Dec' => '12', | 
| 176 |  |  |  |  |  |  | ); | 
| 177 |  |  |  |  |  |  |  | 
| 178 |  |  |  |  |  |  | ####################################################################### | 
| 179 |  |  |  |  |  |  | # Constructor | 
| 180 |  |  |  |  |  |  | ####################################################################### | 
| 181 |  |  |  |  |  |  | =pod | 
| 182 |  |  |  |  |  |  |  | 
| 183 |  |  |  |  |  |  | =head1 CONSTRUCTOR | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | To construct an Apache::ParseLog object,B method is available | 
| 186 |  |  |  |  |  |  | just like other modules. | 
| 187 |  |  |  |  |  |  |  | 
| 188 |  |  |  |  |  |  | The C constructor returns an Apache::ParseLog base object with | 
| 189 |  |  |  |  |  |  | which to obtain basic server information as well as to construct | 
| 190 |  |  |  |  |  |  | B. | 
| 191 |  |  |  |  |  |  |  | 
| 192 |  |  |  |  |  |  | =cut | 
| 193 |  |  |  |  |  |  |  | 
| 194 |  |  |  |  |  |  | ####################################################################### | 
| 195 |  |  |  |  |  |  | # new([$path_to_httpd.conf]); returns ParseLog object | 
| 196 |  |  |  |  |  |  | =pod | 
| 197 |  |  |  |  |  |  |  | 
| 198 |  |  |  |  |  |  | =head2 New Method | 
| 199 |  |  |  |  |  |  |  | 
| 200 |  |  |  |  |  |  | B> | 
| 201 |  |  |  |  |  |  |  | 
| 202 |  |  |  |  |  |  | With the B> method, an Apache::ParseLog object can be created | 
| 203 |  |  |  |  |  |  | in three different ways. | 
| 204 |  |  |  |  |  |  |  | 
| 205 |  |  |  |  |  |  | =over 4 | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | =item 1 | 
| 208 |  |  |  |  |  |  |  | 
| 209 |  |  |  |  |  |  | C<$base = new Apache::ParseLog();> | 
| 210 |  |  |  |  |  |  |  | 
| 211 |  |  |  |  |  |  | This first method creates an empty object, which means that the fields of | 
| 212 |  |  |  |  |  |  | the object are undefined (C); i.e., the object does not know | 
| 213 |  |  |  |  |  |  | what the server name is, where the log files are, etc. It is useful | 
| 214 |  |  |  |  |  |  | when you need to parse log files that are B created on the local | 
| 215 |  |  |  |  |  |  | Apache server (e.g., the log files FTP'd from elsewhere). | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | You have to use the B> method (see below) to call any | 
| 218 |  |  |  |  |  |  | other methods. | 
| 219 |  |  |  |  |  |  |  | 
| 220 |  |  |  |  |  |  | =item 2 | 
| 221 |  |  |  |  |  |  |  | 
| 222 |  |  |  |  |  |  | C<$base = new Apache::ParseLog($httpd_conf);> | 
| 223 |  |  |  |  |  |  |  | 
| 224 |  |  |  |  |  |  | This is the second way to create an object with necessary information | 
| 225 |  |  |  |  |  |  | extracted from the I<$httpd_conf>. I<$httpd_conf> is a scalar string | 
| 226 |  |  |  |  |  |  | containing the absolute path to the F file; e.g., | 
| 227 |  |  |  |  |  |  |  | 
| 228 |  |  |  |  |  |  | $httpd_conf = "/usr/local/httpd/conf/httpd.conf"; | 
| 229 |  |  |  |  |  |  |  | 
| 230 |  |  |  |  |  |  | This method tries to extract the information from I<$httpd_conf>, | 
| 231 |  |  |  |  |  |  | specified by the following Apache directives: | 
| 232 |  |  |  |  |  |  | F, F, F, F, F, | 
| 233 |  |  |  |  |  |  | F, F, and any user-defined F along | 
| 234 |  |  |  |  |  |  | with F. | 
| 235 |  |  |  |  |  |  |  | 
| 236 |  |  |  |  |  |  | If any of the directives cannot be found or commented out in the | 
| 237 |  |  |  |  |  |  | I<$httpd_conf>, then the field(s) for that directive(s) will be | 
| 238 |  |  |  |  |  |  | empty (C), and corresponding methods that use the particular fields | 
| 239 |  |  |  |  |  |  | return an empty string when called, or error out (for B | 
| 240 |  |  |  |  |  |  | methods>, refer to the section below). | 
| 241 |  |  |  |  |  |  |  | 
| 242 |  |  |  |  |  |  | =item 3 | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | C<$base = new Apache::ParseLog($httpd_conf, $virtual_host);> | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | This method creates an object just like the second method, but for the | 
| 247 |  |  |  |  |  |  | VirtualHost specified by I<$virtual_host> B. The Apache directives | 
| 248 |  |  |  |  |  |  | and rules not specified within the  and | 
| 249 |  |  |  |  |  |  | tags are parsed from the "regular" server section in the F file. | 
| 250 |  |  |  |  |  |  |  | 
| 251 |  |  |  |  |  |  | Note that the I<$httpd_conf> B be specified in order to create an | 
| 252 |  |  |  |  |  |  | object for the I<$virtual_host>. | 
| 253 |  |  |  |  |  |  |  | 
| 254 |  |  |  |  |  |  | =back | 
| 255 |  |  |  |  |  |  |  | 
| 256 |  |  |  |  |  |  | =cut | 
| 257 |  |  |  |  |  |  |  | 
| 258 |  |  |  |  |  |  | sub new { | 
| 259 | 10 |  |  | 10 | 0 | 59826 | my($package) = shift; | 
| 260 | 10 |  |  |  |  | 151 | my($httpd_conf) = shift; | 
| 261 | 10 |  |  |  |  | 141 | my($virtual_host) = shift; | 
| 262 | 10 |  |  |  |  | 76 | my(%ARG); | 
| 263 | 10 |  |  |  |  | 115 | my($METHOD) = "Apache::ParseLog::new"; | 
| 264 | 10 | 100 |  |  |  | 190 | if (defined($httpd_conf)) { | 
| 265 | 8 | 50 |  |  |  | 704 | unless (-e $httpd_conf) { | 
| 266 | 0 |  |  |  |  | 0 | croak "$METHOD: $httpd_conf does not exist. Exiting..."; | 
| 267 |  |  |  |  |  |  | } else { | 
| 268 | 8 |  |  |  |  | 359 | %ARG = populate($httpd_conf, $virtual_host); | 
| 269 |  |  |  |  |  |  | } | 
| 270 |  |  |  |  |  |  | } | 
| 271 | 10 |  |  |  |  | 125 | return config($package, %ARG); | 
| 272 |  |  |  |  |  |  | } | 
| 273 |  |  |  |  |  |  |  | 
| 274 |  |  |  |  |  |  | ####################################################################### | 
| 275 |  |  |  |  |  |  | # BASE OBJECT METHODS | 
| 276 |  |  |  |  |  |  | ####################################################################### | 
| 277 |  |  |  |  |  |  | =pod | 
| 278 |  |  |  |  |  |  |  | 
| 279 |  |  |  |  |  |  | =head1 BASE OBJECT METHODS | 
| 280 |  |  |  |  |  |  |  | 
| 281 |  |  |  |  |  |  | This section describes the methods available for the base object created | 
| 282 |  |  |  |  |  |  | by the B> construct described above. | 
| 283 |  |  |  |  |  |  |  | 
| 284 |  |  |  |  |  |  | Unless the object is created with an empty argument, the Apache::ParseLog | 
| 285 |  |  |  |  |  |  | module parses the basic information configured in the F file | 
| 286 |  |  |  |  |  |  | (as passed as the first argument). The object uses the information | 
| 287 |  |  |  |  |  |  | to construct the B. | 
| 288 |  |  |  |  |  |  |  | 
| 289 |  |  |  |  |  |  | The available methods are (return values are in parentheses): | 
| 290 |  |  |  |  |  |  |  | 
| 291 |  |  |  |  |  |  | $base->config([%fields]); # (object) | 
| 292 |  |  |  |  |  |  | $base->version(); # (scalar) | 
| 293 |  |  |  |  |  |  | $base->serverroot(); # (scalar) | 
| 294 |  |  |  |  |  |  | $base->servername(); # (scalar) | 
| 295 |  |  |  |  |  |  | $base->httpport(); # (scalar) | 
| 296 |  |  |  |  |  |  | $base->serveradmin(); # (scalar) | 
| 297 |  |  |  |  |  |  | $base->transferlog(); # (scalar) | 
| 298 |  |  |  |  |  |  | $base->errorlog(); # (scalar) | 
| 299 |  |  |  |  |  |  | $base->agentlog(); # (scalar) | 
| 300 |  |  |  |  |  |  | $base->refererlog(); # (scalar) | 
| 301 |  |  |  |  |  |  | $base->customlog(); # (array) | 
| 302 |  |  |  |  |  |  | $base->customlogLocation($name); # (scalar) | 
| 303 |  |  |  |  |  |  | $base->customlogExists($name); # (scalar boolean, 1 or 0) | 
| 304 |  |  |  |  |  |  | $base->customlogFormat($name); # (scalar) | 
| 305 |  |  |  |  |  |  | $base->getTransferLog(); # (object) | 
| 306 |  |  |  |  |  |  | $base->getErrorLog(); # (object) | 
| 307 |  |  |  |  |  |  | $base->getRefererLog(); # (object) | 
| 308 |  |  |  |  |  |  | $base->getAgentLog(); # (object) | 
| 309 |  |  |  |  |  |  | $base->getCustomLog(); # (object) | 
| 310 |  |  |  |  |  |  |  | 
| 311 |  |  |  |  |  |  | =over 4 | 
| 312 |  |  |  |  |  |  |  | 
| 313 |  |  |  |  |  |  | =cut | 
| 314 |  |  |  |  |  |  |  | 
| 315 |  |  |  |  |  |  |  | 
| 316 |  |  |  |  |  |  | ####################################################################### | 
| 317 |  |  |  |  |  |  | # config($ParseLog, %arg); returns ParseLog object | 
| 318 |  |  |  |  |  |  | =pod | 
| 319 |  |  |  |  |  |  |  | 
| 320 |  |  |  |  |  |  | =item * | 
| 321 |  |  |  |  |  |  |  | 
| 322 |  |  |  |  |  |  | C | 
| 323 |  |  |  |  |  |  |  | 
| 324 |  |  |  |  |  |  | $base = $base->config(field1 => value1, | 
| 325 |  |  |  |  |  |  | field2 => valud2, | 
| 326 |  |  |  |  |  |  | fieldN => valueN); | 
| 327 |  |  |  |  |  |  |  | 
| 328 |  |  |  |  |  |  | This method configures the Apache::ParseLog object. Possible fields are: | 
| 329 |  |  |  |  |  |  |  | 
| 330 |  |  |  |  |  |  | Field Name                     Value | 
| 331 |  |  |  |  |  |  | --------------------------------------------------------- | 
| 332 |  |  |  |  |  |  | serverroot  => absolute path to the server root directory | 
| 333 |  |  |  |  |  |  | servername  => name of the server, e.g., "www.mysite.com" | 
| 334 |  |  |  |  |  |  | httpport    => httpd port, e.g., 80 | 
| 335 |  |  |  |  |  |  | serveradmin => the administrator, e.g., "admin@mysite.com" | 
| 336 |  |  |  |  |  |  | transferlog => absolute path to the transfer log | 
| 337 |  |  |  |  |  |  | errorlog    => absolute path to the error log | 
| 338 |  |  |  |  |  |  | agentlog    => absolute path to the agent log | 
| 339 |  |  |  |  |  |  | refererlog  => absolute path to the referer log | 
| 340 |  |  |  |  |  |  |  | 
| 341 |  |  |  |  |  |  | This method should be called after the empty object is created | 
| 342 |  |  |  |  |  |  | (C, see above). However, you can override the value(s) for any | 
| 343 |  |  |  |  |  |  | fields by calling this method even if the object is created with defined | 
| 344 |  |  |  |  |  |  | I<$httpd_conf> and I<$virtual_host>. (Convenient if you don't have any | 
| 345 |  |  |  |  |  |  | httpd server running on your machine but have to parse the log files | 
| 346 |  |  |  |  |  |  | transferred from elsewhere.) | 
| 347 |  |  |  |  |  |  |  | 
| 348 |  |  |  |  |  |  | Any fields are optional, but at least one field should be specified | 
| 349 |  |  |  |  |  |  | (otherwise why use this method?). | 
| 350 |  |  |  |  |  |  |  | 
| 351 |  |  |  |  |  |  | When this method is called from the empty object, and B all the fields | 
| 352 |  |  |  |  |  |  | are specified, the empty field still will be empty (thereby not being able | 
| 353 |  |  |  |  |  |  | to use some corresponding methods). | 
| 354 |  |  |  |  |  |  |  | 
| 355 |  |  |  |  |  |  | When this method is called from the already configured object (with | 
| 356 |  |  |  |  |  |  | C), the fields specified in | 
| 357 |  |  |  |  |  |  | this C method will override the existing field values, and | 
| 358 |  |  |  |  |  |  | the rest of the fields inherit the pre-existing values. | 
| 359 |  |  |  |  |  |  |  | 
| 360 |  |  |  |  |  |  | B This method B, so make sure | 
| 361 |  |  |  |  |  |  | to use the assignment operator to create the new object | 
| 362 |  |  |  |  |  |  | (see examples below). | 
| 363 |  |  |  |  |  |  |  | 
| 364 |  |  |  |  |  |  | B You B (re)configure F values. It is to alleviate | 
| 365 |  |  |  |  |  |  | the possible broken log formats, which would render the parsed results | 
| 366 |  |  |  |  |  |  | unusable. | 
| 367 |  |  |  |  |  |  |  | 
| 368 |  |  |  |  |  |  | Example 1 | 
| 369 |  |  |  |  |  |  |  | 
| 370 |  |  |  |  |  |  | # Create an empty object first | 
| 371 |  |  |  |  |  |  | $base = new Apache::ParseLog(); | 
| 372 |  |  |  |  |  |  | # Configure the transfer and error fields only, for the files | 
| 373 |  |  |  |  |  |  | # transferred from your Web site hosting service | 
| 374 |  |  |  |  |  |  | $logs = "/home/webmaster/logs"; | 
| 375 |  |  |  |  |  |  | $base = $base->config(transferlog => "$logs/transfer_log", | 
| 376 |  |  |  |  |  |  | errorlog    => "$logs/error_log"); | 
| 377 |  |  |  |  |  |  |  | 
| 378 |  |  |  |  |  |  | Example 2 | 
| 379 |  |  |  |  |  |  |  | 
| 380 |  |  |  |  |  |  | # Create an object with $httpd_conf | 
| 381 |  |  |  |  |  |  | $base = new Apache::ParseLog("/usr/local/httpd/conf/httpd.conf"); | 
| 382 |  |  |  |  |  |  | # Overrides some fields | 
| 383 |  |  |  |  |  |  | $logs = "/usr/local/httpd/logs"; | 
| 384 |  |  |  |  |  |  | $base = $base->config(transferlog => "$logs/old/trans_199807", | 
| 385 |  |  |  |  |  |  | errorlog    => "$logs/old/error_199807", | 
| 386 |  |  |  |  |  |  | agentlog    => "$logs/old/agent_199807", | 
| 387 |  |  |  |  |  |  | refererlog  => "$logs/old/refer_199807"); | 
| 388 |  |  |  |  |  |  |  | 
| 389 |  |  |  |  |  |  | =cut | 
| 390 |  |  |  |  |  |  |  | 
| 391 |  |  |  |  |  |  | sub config { | 
| 392 | 16 |  |  | 16 | 0 | 4115 | my($this, %arg) = @_; | 
| 393 | 16 |  |  |  |  | 49 | my($root, $servername, $port, $admin, $transfer, $error, $agent, $referer, %customlog); | 
| 394 | 16 |  | 100 |  |  | 178 | $serverroot = $arg{'serverroot'} || $this->{'serverroot'}; | 
| 395 | 16 |  | 100 |  |  | 127 | $servername = $arg{'servername'} || $this->{'servername'}; | 
| 396 | 16 |  | 100 |  |  | 228 | $httpport = $arg{'httpport'} || $this->{'httpport'}; | 
| 397 | 16 |  | 100 |  |  | 111 | $serveradmin = $arg{'serveradmin'} || $this->{'serveradmin'}; | 
| 398 | 16 |  | 100 |  |  | 111 | $transferlog = $arg{'transferlog'} || $this->{'transferlog'}; | 
| 399 | 16 |  | 100 |  |  | 143 | $errorlog = $arg{'errorlog'} || $this->{'errorlog'}; | 
| 400 | 16 |  | 100 |  |  | 116 | $agentlog = $arg{'agentlog'} || $this->{'agentlog'}; | 
| 401 | 16 |  | 100 |  |  | 111 | $refererlog = $arg{'refererlog'} || $this->{'refererlog'}; | 
| 402 | 16 |  | 100 |  |  | 87 | $customlog = $arg{'customlog'} || $this->{'customlog'}; | 
| 403 | 16 |  |  |  |  | 362 | return bless { | 
| 404 |  |  |  |  |  |  | 'serverroot'  => $serverroot, | 
| 405 |  |  |  |  |  |  | 'servername'  => $servername, | 
| 406 |  |  |  |  |  |  | 'httpport'    => $httpport, | 
| 407 |  |  |  |  |  |  | 'serveradmin' => $serveradmin, | 
| 408 |  |  |  |  |  |  | 'transferlog' => $transferlog, | 
| 409 |  |  |  |  |  |  | 'errorlog'    => $errorlog, | 
| 410 |  |  |  |  |  |  | 'agentlog'    => $agentlog, | 
| 411 |  |  |  |  |  |  | 'refererlog'  => $refererlog, | 
| 412 |  |  |  |  |  |  | 'customlog'   => $customlog, | 
| 413 |  |  |  |  |  |  | } | 
| 414 |  |  |  |  |  |  | } | 
| 415 |  |  |  |  |  |  |  | 
| 416 |  |  |  |  |  |  | ####################################################################### | 
| 417 |  |  |  |  |  |  | # populate($path_to_httpd.conf[, $virtualHost]); return %arg; private | 
| 418 |  |  |  |  |  |  | sub populate { | 
| 419 | 8 |  |  | 8 | 0 | 83 | my($conf) = shift; | 
| 420 | 8 |  |  |  |  | 33 | my($virtualhost) = shift; | 
| 421 | 8 | 100 |  |  |  | 72 | my($VIRTUAL) = ($virtualhost ? 1 : 0); | 
| 422 | 8 |  |  |  |  | 36 | my(%arg, $fh, $line, $serverroot, $servername, $httpport, $serveradmin, $transferlog, $errorlog, $agentlog, $refererlog, $customlog, @nickname, %location, %format); | 
| 423 | 8 |  |  |  |  | 133 | $fh = openFile($conf); | 
| 424 | 8 |  |  |  |  | 368 | while(defined($line = <$fh>)) { | 
| 425 | 327 |  |  |  |  | 964 | chomp($line); | 
| 426 | 327 | 100 |  |  |  | 1533 | if ($line =~ /^ServerRoot\s+(.+)$/) { | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 427 | 8 |  |  |  |  | 152 | $serverroot = $1; | 
| 428 |  |  |  |  |  |  | } elsif ($line =~ /^Port\s+(.+)$/) { | 
| 429 | 7 |  |  |  |  | 106 | $httpport = $1; | 
| 430 |  |  |  |  |  |  | } elsif ($line =~ /^LogFormat\s+"(.+)"\s+(\w+)$/) { | 
| 431 | 44 |  |  |  |  | 390 | $format{$2} = $1; | 
| 432 |  |  |  |  |  |  | } | 
| 433 | 327 | 100 |  |  |  | 651 | unless ($VIRTUAL) {        # check only when $VIRTUAL == 0 | 
| 434 | 256 | 100 |  |  |  | 2023 | if ($line =~ /^ServerName\s+(.+)$/) { | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 435 | 7 |  |  |  |  | 24 | $servername = $1; | 
| 436 |  |  |  |  |  |  | } elsif ($line =~ /^ServerAdmin\s+(.+)$/) { | 
| 437 | 7 |  |  |  |  | 99 | $serveradmin = $1; | 
| 438 |  |  |  |  |  |  | } elsif ($line =~ /^TransferLog\s+(.+)$/) { | 
| 439 | 6 |  |  |  |  | 20 | $transferlog = $1; | 
| 440 |  |  |  |  |  |  | } elsif ($line =~ /^ErrorLog\s+(.+)$/) { | 
| 441 | 7 |  |  |  |  | 28 | $errorlog =  $1; | 
| 442 |  |  |  |  |  |  | } elsif ($line =~ /^AgentLog\s+(.+)$/) { | 
| 443 | 6 |  |  |  |  | 20 | $agentlog = $1; | 
| 444 |  |  |  |  |  |  | } elsif ($line =~ /^RefererLog\s+(.+)$/) { | 
| 445 | 6 |  |  |  |  | 19 | $refererlog = $1; | 
| 446 |  |  |  |  |  |  | } elsif ($line =~ /^CustomLog\s+(.+)\s+(\w+)$/) { | 
| 447 | 39 |  |  |  |  | 130 | my($loc) = $1; | 
| 448 | 39 |  |  |  |  | 112 | push(@nickname, $2); | 
| 449 | 39 | 50 |  |  |  | 170 | if ($loc =~ m#\|#) { undef $loc } | 
|  | 0 | 50 |  |  |  | 0 |  | 
| 450 | 39 |  |  |  |  | 99 | elsif ($loc !~ m#^/#) { $loc = "$serverroot/$loc" } | 
| 451 | 39 |  |  |  |  | 130 | $location{$2} = $loc; | 
| 452 |  |  |  |  |  |  | } | 
| 453 |  |  |  |  |  |  | } | 
| 454 | 327 | 100 |  |  |  | 645 | if (defined($virtualhost)) { | 
| 455 | 46 | 100 |  |  |  | 451 | if ($line =~ m#^#) { | 
|  |  | 100 |  |  |  |  |  | 
| 456 | 1 | 50 |  |  |  | 80 | if ($1 =~ /$virtualhost/i) {   # if matches, 0 | 
| 457 | 1 |  |  |  |  | 7 | $VIRTUAL = 0; | 
| 458 |  |  |  |  |  |  | } | 
| 459 |  |  |  |  |  |  | } elsif ($line =~ m#^#) { | 
| 460 | 1 |  |  |  |  | 12 | $VIRTUAL = 1;                  # if matches, 0 | 
| 461 |  |  |  |  |  |  | } | 
| 462 |  |  |  |  |  |  | } else { | 
| 463 | 281 | 100 |  |  |  | 1445 | if ($line =~ m#^ | 
|  |  | 100 |  |  |  |  |  | 
| 464 | 6 |  |  |  |  | 172 | $VIRTUAL = 1; | 
| 465 |  |  |  |  |  |  | } elsif ($line =~ m#^#) { | 
| 466 | 6 |  |  |  |  | 21 | $VIRTUAL = 0; | 
| 467 |  |  |  |  |  |  | } | 
| 468 |  |  |  |  |  |  | } | 
| 469 |  |  |  |  |  |  | } | 
| 470 | 8 |  |  |  |  | 169 | close($fh); | 
| 471 | 8 |  | 50 |  |  | 58 | $arg{'serverroot'} = $serverroot || undef; | 
| 472 | 8 |  | 100 |  |  | 170 | $arg{'servername'} = $servername || undef; | 
| 473 | 8 |  | 100 |  |  | 68 | $arg{'httpport'} = $httpport || undef; | 
| 474 | 8 |  | 100 |  |  | 60 | $arg{'serveradmin'} = $serveradmin || undef; | 
| 475 | 8 | 100 |  |  |  | 29 | if ($transferlog) { | 
| 476 | 6 | 50 |  |  |  | 47 | if ($transferlog !~ m#^/#) { | 
|  |  | 0 |  |  |  |  |  | 
| 477 | 6 |  |  |  |  | 27 | $transferlog = "$serverroot/$transferlog" | 
| 478 |  |  |  |  |  |  | } elsif ($transferlog =~ m#\|#) { | 
| 479 | 0 |  |  |  |  | 0 | undef $transferlog | 
| 480 |  |  |  |  |  |  | } | 
| 481 |  |  |  |  |  |  | } | 
| 482 | 8 |  |  |  |  | 32 | $arg{'transferlog'} = $transferlog; | 
| 483 | 8 | 100 |  |  |  | 62 | if ($errorlog) { | 
| 484 | 7 | 50 |  |  |  | 43 | if ($errorlog !~ m#^/#) { | 
|  |  | 0 |  |  |  |  |  | 
| 485 | 7 |  |  |  |  | 37 | $errorlog = "$serverroot/$errorlog" | 
| 486 |  |  |  |  |  |  | } elsif ($errorlog =~ m#\|#) { | 
| 487 | 0 |  |  |  |  | 0 | undef $errorlog | 
| 488 |  |  |  |  |  |  | } | 
| 489 |  |  |  |  |  |  | } | 
| 490 | 8 |  |  |  |  | 37 | $arg{'errorlog'} = $errorlog; | 
| 491 | 8 | 100 |  |  |  | 54 | if ($agentlog) { | 
| 492 | 6 | 50 |  |  |  | 25 | if ($agentlog !~ m#^/#) { | 
|  |  | 0 |  |  |  |  |  | 
| 493 | 6 |  |  |  |  | 20 | $agentlog = "$serverroot/$agentlog" | 
| 494 |  |  |  |  |  |  | } elsif ($agentlog =~ m#\|#) { | 
| 495 | 0 |  |  |  |  | 0 | undef $agentlog | 
| 496 |  |  |  |  |  |  | } | 
| 497 |  |  |  |  |  |  | } | 
| 498 | 8 |  |  |  |  | 26 | $arg{'agentlog'} = $agentlog; | 
| 499 | 8 | 100 |  |  |  | 54 | if ($refererlog) { | 
| 500 | 6 | 50 |  |  |  | 23 | if ($refererlog !~ m#^/#) { | 
|  |  | 0 |  |  |  |  |  | 
| 501 | 6 |  |  |  |  | 20 | $refererlog = "$serverroot/$refererlog" | 
| 502 |  |  |  |  |  |  | } elsif ($refererlog =~ m#\|#) { | 
| 503 | 0 |  |  |  |  | 0 | undef $refererlog | 
| 504 |  |  |  |  |  |  | } | 
| 505 |  |  |  |  |  |  | } | 
| 506 | 8 |  |  |  |  | 25 | $arg{'refererlog'} = $refererlog; | 
| 507 | 8 |  |  |  |  | 226 | $customlog = { | 
| 508 |  |  |  |  |  |  | 'nickname' => [ @nickname ], | 
| 509 |  |  |  |  |  |  | 'format'   => { %format }, | 
| 510 |  |  |  |  |  |  | 'location' => { %location }, | 
| 511 |  |  |  |  |  |  | }; | 
| 512 | 8 |  |  |  |  | 50 | $arg{'customlog'} = $customlog; | 
| 513 | 8 |  |  |  |  | 376 | return %arg; | 
| 514 |  |  |  |  |  |  | } | 
| 515 |  |  |  |  |  |  |  | 
| 516 |  |  |  |  |  |  | ####################################################################### | 
| 517 |  |  |  |  |  |  | # serverroot(); returns $serverroot | 
| 518 |  |  |  |  |  |  | =pod | 
| 519 |  |  |  |  |  |  |  | 
| 520 |  |  |  |  |  |  | =item * | 
| 521 |  |  |  |  |  |  |  | 
| 522 |  |  |  |  |  |  | C | 
| 523 |  |  |  |  |  |  |  | 
| 524 |  |  |  |  |  |  | print $base->serverroot(), "\n"; | 
| 525 |  |  |  |  |  |  |  | 
| 526 |  |  |  |  |  |  | Returns a scalar containing the root of the Web server as specified | 
| 527 |  |  |  |  |  |  | in the F file, or C if the object is not specified. | 
| 528 |  |  |  |  |  |  |  | 
| 529 |  |  |  |  |  |  | =cut | 
| 530 |  |  |  |  |  |  |  | 
| 531 |  |  |  |  |  |  | sub serverroot { | 
| 532 | 7 |  |  | 7 | 0 | 22 | my($this) = shift; | 
| 533 | 7 |  | 50 |  |  | 59 | return $this->{'serverroot'} || undef; | 
| 534 |  |  |  |  |  |  | } | 
| 535 |  |  |  |  |  |  |  | 
| 536 |  |  |  |  |  |  | ####################################################################### | 
| 537 |  |  |  |  |  |  | # servername(); returns $servername | 
| 538 |  |  |  |  |  |  | =pod | 
| 539 |  |  |  |  |  |  |  | 
| 540 |  |  |  |  |  |  | =item * | 
| 541 |  |  |  |  |  |  |  | 
| 542 |  |  |  |  |  |  | C | 
| 543 |  |  |  |  |  |  |  | 
| 544 |  |  |  |  |  |  | print $base->servername(), "\n"; | 
| 545 |  |  |  |  |  |  |  | 
| 546 |  |  |  |  |  |  | Returns a scalar containing the name of the Web server, or C | 
| 547 |  |  |  |  |  |  | if server name is not specified. | 
| 548 |  |  |  |  |  |  |  | 
| 549 |  |  |  |  |  |  | =cut | 
| 550 |  |  |  |  |  |  |  | 
| 551 |  |  |  |  |  |  | sub servername { | 
| 552 | 2 |  |  | 2 | 0 | 821 | my($this) = shift; | 
| 553 | 2 |  | 50 |  |  | 30 | return $this->{'servername'} || undef; | 
| 554 |  |  |  |  |  |  | } | 
| 555 |  |  |  |  |  |  |  | 
| 556 |  |  |  |  |  |  | ####################################################################### | 
| 557 |  |  |  |  |  |  | # httpport(); returns $port | 
| 558 |  |  |  |  |  |  | =pod | 
| 559 |  |  |  |  |  |  |  | 
| 560 |  |  |  |  |  |  | =item * | 
| 561 |  |  |  |  |  |  |  | 
| 562 |  |  |  |  |  |  | C | 
| 563 |  |  |  |  |  |  |  | 
| 564 |  |  |  |  |  |  | print $base->httpport(), "\n"; | 
| 565 |  |  |  |  |  |  |  | 
| 566 |  |  |  |  |  |  | Returns a scalar containing the port number used for the httpd, or C | 
| 567 |  |  |  |  |  |  | if not specified. (By default, httpd uses port 80.) | 
| 568 |  |  |  |  |  |  |  | 
| 569 |  |  |  |  |  |  | =cut | 
| 570 |  |  |  |  |  |  |  | 
| 571 |  |  |  |  |  |  | sub httpport { | 
| 572 | 1 |  |  | 1 | 0 | 10 | my($this) = shift; | 
| 573 | 1 |  | 50 |  |  | 5 | return $this->{'httpport'} || undef; | 
| 574 |  |  |  |  |  |  | } | 
| 575 |  |  |  |  |  |  |  | 
| 576 |  |  |  |  |  |  | ####################################################################### | 
| 577 |  |  |  |  |  |  | # serveradmin(); returns $serveradmin | 
| 578 |  |  |  |  |  |  | =pod | 
| 579 |  |  |  |  |  |  |  | 
| 580 |  |  |  |  |  |  | =item * | 
| 581 |  |  |  |  |  |  |  | 
| 582 |  |  |  |  |  |  | C | 
| 583 |  |  |  |  |  |  |  | 
| 584 |  |  |  |  |  |  | print $base->serveradmin(), "\n"; | 
| 585 |  |  |  |  |  |  |  | 
| 586 |  |  |  |  |  |  | Returns a scalar containing the name of the server administrator, | 
| 587 |  |  |  |  |  |  | or C if not specified. | 
| 588 |  |  |  |  |  |  |  | 
| 589 |  |  |  |  |  |  | =cut | 
| 590 |  |  |  |  |  |  |  | 
| 591 |  |  |  |  |  |  | sub serveradmin { | 
| 592 | 2 |  |  | 2 | 0 | 43 | my($this) = shift; | 
| 593 | 2 |  | 50 |  |  | 14 | return $this->{'serveradmin'} || undef; | 
| 594 |  |  |  |  |  |  | } | 
| 595 |  |  |  |  |  |  |  | 
| 596 |  |  |  |  |  |  | ####################################################################### | 
| 597 |  |  |  |  |  |  | # transferlog(); returns $transferlog | 
| 598 |  |  |  |  |  |  | =pod | 
| 599 |  |  |  |  |  |  |  | 
| 600 |  |  |  |  |  |  | =item * | 
| 601 |  |  |  |  |  |  |  | 
| 602 |  |  |  |  |  |  | C | 
| 603 |  |  |  |  |  |  |  | 
| 604 |  |  |  |  |  |  | die "$!\n" unless -e $base->transferlog(); | 
| 605 |  |  |  |  |  |  |  | 
| 606 |  |  |  |  |  |  | Returns a scalar containing the absolute path to the transfer log file, | 
| 607 |  |  |  |  |  |  | or C if not specified. | 
| 608 |  |  |  |  |  |  |  | 
| 609 |  |  |  |  |  |  | =cut | 
| 610 |  |  |  |  |  |  |  | 
| 611 |  |  |  |  |  |  | sub transferlog { | 
| 612 | 1 |  |  | 1 | 0 | 11 | my($this) = shift; | 
| 613 | 1 |  | 50 |  |  | 4 | return $this->{'transferlog'} || undef; | 
| 614 |  |  |  |  |  |  | } | 
| 615 |  |  |  |  |  |  |  | 
| 616 |  |  |  |  |  |  | ####################################################################### | 
| 617 |  |  |  |  |  |  | # errorlog(); returns $errorlog | 
| 618 |  |  |  |  |  |  | =pod | 
| 619 |  |  |  |  |  |  |  | 
| 620 |  |  |  |  |  |  | =item * | 
| 621 |  |  |  |  |  |  |  | 
| 622 |  |  |  |  |  |  | C | 
| 623 |  |  |  |  |  |  |  | 
| 624 |  |  |  |  |  |  | die "$!\n" unless -e $base->errorlog(); | 
| 625 |  |  |  |  |  |  |  | 
| 626 |  |  |  |  |  |  | Returns a scalar containing the absolute path to the error log file, | 
| 627 |  |  |  |  |  |  | or C if not specified. | 
| 628 |  |  |  |  |  |  |  | 
| 629 |  |  |  |  |  |  | =cut | 
| 630 |  |  |  |  |  |  |  | 
| 631 |  |  |  |  |  |  | sub errorlog { | 
| 632 | 2 |  |  | 2 | 0 | 39 | my($this) = shift; | 
| 633 | 2 |  | 50 |  |  | 26 | return $this->{'errorlog'} || undef; | 
| 634 |  |  |  |  |  |  | } | 
| 635 |  |  |  |  |  |  |  | 
| 636 |  |  |  |  |  |  | ####################################################################### | 
| 637 |  |  |  |  |  |  | # agentlog(); returns $agentlog | 
| 638 |  |  |  |  |  |  | =pod | 
| 639 |  |  |  |  |  |  |  | 
| 640 |  |  |  |  |  |  | =item * | 
| 641 |  |  |  |  |  |  |  | 
| 642 |  |  |  |  |  |  | C | 
| 643 |  |  |  |  |  |  |  | 
| 644 |  |  |  |  |  |  | die "$!\n" unless -e $base->agentlog(); | 
| 645 |  |  |  |  |  |  |  | 
| 646 |  |  |  |  |  |  | Returns a scalar containing the absolute path to the agent log file, | 
| 647 |  |  |  |  |  |  | or C if not specified. | 
| 648 |  |  |  |  |  |  |  | 
| 649 |  |  |  |  |  |  | =cut | 
| 650 |  |  |  |  |  |  |  | 
| 651 |  |  |  |  |  |  | sub agentlog { | 
| 652 | 1 |  |  | 1 | 0 | 15 | my($this) = shift; | 
| 653 | 1 |  | 50 |  |  | 8 | return $this->{'agentlog'} || undef; | 
| 654 |  |  |  |  |  |  | } | 
| 655 |  |  |  |  |  |  |  | 
| 656 |  |  |  |  |  |  | ####################################################################### | 
| 657 |  |  |  |  |  |  | # refererlog(); returns $refererlog | 
| 658 |  |  |  |  |  |  | =pod | 
| 659 |  |  |  |  |  |  |  | 
| 660 |  |  |  |  |  |  | =item * | 
| 661 |  |  |  |  |  |  |  | 
| 662 |  |  |  |  |  |  | C | 
| 663 |  |  |  |  |  |  |  | 
| 664 |  |  |  |  |  |  | die "$!\n" unless -e $base->refererlog(); | 
| 665 |  |  |  |  |  |  |  | 
| 666 |  |  |  |  |  |  | Returns a scalar containing the absolute path to the referer log file, | 
| 667 |  |  |  |  |  |  | or C if not specified. | 
| 668 |  |  |  |  |  |  |  | 
| 669 |  |  |  |  |  |  | =cut | 
| 670 |  |  |  |  |  |  |  | 
| 671 |  |  |  |  |  |  | sub refererlog { | 
| 672 | 1 |  |  | 1 | 0 | 12 | my($this) = shift; | 
| 673 | 1 |  | 50 |  |  | 7 | return $this->{'refererlog'} || undef; | 
| 674 |  |  |  |  |  |  | } | 
| 675 |  |  |  |  |  |  |  | 
| 676 |  |  |  |  |  |  | ####################################################################### | 
| 677 |  |  |  |  |  |  | # customlog(); returns @customlog | 
| 678 |  |  |  |  |  |  | =pod | 
| 679 |  |  |  |  |  |  |  | 
| 680 |  |  |  |  |  |  | =item * | 
| 681 |  |  |  |  |  |  |  | 
| 682 |  |  |  |  |  |  | C | 
| 683 |  |  |  |  |  |  |  | 
| 684 |  |  |  |  |  |  | @customlog = $base->customlog(); | 
| 685 |  |  |  |  |  |  |  | 
| 686 |  |  |  |  |  |  | Returns an array containing "nicknames" of the custom logs defined in | 
| 687 |  |  |  |  |  |  | the I<$httpd_conf>. | 
| 688 |  |  |  |  |  |  |  | 
| 689 |  |  |  |  |  |  | =cut | 
| 690 |  |  |  |  |  |  |  | 
| 691 |  |  |  |  |  |  | sub customlog { | 
| 692 | 8 |  |  | 8 | 0 | 38 | my($this) = shift; | 
| 693 | 8 |  |  |  |  | 11 | return @{ ${$this->{'customlog'}}{'nickname'} }; | 
|  | 8 |  |  |  |  | 1001 |  | 
|  | 8 |  |  |  |  | 58 |  | 
| 694 |  |  |  |  |  |  | } | 
| 695 |  |  |  |  |  |  |  | 
| 696 |  |  |  |  |  |  | ####################################################################### | 
| 697 |  |  |  |  |  |  | # customlogDefined($customlog_nickname); returns 1 or 0; private | 
| 698 |  |  |  |  |  |  | sub customlogDefined { | 
| 699 | 6 |  |  | 6 | 0 | 8 | my($this) = shift; | 
| 700 | 6 |  |  |  |  | 8 | my($nickname) = shift; | 
| 701 | 6 |  |  |  |  | 9 | my($switch) = 0; | 
| 702 | 6 |  |  |  |  | 16 | my(@logs) = customlog($this); | 
| 703 | 6 |  |  |  |  | 18 | foreach (@logs) { | 
| 704 | 9 | 100 |  |  |  | 26 | if ($_ eq $nickname) { | 
| 705 | 6 |  |  |  |  | 9 | $switch++; | 
| 706 | 6 |  |  |  |  | 8 | last; | 
| 707 |  |  |  |  |  |  | } | 
| 708 |  |  |  |  |  |  | } | 
| 709 | 6 |  |  |  |  | 22 | return $switch; | 
| 710 |  |  |  |  |  |  | } | 
| 711 |  |  |  |  |  |  |  | 
| 712 |  |  |  |  |  |  | ####################################################################### | 
| 713 |  |  |  |  |  |  | # customlogLocation($customlog_nickname); returns path to the log | 
| 714 |  |  |  |  |  |  | =pod | 
| 715 |  |  |  |  |  |  |  | 
| 716 |  |  |  |  |  |  | =item * | 
| 717 |  |  |  |  |  |  |  | 
| 718 |  |  |  |  |  |  | C | 
| 719 |  |  |  |  |  |  |  | 
| 720 |  |  |  |  |  |  | print $base->customlogLocation($name), "\n"; | 
| 721 |  |  |  |  |  |  |  | 
| 722 |  |  |  |  |  |  | Returns a scalar containing the absolute path to the custom log I<$name>. | 
| 723 |  |  |  |  |  |  | If the custom log I<$name> does not exist, it will return C. | 
| 724 |  |  |  |  |  |  |  | 
| 725 |  |  |  |  |  |  | This method should be used for debugging purposes only, since you can call | 
| 726 |  |  |  |  |  |  | C to parse the logs, making it unnecessary to manually open | 
| 727 |  |  |  |  |  |  | the custom log file in your own script. | 
| 728 |  |  |  |  |  |  |  | 
| 729 |  |  |  |  |  |  | =cut | 
| 730 |  |  |  |  |  |  |  | 
| 731 |  |  |  |  |  |  | sub customlogLocation { | 
| 732 | 6 |  |  | 6 | 0 | 10 | my($this) = shift; | 
| 733 | 6 |  |  |  |  | 9 | my($nickname) = shift; | 
| 734 | 6 |  |  |  |  | 18 | my($root) = serverroot($this); | 
| 735 | 6 | 50 |  |  |  | 16 | if (customlogDefined($this, $nickname)) { | 
| 736 | 6 |  |  |  |  | 9 | return ${ ${$this->{'customlog'}}{'location'} }{$nickname}; | 
|  | 6 |  |  |  |  | 7 |  | 
|  | 6 |  |  |  |  | 148 |  | 
| 737 |  |  |  |  |  |  | } else { | 
| 738 | 0 |  |  |  |  | 0 | return undef; | 
| 739 |  |  |  |  |  |  | } | 
| 740 |  |  |  |  |  |  | } | 
| 741 |  |  |  |  |  |  |  | 
| 742 |  |  |  |  |  |  | ####################################################################### | 
| 743 |  |  |  |  |  |  | # customlogExists($customlog_nickname); returns 1 or 0 | 
| 744 |  |  |  |  |  |  | =pod | 
| 745 |  |  |  |  |  |  |  | 
| 746 |  |  |  |  |  |  | =item * | 
| 747 |  |  |  |  |  |  |  | 
| 748 |  |  |  |  |  |  | C | 
| 749 |  |  |  |  |  |  |  | 
| 750 |  |  |  |  |  |  | if ($base->customlogExists($name)) { | 
| 751 |  |  |  |  |  |  | $customlog = $base->getCustomLog($name); | 
| 752 |  |  |  |  |  |  | } | 
| 753 |  |  |  |  |  |  |  | 
| 754 |  |  |  |  |  |  | Returns C<1> if the custom log I<$name> (e.g., B, B) | 
| 755 |  |  |  |  |  |  | is defined in the I<$httpd_conf> file B the log file exists, | 
| 756 |  |  |  |  |  |  | or C<0> otherwise. | 
| 757 |  |  |  |  |  |  |  | 
| 758 |  |  |  |  |  |  | You do B have to call this method usually because this is internally | 
| 759 |  |  |  |  |  |  | called by the C method. | 
| 760 |  |  |  |  |  |  |  | 
| 761 |  |  |  |  |  |  | =cut | 
| 762 |  |  |  |  |  |  |  | 
| 763 |  |  |  |  |  |  | sub customlogExists { | 
| 764 | 4 |  |  | 4 | 0 | 7 | my($this) = shift; | 
| 765 | 4 |  |  |  |  | 8 | my($nickname) = shift; | 
| 766 | 4 |  |  |  |  | 6 | my($switch) = 0; | 
| 767 | 4 | 50 |  |  |  | 12 | $switch++ if -e customlogLocation($this, $nickname); | 
| 768 | 4 |  |  |  |  | 20 | return $switch; | 
| 769 |  |  |  |  |  |  | } | 
| 770 |  |  |  |  |  |  |  | 
| 771 |  |  |  |  |  |  | ####################################################################### | 
| 772 |  |  |  |  |  |  | # customlogFormat($customlog_nickname); returns the format | 
| 773 |  |  |  |  |  |  | =pod | 
| 774 |  |  |  |  |  |  |  | 
| 775 |  |  |  |  |  |  | =item * | 
| 776 |  |  |  |  |  |  |  | 
| 777 |  |  |  |  |  |  | C | 
| 778 |  |  |  |  |  |  |  | 
| 779 |  |  |  |  |  |  | print $base->customlogFormat($name), "\n"; | 
| 780 |  |  |  |  |  |  |  | 
| 781 |  |  |  |  |  |  | Returns a scalar containing the string of the "LogFormat" for the | 
| 782 |  |  |  |  |  |  | custom log I<$name>, as specified in I<$httpd_conf>. This method | 
| 783 |  |  |  |  |  |  | is meant to be used internally, as well as for debugging purpose. | 
| 784 |  |  |  |  |  |  |  | 
| 785 |  |  |  |  |  |  | =cut | 
| 786 |  |  |  |  |  |  |  | 
| 787 |  |  |  |  |  |  | sub customlogFormat { | 
| 788 | 2 |  |  | 2 | 0 | 5 | my($this) = shift; | 
| 789 | 2 |  |  |  |  | 4 | my($nickname) = shift; | 
| 790 | 2 | 50 |  |  |  | 6 | if (customlogExists($this, $nickname)) { | 
| 791 | 2 |  |  |  |  | 3 | return ${ ${$this->{'customlog'}}{'format'} }{$nickname}; | 
|  | 2 |  |  |  |  | 13 |  | 
|  | 2 |  |  |  |  | 11 |  | 
| 792 |  |  |  |  |  |  | } else { | 
| 793 | 0 |  |  |  |  | 0 | return undef; | 
| 794 |  |  |  |  |  |  | } | 
| 795 |  |  |  |  |  |  | } | 
| 796 |  |  |  |  |  |  |  | 
| 797 |  |  |  |  |  |  | ####################################################################### | 
| 798 |  |  |  |  |  |  | # getTransferLog(); returns a blessed ref object for TransferLog | 
| 799 |  |  |  |  |  |  | =pod | 
| 800 |  |  |  |  |  |  |  | 
| 801 |  |  |  |  |  |  | =item * | 
| 802 |  |  |  |  |  |  |  | 
| 803 |  |  |  |  |  |  | C | 
| 804 |  |  |  |  |  |  |  | 
| 805 |  |  |  |  |  |  | $transferlog = $base->getTransferLog(); | 
| 806 |  |  |  |  |  |  |  | 
| 807 |  |  |  |  |  |  | Returns an object through which to access the information | 
| 808 |  |  |  |  |  |  | parsed from the F file. See the L<"LOG OBJECT METHODS"> below | 
| 809 |  |  |  |  |  |  | for methods to access the log information. | 
| 810 |  |  |  |  |  |  |  | 
| 811 |  |  |  |  |  |  | =cut | 
| 812 |  |  |  |  |  |  |  | 
| 813 |  |  |  |  |  |  | sub getTransferLog { | 
| 814 | 2 |  |  | 2 | 0 | 320 | my($this) = shift; | 
| 815 | 2 |  |  |  |  | 11 | my($METHOD) = "Apache::ParseLog::getTransferLog"; | 
| 816 | 2 |  |  |  |  | 7 | my($logfile) = $this->{'transferlog'}; | 
| 817 | 2 | 50 |  |  |  | 111 | croak "$METHOD: $logfile does not exist. Exiting " unless -e $logfile; | 
| 818 | 2 |  |  |  |  | 15 | my($FORMAT) = '(\\S+)\\s(\\S+)\\s(\\S+)\\s\\[(\\d{2}/\\w+/\\d{4}\\:\\d{2}\\:\\d{2}\\:\\d{2}\\s+.+?)\\]\\s\\"(\\w+\\s\\S+\\s\\w+\\/\\d+\\.\\d+)\\"\\s(\\d+)\\s(\\d+|-)'; | 
| 819 | 2 |  |  |  |  | 11 | my(@elements) = qw/HOST LOGIN USER DATETIME REQUEST LSTATUS BYTE/; | 
| 820 | 2 |  |  |  |  | 38 | return scanLog($this, $logfile, $FORMAT, @elements); | 
| 821 |  |  |  |  |  |  | } | 
| 822 |  |  |  |  |  |  |  | 
| 823 |  |  |  |  |  |  | ####################################################################### | 
| 824 |  |  |  |  |  |  | # getRefererLog(); returns a blessed ref object for RefererLog | 
| 825 |  |  |  |  |  |  | =pod | 
| 826 |  |  |  |  |  |  |  | 
| 827 |  |  |  |  |  |  | =item * | 
| 828 |  |  |  |  |  |  |  | 
| 829 |  |  |  |  |  |  | C | 
| 830 |  |  |  |  |  |  |  | 
| 831 |  |  |  |  |  |  | $refererlog = $base->getRefererLog(); | 
| 832 |  |  |  |  |  |  |  | 
| 833 |  |  |  |  |  |  | Returns an object through which to access the information | 
| 834 |  |  |  |  |  |  | parsed from the F file. See the L<"LOG OBJECT METHODS"> below | 
| 835 |  |  |  |  |  |  | for methods to access the log information. | 
| 836 |  |  |  |  |  |  |  | 
| 837 |  |  |  |  |  |  | =cut | 
| 838 |  |  |  |  |  |  |  | 
| 839 |  |  |  |  |  |  | sub getRefererLog { | 
| 840 | 1 |  |  | 1 | 0 | 170 | my($this) = shift; | 
| 841 | 1 |  |  |  |  | 6 | my($METHOD) = "Apache::ParseLog::getRefererLog"; | 
| 842 | 1 |  |  |  |  | 3 | my($logfile) = $this->{'refererlog'}; | 
| 843 | 1 | 50 |  |  |  | 31 | croak "$METHOD: $logfile does not exist. Exiting " unless -e $logfile; | 
| 844 | 1 |  |  |  |  | 5 | my($FORMAT) = '(\\S+)\\s\\-\\>\\s(\\S+)'; | 
| 845 | 1 |  |  |  |  | 9 | my(@elements) = qw/REFERER URL/; | 
| 846 | 1 |  |  |  |  | 20 | return scanLog($this, $logfile, $FORMAT, @elements); | 
| 847 |  |  |  |  |  |  | } | 
| 848 |  |  |  |  |  |  |  | 
| 849 |  |  |  |  |  |  | ####################################################################### | 
| 850 |  |  |  |  |  |  | # getAgentLog(); returns a blessed ref object for AgentLog | 
| 851 |  |  |  |  |  |  | =pod | 
| 852 |  |  |  |  |  |  |  | 
| 853 |  |  |  |  |  |  | =item * | 
| 854 |  |  |  |  |  |  |  | 
| 855 |  |  |  |  |  |  | C | 
| 856 |  |  |  |  |  |  |  | 
| 857 |  |  |  |  |  |  | $agentlog = $base->getAgentLog(); | 
| 858 |  |  |  |  |  |  |  | 
| 859 |  |  |  |  |  |  | This method returns an object through which to access the information | 
| 860 |  |  |  |  |  |  | parsed from the F file. See the L<"LOG OBJECT METHODS"> below | 
| 861 |  |  |  |  |  |  | for methods to access the log information. | 
| 862 |  |  |  |  |  |  |  | 
| 863 |  |  |  |  |  |  | =cut | 
| 864 |  |  |  |  |  |  |  | 
| 865 |  |  |  |  |  |  | sub getAgentLog { | 
| 866 | 1 |  |  | 1 | 0 | 208 | my($this) = shift; | 
| 867 | 1 |  |  |  |  | 6 | my($METHOD) = "Apache::ParseLog::getAgentLog"; | 
| 868 | 1 |  |  |  |  | 3 | my($logfile) = $this->{'agentlog'}; | 
| 869 | 1 | 50 |  |  |  | 41 | croak "$METHOD: $logfile does not exist. Exiting " unless -e $logfile; | 
| 870 | 1 |  |  |  |  | 3 | my($FORMAT) = '(.+)'; | 
| 871 | 1 |  |  |  |  | 6 | my(@elements) = qw/UAGENT/; | 
| 872 | 1 |  |  |  |  | 15 | return scanLog($this, $logfile, $FORMAT, @elements); | 
| 873 |  |  |  |  |  |  | } | 
| 874 |  |  |  |  |  |  |  | 
| 875 |  |  |  |  |  |  | ####################################################################### | 
| 876 |  |  |  |  |  |  | # getErrorLog(); returns a blessed ref object for ErrorLog | 
| 877 |  |  |  |  |  |  | =pod | 
| 878 |  |  |  |  |  |  |  | 
| 879 |  |  |  |  |  |  | =item * | 
| 880 |  |  |  |  |  |  |  | 
| 881 |  |  |  |  |  |  | C | 
| 882 |  |  |  |  |  |  |  | 
| 883 |  |  |  |  |  |  | $errorlog = $base->getErrorLog(); | 
| 884 |  |  |  |  |  |  |  | 
| 885 |  |  |  |  |  |  | This method returns an object through which to access the information | 
| 886 |  |  |  |  |  |  | parsed from the F file. See the L<"LOG OBJECT METHODS"> below | 
| 887 |  |  |  |  |  |  | for methods to access the log information. | 
| 888 |  |  |  |  |  |  |  | 
| 889 |  |  |  |  |  |  | =cut | 
| 890 |  |  |  |  |  |  |  | 
| 891 |  |  |  |  |  |  | sub getErrorLog { | 
| 892 | 1 |  |  | 1 | 0 | 192 | my($this) = shift; | 
| 893 | 1 |  |  |  |  | 5 | my($METHOD) = "Apache::ParseLog::getErrorLog"; | 
| 894 | 1 |  |  |  |  | 3 | my($logfile) = $this->{'errorlog'}; | 
| 895 | 1 | 50 |  |  |  | 28 | croak "$METHOD: $logfile does not exist. Exiting " unless -e $logfile; | 
| 896 | 1 |  |  |  |  | 6 | my($FORMAT) = '\\[(?:\\S+)\\s+(\\S+)\\s+(\\d+)\\s+(\\S+)\\s+(\\d{4})\\]\\s+(\\[(\\w+)\\])?'; | 
| 897 | 1 |  |  |  |  | 41 | my($regex) = qr/$FORMAT/; | 
| 898 | 1 |  |  |  |  | 2 | my($line, %count,  %allbydate, %allbytime, %allbydatetime, %allmessage, %errorbydate, %errorbytime, %errorbydatetime, %errormessage, %noticebydate, %noticebytime, %noticebydatetime, %noticemessage, %warnbydate, %warnbytime, %warnbydatetime, %warnmessage); | 
| 899 | 1 |  |  |  |  | 4 | my($fh) = openFile($logfile); | 
| 900 | 1 |  |  |  |  | 29 | while (defined($line = <$fh>)) { | 
| 901 | 68 |  |  |  |  | 77 | chomp($line); | 
| 902 | 68 | 100 |  |  |  | 257 | if ($line =~ m/^\[/) { | 
| 903 | 56 |  |  |  |  | 345 | $line =~ m#$regex#; | 
| 904 | 56 |  |  |  |  | 120 | my($m) = $M2N{$1}; | 
| 905 | 56 |  |  |  |  | 75 | my($d) = $2; | 
| 906 | 56 |  |  |  |  | 87 | my($time) = $3; | 
| 907 | 56 |  |  |  |  | 79 | my($y) = $4; | 
| 908 | 56 |  |  |  |  | 64 | my($keyword) = $6; | 
| 909 | 56 | 100 |  |  |  | 155 | $d = "0" . $d if $d =~ m/^\d$/; | 
| 910 | 56 |  |  |  |  | 104 | my($date) = "$m/$d/$y"; | 
| 911 | 56 |  |  |  |  | 175 | $time =~ s/:.+$//; | 
| 912 | 56 |  |  |  |  | 92 | my($datetime) = "$date-$time"; | 
| 913 | 56 |  |  |  |  | 318 | $line =~ s/^.+\]\s+//; | 
| 914 | 56 | 100 |  |  |  | 121 | if ($keyword eq "error") { | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 915 | 44 |  |  |  |  | 58 | $count{'error'}++; | 
| 916 | 44 |  |  |  |  | 56 | $errorbydate{$date}++; | 
| 917 | 44 |  |  |  |  | 50 | $errorbytime{$time}++; | 
| 918 | 44 |  |  |  |  | 57 | $errorbydatetime{$datetime}++; | 
| 919 | 44 |  |  |  |  | 88 | $errormessage{$line}++; | 
| 920 |  |  |  |  |  |  | } elsif ($keyword eq "notice") { | 
| 921 | 3 |  |  |  |  | 8 | $count{'notice'}++; | 
| 922 | 3 |  |  |  |  | 8 | $noticebydate{$date}++; | 
| 923 | 3 |  |  |  |  | 5 | $noticebytime{$time}++; | 
| 924 | 3 |  |  |  |  | 5 | $noticebydatetime{$datetime}++; | 
| 925 | 3 |  |  |  |  | 9 | $noticemessage{$line}++; | 
| 926 |  |  |  |  |  |  | } elsif ($keyword eq "warn") { | 
| 927 | 9 |  |  |  |  | 12 | $count{'warn'}++; | 
| 928 | 9 |  |  |  |  | 16 | $warnbydate{$date}++; | 
| 929 | 9 |  |  |  |  | 12 | $warnbytime{$time}++; | 
| 930 | 9 |  |  |  |  | 12 | $warnbydatetime{$datetime}++; | 
| 931 | 9 |  |  |  |  | 21 | $warnmessage{$line}++; | 
| 932 |  |  |  |  |  |  | } | 
| 933 | 56 |  |  |  |  | 61 | $allbydate{$date}++; | 
| 934 | 56 |  |  |  |  | 489 | $allbytime{$time}++; | 
| 935 | 56 |  |  |  |  | 62 | $allbydatetime{$datetime}++; | 
| 936 | 56 | 50 |  |  |  | 173 | $allmessage{$line}++ if $line; | 
| 937 | 56 |  |  |  |  | 84 | $count{'dated'}++; | 
| 938 |  |  |  |  |  |  | } else { | 
| 939 | 12 |  |  |  |  | 13 | $count{'nodate'}++; | 
| 940 | 12 | 50 |  |  |  | 34 | $allmessage{$line}++ if $line; | 
| 941 |  |  |  |  |  |  | } | 
| 942 | 68 |  |  |  |  | 346 | $count{'Total'}++; | 
| 943 |  |  |  |  |  |  | } | 
| 944 | 1 |  |  |  |  | 12 | close($fh); | 
| 945 | 1 |  |  |  |  | 10 | my(@methods) = qw/count allbydate allbytime allbydatetime allmessage errorbydate errorbytime errorbydatetime errormessage noticebydate noticebytime noticebydatetime noticemessage warnbydate warnbytime warnbydatetime warnmessage/; | 
| 946 | 1 |  |  |  |  | 140 | return bless { | 
| 947 |  |  |  |  |  |  | 'allbydate'             => { %allbydate }, | 
| 948 |  |  |  |  |  |  | 'allbytime'             => { %allbytime }, | 
| 949 |  |  |  |  |  |  | 'allbydatetime'         => { %allbydatetime }, | 
| 950 |  |  |  |  |  |  | 'allmessage'            => { %allmessage }, | 
| 951 |  |  |  |  |  |  | 'errorbydate'           => { %errorbydate }, | 
| 952 |  |  |  |  |  |  | 'errorbytime'           => { %errorbytime }, | 
| 953 |  |  |  |  |  |  | 'errorbydatetime'       => { %errorbydatetime }, | 
| 954 |  |  |  |  |  |  | 'errormessage'          => { %errormessage }, | 
| 955 |  |  |  |  |  |  | 'noticebydate'          => { %noticebydate }, | 
| 956 |  |  |  |  |  |  | 'noticebytime'          => { %noticebytime }, | 
| 957 |  |  |  |  |  |  | 'noticebydatetime'      => { %noticebydatetime }, | 
| 958 |  |  |  |  |  |  | 'noticemessage'         => { %noticemessage }, | 
| 959 |  |  |  |  |  |  | 'warnbydate'            => { %warnbydate }, | 
| 960 |  |  |  |  |  |  | 'warnbytime'            => { %warnbytime }, | 
| 961 |  |  |  |  |  |  | 'warnbydatetime'        => { %warnbydatetime }, | 
| 962 |  |  |  |  |  |  | 'warnmessage'           => { %warnmessage }, | 
| 963 |  |  |  |  |  |  | 'count'                 => { %count }, | 
| 964 |  |  |  |  |  |  | 'methods'               => [ @methods ], | 
| 965 |  |  |  |  |  |  | }; | 
| 966 |  |  |  |  |  |  | } | 
| 967 |  |  |  |  |  |  |  | 
| 968 |  |  |  |  |  |  | ####################################################################### | 
| 969 |  |  |  |  |  |  | # getCustomLog($nickname); returns $customlog object | 
| 970 |  |  |  |  |  |  | =pod | 
| 971 |  |  |  |  |  |  |  | 
| 972 |  |  |  |  |  |  | =item * | 
| 973 |  |  |  |  |  |  |  | 
| 974 |  |  |  |  |  |  | C | 
| 975 |  |  |  |  |  |  |  | 
| 976 |  |  |  |  |  |  | $customlog = $base->getCustomLog($name); | 
| 977 |  |  |  |  |  |  |  | 
| 978 |  |  |  |  |  |  | This method returns an object through which to access the information | 
| 979 |  |  |  |  |  |  | parsed from the F file I<$name>. See the L<"LOG OBJECT METHODS"> | 
| 980 |  |  |  |  |  |  | below for methods for methods to access the log information. | 
| 981 |  |  |  |  |  |  |  | 
| 982 |  |  |  |  |  |  | =back | 
| 983 |  |  |  |  |  |  |  | 
| 984 |  |  |  |  |  |  | =cut | 
| 985 |  |  |  |  |  |  |  | 
| 986 |  |  |  |  |  |  | sub getCustomLog { | 
| 987 | 2 |  |  | 2 | 0 | 372 | my($this) = shift; | 
| 988 | 2 |  |  |  |  | 8 | my($nickname) = shift; | 
| 989 | 2 |  |  |  |  | 8 | my($METHOD) = "Apache::ParseLog::getCustomLog"; | 
| 990 | 2 | 50 |  |  |  | 12 | croak "$METHOD: $nickname does not exist, Exiting " unless customlogExists($this, $nickname); | 
| 991 | 2 |  |  |  |  | 5 | my($logfile) = customlogLocation($this, $nickname); | 
| 992 | 2 | 50 |  |  |  | 46 | croak "$METHOD: $logfile does not exist. Exiting " unless -e $logfile; | 
| 993 |  |  |  |  |  |  | # Variables preparation | 
| 994 | 2 |  |  |  |  | 5 | my($host_rx) = '(\\S+)';            # %h (host, visitor IP/hostname) | 
| 995 | 2 |  |  |  |  | 4 | my($log_rx) = '(\\S+)';             # %l (login, login name) | 
| 996 | 2 |  |  |  |  | 4 | my($user_rx) = '(\\S+)';            # %u (user, user name) | 
| 997 | 2 |  |  |  |  | 6 | my($time_rx) = '\\[(\\d{2}/\\w+/\\d{4}\\:\\d{2}\\:\\d{2}\\:\\d{2}\\s+.+?)\\]';                                     # %t (datetime, date/time) | 
| 998 | 2 |  |  |  |  | 3 | my($req_rx) = '(\\w+\\s\\S+\\s\\w+\\/\\d+\\.\\d+)'; | 
| 999 |  |  |  |  |  |  | # %r (request, method, file, proto) | 
| 1000 | 2 |  |  |  |  | 6 | my($ost_rx) = '(\\d+)';             # %s (ostatus, original status) | 
| 1001 | 2 |  |  |  |  | 5 | my($lst_rx) = '(\\d+)';             # %>s (lstatus, last status) | 
| 1002 | 2 |  |  |  |  | 3 | my($byte_rx) = '(\\d+|-)';          # %b (byte, bytes) | 
| 1003 | 2 |  |  |  |  | 6 | my($file_rx) = '(\\S+)';            # %f (filename, filename) | 
| 1004 | 2 |  |  |  |  | 9 | my($addr_rx) = '(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})'; | 
| 1005 |  |  |  |  |  |  | # %a (addr, IP) | 
| 1006 | 2 |  |  |  |  | 4 | my($port_rx) = '(\\d+)';            # %p (port, port) | 
| 1007 | 2 |  |  |  |  | 3 | my($proc_rx) = '(\\d+)';            # %p (proc, proc ID) | 
| 1008 | 2 |  |  |  |  | 3 | my($sec_rx) = '(\\d+)';             # %T (sec, time in sec) | 
| 1009 | 2 |  |  |  |  | 3 | my($url_rx) = '(\\S+)';             # %U (url, URL) | 
| 1010 | 2 |  |  |  |  | 5 | my($hname_rx) = '(\\S+)';           # %v (hostname, hostname) | 
| 1011 | 2 |  |  |  |  | 2 | my($referer_rx) = '(\\S+)';         # %{Referer}i (referer, referer) | 
| 1012 | 2 |  |  |  |  | 3 | my($uagent_rx) = '(.+?)';           # %{User-agent}i (uagent, browser) | 
| 1013 | 2 |  |  |  |  | 7 | my($space) = '\\s';                 # white space | 
| 1014 | 2 |  |  |  |  | 8 | my($FORMAT) = customlogFormat($this, $nickname); | 
| 1015 | 2 |  |  |  |  | 8 | my($temp) = $FORMAT . " "; # add the last space for the $temp regex below | 
| 1016 | 2 |  |  |  |  | 4 | my(@regex, @elements); | 
| 1017 |  |  |  |  |  |  | # Create the pre-compiled regex sting dynamically here | 
| 1018 | 2 |  |  |  |  | 8 | while ((length($temp)) > 0) { | 
| 1019 | 20 |  |  |  |  | 115 | $temp =~ s/^(\\?\")?(.+?)(\\?\")?\s+//; | 
| 1020 | 20 |  |  |  |  | 46 | my($match) = $2; | 
| 1021 | 20 | 100 |  |  |  | 1351 | if ($2 eq '%h') { | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 1022 | 1 |  |  |  |  | 3 | push(@regex, $host_rx);    push(@elements, 'HOST'); | 
|  | 1 |  |  |  |  | 2 |  | 
| 1023 |  |  |  |  |  |  | } elsif ($2 eq '%l') { | 
| 1024 | 1 |  |  |  |  | 3 | push(@regex, $log_rx);     push(@elements, 'LOGIN'); | 
|  | 1 |  |  |  |  | 3 |  | 
| 1025 |  |  |  |  |  |  | } elsif ($2 eq '%u') { | 
| 1026 | 1 |  |  |  |  | 3 | push(@regex, $user_rx);    push(@elements, 'USER'); | 
|  | 1 |  |  |  |  | 2 |  | 
| 1027 |  |  |  |  |  |  | } elsif ($2 eq '%t') { | 
| 1028 | 2 |  |  |  |  | 5 | push(@regex, $time_rx);    push(@elements, 'DATETIME'); | 
|  | 2 |  |  |  |  | 3 |  | 
| 1029 |  |  |  |  |  |  | } elsif ($2 eq '%r') { | 
| 1030 | 1 |  |  |  |  | 3 | push(@regex, $req_rx);     push(@elements, 'REQUEST'); | 
|  | 1 |  |  |  |  | 2 |  | 
| 1031 |  |  |  |  |  |  | } elsif ($2 eq '%s') { | 
| 1032 | 1 |  |  |  |  | 3 | push(@regex, $ost_rx);     push(@elements, 'OSTATUS'); | 
|  | 1 |  |  |  |  | 2 |  | 
| 1033 |  |  |  |  |  |  | } elsif ($2 eq '%>s') { | 
| 1034 | 1 |  |  |  |  | 4 | push(@regex, $lst_rx);     push(@elements, 'LSTATUS'); | 
|  | 1 |  |  |  |  | 3 |  | 
| 1035 |  |  |  |  |  |  | } elsif ($2 eq '%b') { | 
| 1036 | 1 |  |  |  |  | 10 | push(@regex, $byte_rx);    push(@elements, 'BYTE'); | 
|  | 1 |  |  |  |  | 2 |  | 
| 1037 |  |  |  |  |  |  | } elsif ($2 eq '%f') { | 
| 1038 | 1 |  |  |  |  | 2 | push(@regex, $file_rx);    push(@elements, 'FILENAME'); | 
|  | 1 |  |  |  |  | 2 |  | 
| 1039 |  |  |  |  |  |  | } elsif ($2 eq '%a') { | 
| 1040 | 1 |  |  |  |  | 2 | push(@regex, $addr_rx);    push(@elements, 'ADDR'); | 
|  | 1 |  |  |  |  | 3 |  | 
| 1041 |  |  |  |  |  |  | } elsif ($2 eq '%p') { | 
| 1042 | 1 |  |  |  |  | 3 | push(@regex, $port_rx);    push(@elements, 'PORT'); | 
|  | 1 |  |  |  |  | 2 |  | 
| 1043 |  |  |  |  |  |  | } elsif ($2 eq '%P') { | 
| 1044 | 1 |  |  |  |  | 3 | push(@regex, $proc_rx);    push(@elements, 'PROC'); | 
|  | 1 |  |  |  |  | 2 |  | 
| 1045 |  |  |  |  |  |  | } elsif ($2 eq '%T') { | 
| 1046 | 1 |  |  |  |  | 3 | push(@regex, $sec_rx);     push(@elements, 'SEC'); | 
|  | 1 |  |  |  |  | 6 |  | 
| 1047 |  |  |  |  |  |  | } elsif ($2 eq '%U') { | 
| 1048 | 2 |  |  |  |  | 4 | push(@regex, $url_rx);     push(@elements, 'URL'); | 
|  | 2 |  |  |  |  | 5 |  | 
| 1049 |  |  |  |  |  |  | } elsif ($2 eq '%v') { | 
| 1050 | 1 |  |  |  |  | 4 | push(@regex, $hname_rx);   push(@elements, 'HOSTNAME'); | 
|  | 1 |  |  |  |  | 2 |  | 
| 1051 |  |  |  |  |  |  | } elsif ($2 =~ /Referer/i) { | 
| 1052 | 1 |  |  |  |  | 3 | push(@regex, $referer_rx); push(@elements, 'REFERER'); | 
|  | 1 |  |  |  |  | 3 |  | 
| 1053 |  |  |  |  |  |  | } elsif ($2 =~ /User-agent/i) { | 
| 1054 | 1 |  |  |  |  | 3 | push(@regex, $uagent_rx);  push(@elements, 'UAGENT'); | 
|  | 1 |  |  |  |  | 2 |  | 
| 1055 |  |  |  |  |  |  | } else { | 
| 1056 | 1 |  |  |  |  | 3 | my($unknown) = $2; | 
| 1057 | 1 |  |  |  |  | 8 | $unknown =~ s|(\W)|\\$1|g; | 
| 1058 | 1 |  |  |  |  | 3 | push(@regex, $unknown); | 
| 1059 |  |  |  |  |  |  | } | 
| 1060 | 20 |  |  |  |  | 536 | $FORMAT =~ s/$match/$regex[$#regex]/; | 
| 1061 |  |  |  |  |  |  | } | 
| 1062 | 2 |  |  |  |  | 22 | $FORMAT =~ s/\s/$space/g; | 
| 1063 |  |  |  |  |  |  | # Parse the log finally | 
| 1064 | 2 |  |  |  |  | 12 | return scanLog($this, $logfile, $FORMAT, @elements); | 
| 1065 |  |  |  |  |  |  | } | 
| 1066 |  |  |  |  |  |  |  | 
| 1067 |  |  |  |  |  |  | ####################################################################### | 
| 1068 |  |  |  |  |  |  | # scanLog($path_to_logfile, $regex_format, @elments); | 
| 1069 |  |  |  |  |  |  | # returns a blessed object; private | 
| 1070 |  |  |  |  |  |  | sub scanLog { | 
| 1071 | 6 |  |  | 6 | 0 | 30 | my($this) = shift;    # package | 
| 1072 | 6 |  |  |  |  | 17 | my($logfile) = shift; # path to the log | 
| 1073 | 6 |  |  |  |  | 14 | my($FORMAT) = shift;   # regex | 
| 1074 | 6 |  |  |  |  | 30 | my(@elements) = @_;   # array containing what's in the regex | 
| 1075 |  |  |  |  |  |  | # create an array containing the uc name of placeholders | 
| 1076 | 6 |  |  |  |  | 16 | my($hostswitch) = 1;    # off with host defined | 
| 1077 | 6 |  |  |  |  | 13 | my($visitorswitch) = 0; # on with host defined | 
| 1078 | 6 |  |  |  |  | 36 | my($visitordone) = 0;   # on with visitor added to @methods | 
| 1079 | 6 |  |  |  |  | 15 | my($dtswitch) = 0;      # on with datetime defined | 
| 1080 | 6 |  |  |  |  | 11 | my($dtbyteswitch) = 0;  # on with datetime or byte defined | 
| 1081 | 6 |  |  |  |  | 14 | my($fileswitch) = 0;    # on with filename or request or url defined | 
| 1082 |  |  |  |  |  |  | my(@METHODS) = map { | 
| 1083 | 6 | 100 | 66 |  |  | 34 | if ((m"^HOST") && ($hostswitch)) { | 
|  | 36 | 100 | 100 |  |  | 1427 |  | 
|  |  | 100 | 100 |  |  |  |  | 
|  |  | 100 | 66 |  |  |  |  | 
|  |  | 100 | 66 |  |  |  |  | 
|  |  | 100 | 100 |  |  |  |  | 
|  |  | 100 | 66 |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 1084 | 4 |  |  |  |  | 10 | $hostswitch--; | 
| 1085 | 4 |  |  |  |  | 8 | $visitorswitch++; | 
| 1086 | 4 | 100 | 66 |  |  | 22 | if (($dtswitch) && (! $visitordone)) { | 
| 1087 | 1 |  |  |  |  | 4 | ($_, "TOPDOMAIN", "SECDOMAIN", "VISITORBYDATE", "VISITORBYTTME", "VISITORBYDATETIME") | 
| 1088 |  |  |  |  |  |  | } else { | 
| 1089 | 3 |  |  |  |  | 26 | ($_, "TOPDOMAIN", "SECDOMAIN") | 
| 1090 |  |  |  |  |  |  | } | 
| 1091 |  |  |  |  |  |  | } elsif (((m"DATETIME") || (m"BYTE")) && (! $dtbyteswitch)) { | 
| 1092 | 4 |  |  |  |  | 8 | $dtbyteswitch++; | 
| 1093 | 4 | 50 |  |  |  | 22 | if (m"DATETIME") { | 
| 1094 | 4 |  |  |  |  | 8 | $dtswitch++; | 
| 1095 | 4 | 100 |  |  |  | 12 | if ($visitorswitch) { | 
| 1096 | 3 |  |  |  |  | 7 | $visitorswitch = 0; | 
| 1097 | 3 |  |  |  |  | 5 | $visitordone++; | 
| 1098 | 3 |  |  |  |  | 37 | ("VISITORBYDATE", "VISITORBYTIME", "VISITORBYDATETIME", "HITBYDATE", "HITBYTIME", "HITBYDATETIME") | 
| 1099 |  |  |  |  |  |  | } else { | 
| 1100 | 1 |  |  |  |  | 5 | ("HITBYDATE", "HITBYTIME", "HITBYDATETIME") | 
| 1101 |  |  |  |  |  |  | } | 
| 1102 |  |  |  |  |  |  | } else { | 
| 1103 | 0 |  |  |  |  | 0 | $_ | 
| 1104 |  |  |  |  |  |  | } | 
| 1105 |  |  |  |  |  |  | } elsif (((m"DATETIME") || (m"BYTE")) && ($dtbyteswitch)) { | 
| 1106 | 3 | 50 |  |  |  | 12 | if (m"DATETIME") { | 
| 1107 | 0 |  |  |  |  | 0 | $dtswitch++; | 
| 1108 | 0 | 0 |  |  |  | 0 | if ($visitorswitch) { | 
| 1109 | 0 |  |  |  |  | 0 | $visitorswitch = 0; | 
| 1110 | 0 |  |  |  |  | 0 | $visitordone++; | 
| 1111 | 0 |  |  |  |  | 0 | ("VISITORBYDATE", "VISITORBYTIME", "VISITORBYDATETIME", "HITBYDATE", "HITBYTIME", "HITBYDATETIME", "BYTEBYDATE", "BYTEBYTIME", "BYTEBYDATETIME") | 
| 1112 |  |  |  |  |  |  | } else { | 
| 1113 | 0 |  |  |  |  | 0 | ("HITBYDATE", "HITBYTIME", "HITBYDATETIME", "BYTEBYDATE", "BYTEBYTIME", "BYTEBYDATETIME") | 
| 1114 |  |  |  |  |  |  | } | 
| 1115 |  |  |  |  |  |  | } else { | 
| 1116 | 3 |  |  |  |  | 27 | ($_, "BYTEBYDATE", "BYTEBYTIME", "BYTEBYDATETIME") | 
| 1117 |  |  |  |  |  |  | } | 
| 1118 |  |  |  |  |  |  | } elsif (m"REQUEST") { | 
| 1119 | 3 |  |  |  |  | 8 | $fileswitch++; | 
| 1120 | 3 |  |  |  |  | 30 | ("METHOD", "FILE", "QUERYSTRING", "PROTO") | 
| 1121 |  |  |  |  |  |  | } elsif ((m"FILENAME") || (m"URL")) { | 
| 1122 | 4 |  |  |  |  | 5 | $fileswitch++; | 
| 1123 | 4 |  |  |  |  | 12 | $_ | 
| 1124 |  |  |  |  |  |  | } elsif ((m"SEC") && ($fileswitch)) { | 
| 1125 | 1 |  |  |  |  | 3 | $_ | 
| 1126 |  |  |  |  |  |  | } elsif (m"UAGENT") { | 
| 1127 | 2 |  |  |  |  | 22 | ($_, "UAVERSION", "BROWSER", "PLATFORM", "BROWSERBYOS") | 
| 1128 |  |  |  |  |  |  | } elsif (m"REFERER") { | 
| 1129 | 2 |  |  |  |  | 6 | ($_, "REFERERDETAIL") | 
| 1130 |  |  |  |  |  |  | } else { | 
| 1131 | 13 |  |  |  |  | 77 | $_ | 
| 1132 |  |  |  |  |  |  | } | 
| 1133 |  |  |  |  |  |  | } @elements; | 
| 1134 | 6 |  |  |  |  | 33 | push(@METHODS, "HIT");  # the hit => { %hit } is always there | 
| 1135 | 6 |  |  |  |  | 14 | @METHODS = map { lc } @METHODS; | 
|  | 98 |  |  |  |  | 248 |  | 
| 1136 |  |  |  |  |  |  | ### reports placeholders | 
| 1137 | 6 |  |  |  |  | 32 | my(%host);               # hosts (visitors) | 
| 1138 |  |  |  |  |  |  | my(%topdomain);          # top domains | 
| 1139 | 0 |  |  |  |  | 0 | my(%secdomain);          # secondary domains | 
| 1140 | 0 |  |  |  |  | 0 | my(%login);              # logins | 
| 1141 | 0 |  |  |  |  | 0 | my(%user);               # users | 
| 1142 | 0 |  |  |  |  | 0 | my(%visitorbydate);      # unique visitors (hosts) by date | 
| 1143 | 0 |  |  |  |  | 0 | my(%visitorbytime);      # unique visitors by time | 
| 1144 | 0 |  |  |  |  | 0 | my(%visitorbydatetime);  # unique visitors by date/time | 
| 1145 | 0 |  |  |  |  | 0 | my(%hitbydate);          # hits by date | 
| 1146 | 0 |  |  |  |  | 0 | my(%hitbytime);          # hits by time | 
| 1147 | 0 |  |  |  |  | 0 | my(%hitbydatetime);      # hits by date/time | 
| 1148 | 0 |  |  |  |  | 0 | my(%method);             # methods (get, post, etc.) | 
| 1149 | 0 |  |  |  |  | 0 | my(%file);               # files | 
| 1150 | 0 |  |  |  |  | 0 | my(%querystring);        # Query String | 
| 1151 | 0 |  |  |  |  | 0 | my(%proto);              # protos (HTTP/1.0, etc.) | 
| 1152 | 0 |  |  |  |  | 0 | my(%ostatus);            # original status (..) | 
| 1153 | 0 |  |  |  |  | 0 | my(%lstatus);            # last status (use with %STATUS_BY_CODE) | 
| 1154 | 0 |  |  |  |  | 0 | my(%byte);               # Bytes transferred (* containts one key "total") | 
| 1155 | 0 |  |  |  |  | 0 | my(%bytebydate);         # bytes by date | 
| 1156 | 0 |  |  |  |  | 0 | my(%bytebytime);         # bytes by time | 
| 1157 | 0 |  |  |  |  | 0 | my(%bytebydatetime);     # bytes by date/time | 
| 1158 | 0 |  |  |  |  | 0 | my(%filename);           # filenames (= files) | 
| 1159 | 0 |  |  |  |  | 0 | my(%addr);               # IPs (=~ hosts) | 
| 1160 | 0 |  |  |  |  | 0 | my(%port);               # ports | 
| 1161 | 0 |  |  |  |  | 0 | my(%proc);               # procs | 
| 1162 | 0 |  |  |  |  | 0 | my(%sec);                # seconds (time in sec) | 
| 1163 | 0 |  |  |  |  | 0 | my(%url);                # URLs (=~ files) | 
| 1164 | 0 |  |  |  |  | 0 | my(%hostname);           # hostnames (=~ hosts) | 
| 1165 | 0 |  |  |  |  | 0 | my(%referer);            # referer (site only) | 
| 1166 | 0 |  |  |  |  | 0 | my(%refererdetail);      # referer (detail) | 
| 1167 | 0 |  |  |  |  | 0 | my(%uagent);             # agents | 
| 1168 | 0 |  |  |  |  | 0 | my(%uaversion);          # uagent w/ versions (Mozilla/4.04, Slurp/2.0) | 
| 1169 | 0 |  |  |  |  | 0 | my(%browser);            # browsers w/ version | 
| 1170 | 0 |  |  |  |  | 0 | my(%platform);           # platforms only | 
| 1171 | 0 |  |  |  |  | 0 | my(%browserbyos);        # browsers w/ platforms | 
| 1172 | 0 |  |  |  |  | 0 | my(%hit);                # Total number of hits (lines) | 
| 1173 |  |  |  |  |  |  | ### Routine | 
| 1174 | 6 | 100 | 66 |  |  | 46 | if ((scalar(@elements) == 1) && ($elements[0] eq "UAGENT")) { | 
| 1175 | 1 |  |  |  |  | 4 | $FORMAT =~ s#\?## | 
| 1176 |  |  |  |  |  |  | } | 
| 1177 | 6 |  |  |  |  | 325 | my($regex) = qr/$FORMAT/; | 
| 1178 | 6 |  |  |  |  | 13 | my($line); | 
| 1179 | 6 |  |  |  |  | 29 | my($fh) = openFile($logfile); | 
| 1180 | 6 |  |  |  |  | 223 | while (defined($line = <$fh>)) { | 
| 1181 | 241 |  |  |  |  | 320 | chomp($line); | 
| 1182 | 241 |  |  |  |  | 2629 | $line =~ m#$regex#; | 
| 1183 |  |  |  |  |  |  | # Scan each match | 
| 1184 | 241 |  |  |  |  | 5027 | for ($i = 0; $i < scalar(@elements); $i++) { | 
| 1185 | 1142 |  |  |  |  | 1447 | my($mi) = $i + 1;          # index for match; $1, $2,... | 
| 1186 | 1142 |  |  |  |  | 1320 | ${$elements[$i]} = ${$mi}; # assign the back ref | 
|  | 1142 |  |  |  |  | 5231 |  | 
|  | 1142 |  |  |  |  | 2739 |  | 
| 1187 |  |  |  |  |  |  | } | 
| 1188 | 241 |  |  |  |  | 304 | my($date, $time, $method, $file, $proto); | 
| 1189 |  |  |  |  |  |  | ### create reports ### | 
| 1190 |  |  |  |  |  |  | { # HOST RELATED BLOCK | 
| 1191 |  |  |  |  |  |  | # HOST | 
| 1192 | 241 | 100 |  |  |  | 250 | $host{$HOST}++ if $HOST; | 
|  | 241 |  |  |  |  | 508 |  | 
| 1193 |  |  |  |  |  |  | # HOSTNAME | 
| 1194 | 241 | 100 |  |  |  | 467 | $hostname{$HOSTNAME}++ if $HOSTNAME; | 
| 1195 | 241 | 100 |  |  |  | 459 | my($domain) = ($HOST ? $HOST : $HOSTNAME); | 
| 1196 |  |  |  |  |  |  | # (TOP|SEC)DOMAIN | 
| 1197 | 241 | 100 |  |  |  | 507 | if ($domain) { | 
| 1198 | 118 | 50 |  |  |  | 296 | if ($domain !~ /^\d{1,3}(?:\.\d{1,3}){3}$/) { | 
| 1199 | 118 | 50 |  |  |  | 535 | if ($domain =~ m/\.([A-Za-z0-9\-]+\.)(\w+)$/) { | 
| 1200 | 118 |  |  |  |  | 220 | my($secdomain) = $1; | 
| 1201 | 118 |  |  |  |  | 181 | my($topdomain) = $2; | 
| 1202 | 118 |  |  |  |  | 183 | $topdomain{$topdomain}++; | 
| 1203 | 118 |  |  |  |  | 157 | $secdomain = $secdomain . $topdomain; | 
| 1204 | 118 |  |  |  |  | 256 | $secdomain{$secdomain}++; | 
| 1205 |  |  |  |  |  |  | } else { | 
| 1206 | 0 |  |  |  |  | 0 | $topdomain{$domain}++; | 
| 1207 | 0 |  |  |  |  | 0 | $secdomain{$domain}++; | 
| 1208 |  |  |  |  |  |  | } | 
| 1209 |  |  |  |  |  |  | } else { | 
| 1210 | 0 |  |  |  |  | 0 | $topdomain{'unknown'}++; | 
| 1211 | 0 |  |  |  |  | 0 | $secdomain{'unknown'}++; | 
| 1212 |  |  |  |  |  |  | } | 
| 1213 |  |  |  |  |  |  | } | 
| 1214 |  |  |  |  |  |  | } | 
| 1215 |  |  |  |  |  |  | # LOGIN | 
| 1216 | 241 | 100 |  |  |  | 593 | $login{$LOGIN}++ if $LOGIN; | 
| 1217 |  |  |  |  |  |  | # USER | 
| 1218 | 241 | 100 |  |  |  | 490 | $user{$USER}++ if $USER; | 
| 1219 |  |  |  |  |  |  | # DATETIME | 
| 1220 | 241 | 100 |  |  |  | 449 | if ($DATETIME) { | 
| 1221 | 118 |  |  |  |  | 485 | $DATETIME =~ m#^(\d+)/(\w+)/(\d+)\:(\d{2})\:\d{2}\:\d{2}#; | 
| 1222 | 118 | 50 |  |  |  | 422 | my($d) = ($1 =~ /^\d$/ ? '0' . $1 : $1); | 
| 1223 | 118 |  |  |  |  | 247 | my($m) = $M2N{$2}; | 
| 1224 | 118 |  |  |  |  | 187 | my($y) = $3; | 
| 1225 | 118 |  |  |  |  | 246 | my($t) = $4; | 
| 1226 | 118 |  |  |  |  | 251 | my($date) = "$m/$d/$y"; | 
| 1227 | 118 |  |  |  |  | 191 | $hitbydate{$date}++; | 
| 1228 | 118 |  |  |  |  | 170 | $hitbytime{$t}++; | 
| 1229 | 118 |  |  |  |  | 199 | my($dt) = "$date-$t"; | 
| 1230 | 118 |  |  |  |  | 176 | $hitbydatetime{$dt}++; | 
| 1231 | 118 | 100 | 100 |  |  | 732 | if (($BYTE) && ($BYTE =~ m#^\d+$#)) { | 
| 1232 | 68 |  |  |  |  | 139 | $bytebydate{$date} += $BYTE; | 
| 1233 | 68 |  |  |  |  | 94 | $bytebytime{$t} += $BYTE; | 
| 1234 | 68 |  |  |  |  | 119 | $bytebydatetime{$dt} += $BYTE; | 
| 1235 |  |  |  |  |  |  | } | 
| 1236 | 118 |  |  |  |  | 140 | my($visitor); | 
| 1237 | 118 | 100 |  |  |  | 236 | if ($HOST) { $visitor = $HOST } | 
|  | 89 | 50 |  |  |  | 130 |  | 
|  |  | 0 |  |  |  |  |  | 
| 1238 | 29 |  |  |  |  | 41 | elsif ($HOSTNAME) { $visitor = $HOSTNAME } | 
| 1239 | 0 |  |  |  |  | 0 | elsif ($ADDR) { $visitor = $HOSTNAME } | 
| 1240 | 118 |  |  |  |  | 132 | ${$date}{$visitor}++; | 
|  | 118 |  |  |  |  | 347 |  | 
| 1241 | 118 |  |  |  |  | 155 | ${$t}{$visitor}++; | 
|  | 118 |  |  |  |  | 604 |  | 
| 1242 | 118 |  |  |  |  | 167 | ${$dt}{$visitor}++; | 
|  | 118 |  |  |  |  | 435 |  | 
| 1243 |  |  |  |  |  |  | } | 
| 1244 |  |  |  |  |  |  | # STATUS | 
| 1245 | 241 | 100 |  |  |  | 541 | if ($OSTATUS) { | 
| 1246 | 29 |  |  |  |  | 58 | my($key) = "$OSTATUS $STATUS_BY_CODE{$OSTATUS}"; | 
| 1247 | 29 |  |  |  |  | 40 | $ostatus{$key}++; | 
| 1248 |  |  |  |  |  |  | } | 
| 1249 | 241 | 100 |  |  |  | 446 | if ($LSTATUS) { | 
| 1250 | 89 |  |  |  |  | 271 | my($key) = "$LSTATUS $STATUS_BY_CODE{$LSTATUS}"; | 
| 1251 | 89 |  |  |  |  | 149 | $lstatus{$key}++; | 
| 1252 |  |  |  |  |  |  | } | 
| 1253 |  |  |  |  |  |  | # FILENAME | 
| 1254 | 241 | 100 |  |  |  | 500 | $filename{$FILENAME}++ if $FILENAME; | 
| 1255 |  |  |  |  |  |  | # ADDR | 
| 1256 | 241 | 100 |  |  |  | 423 | $addr{$ADDR}++ if $ADDR; | 
| 1257 |  |  |  |  |  |  | # PORT | 
| 1258 | 241 | 100 |  |  |  | 413 | $port{$PORT}++ if $PORT; | 
| 1259 |  |  |  |  |  |  | # PROC | 
| 1260 | 241 | 100 |  |  |  | 550 | $proc{$PROC}++ if $PROC; | 
| 1261 |  |  |  |  |  |  | { # BEGIN FILE RELATED BLOCK | 
| 1262 | 241 |  |  |  |  | 235 | my($FILE); | 
|  | 241 |  |  |  |  | 269 |  | 
| 1263 |  |  |  |  |  |  | # REQUEST | 
| 1264 | 241 | 100 |  |  |  | 1592 | if ($REQUEST) { | 
| 1265 | 89 |  |  |  |  | 325 | $REQUEST =~ m#^(\w+)\s(\S+)\s(\S+)$#; | 
| 1266 | 89 |  |  |  |  | 170 | my($method) = $1; | 
| 1267 | 89 |  |  |  |  | 146 | my($file) = $2; | 
| 1268 | 89 |  |  |  |  | 140 | my($proto) = $3; | 
| 1269 | 89 |  |  |  |  | 126 | $method{$method}++; | 
| 1270 | 89 | 50 |  |  |  | 226 | if ($file =~ m#\?(.+)$#) { | 
| 1271 | 0 |  |  |  |  | 0 | $querystring{$1}++;    # query string | 
| 1272 |  |  |  |  |  |  | } | 
| 1273 | 89 |  |  |  |  | 156 | $file =~ s#\?.+$##;        # trim query_string | 
| 1274 | 89 |  |  |  |  | 124 | $file =~ s#/\./#/#g;         # same-dir duplicates | 
| 1275 | 89 |  |  |  |  | 119 | $file =~ s#/\s+?/\.\./#/#g;  # same-upper-dir duplicates | 
| 1276 | 89 |  |  |  |  | 185 | $file{$file}++; | 
| 1277 | 89 |  |  |  |  | 127 | $proto{$proto}++; | 
| 1278 | 89 |  |  |  |  | 165 | $FILE = $file; | 
| 1279 |  |  |  |  |  |  | } | 
| 1280 |  |  |  |  |  |  | # URL | 
| 1281 | 241 | 100 |  |  |  | 478 | if ($URL) { | 
| 1282 | 88 |  |  |  |  | 181 | $url{$URL}++; | 
| 1283 | 88 |  |  |  |  | 119 | $FILE = $URL; | 
| 1284 |  |  |  |  |  |  | } | 
| 1285 |  |  |  |  |  |  | # FILE | 
| 1286 | 241 | 100 |  |  |  | 462 | $FILE = $FILENAME unless $FILE; | 
| 1287 |  |  |  |  |  |  | # SEC | 
| 1288 | 241 | 100 |  |  |  | 999 | SEC: if ($SEC) { | 
| 1289 | 8 | 50 |  |  |  | 14 | last SEC unless $FILE; | 
| 1290 | 8 | 50 |  |  |  | 17 | if (exists($sec{$FILE})) { | 
| 1291 | 0 | 0 |  |  |  | 0 | $sec{$FILE} = "$SEC" if $SEC > $sec{$FILE}; | 
| 1292 |  |  |  |  |  |  | } else { | 
| 1293 | 8 |  |  |  |  | 20 | $sec{$FILE} = "$SEC"; | 
| 1294 |  |  |  |  |  |  | } | 
| 1295 |  |  |  |  |  |  | } | 
| 1296 |  |  |  |  |  |  | # BYTE | 
| 1297 | 241 | 100 | 100 |  |  | 894 | if (($BYTE) && ($BYTE =~ m#^\d+$#)) { | 
| 1298 | 68 |  |  |  |  | 118 | $byte{'Total'} += $BYTE; | 
| 1299 | 68 | 50 |  |  |  | 136 | last unless $FILE; | 
| 1300 | 68 |  |  |  |  | 178 | $FILE =~ m#\.(\w+)$#; | 
| 1301 | 68 | 100 |  |  |  | 164 | if ($1) { | 
| 1302 | 48 |  |  |  |  | 82 | $byte{$1} += $BYTE; | 
| 1303 | 48 |  |  |  |  | 81 | $hit{$1}++; | 
| 1304 |  |  |  |  |  |  | } else { | 
| 1305 | 20 |  |  |  |  | 41 | $byte{'OtherTypes'} += $BYTE; | 
| 1306 | 20 |  |  |  |  | 37 | $hit{'OtherTypes'}++; | 
| 1307 |  |  |  |  |  |  | } | 
| 1308 |  |  |  |  |  |  | } | 
| 1309 |  |  |  |  |  |  | # REFERER | 
| 1310 | 241 | 100 |  |  |  | 583 | if ($REFERER) { | 
| 1311 | 59 |  |  |  |  | 56 | my($refered); | 
| 1312 | 59 | 50 |  |  |  | 95 | if ($URL) { $refered = $URL } | 
|  | 59 | 0 |  |  |  | 76 |  | 
|  |  | 0 |  |  |  |  |  | 
| 1313 | 0 |  |  |  |  | 0 | elsif ($FILE) { $refered = $FILE } | 
| 1314 | 0 |  |  |  |  | 0 | elsif ($FILENAME) { $refered = $FILENAME } | 
| 1315 | 59 | 50 |  |  |  | 151 | my($ref) = (($refered) ? "$REFERER -> $refered" : $REFERER); | 
| 1316 | 59 |  |  |  |  | 202 | $refererdetail{$ref}++; | 
| 1317 | 59 | 100 |  |  |  | 1372 | if ($REFERER =~ m#http://(\S+?)[/?]#) { $referer{$1}++ } | 
|  | 52 | 50 |  |  |  | 137 |  | 
| 1318 | 7 |  |  |  |  | 17 | elsif ($REFERER =~ m#^-$#) { $referer{'bookmark'}++ } | 
| 1319 | 0 |  |  |  |  | 0 | else { $referer{'unknown'}++ } | 
| 1320 |  |  |  |  |  |  | } | 
| 1321 |  |  |  |  |  |  | } # END FILE RELATED BLOCK | 
| 1322 |  |  |  |  |  |  | # UAGENT | 
| 1323 | 241 | 100 |  |  |  | 436 | if ($UAGENT) { | 
| 1324 | 120 |  |  |  |  | 246 | $uagent{$UAGENT}++; | 
| 1325 | 120 |  |  |  |  | 370 | $UAGENT =~ m#^(\S+)\s*(.+)?$#; | 
| 1326 | 120 |  |  |  |  | 211 | my($parser) = $1; | 
| 1327 | 120 |  |  |  |  | 172 | my($rest) = $2; | 
| 1328 | 120 | 50 |  |  |  | 247 | $uaversion{$parser}++ if $parser; | 
| 1329 | 120 |  |  |  |  | 112 | my($browser); | 
| 1330 | 120 | 100 | 100 |  |  | 1849 | if (($UAGENT =~ m/^Mozilla/) | 
|  |  | 50 | 33 |  |  |  |  | 
|  |  |  | 33 |  |  |  |  | 
| 1331 |  |  |  |  |  |  | && (($rest =~ m/(Webtv.+?)[;)]/) | 
| 1332 |  |  |  |  |  |  | || ($rest =~ m/(AOL.+?)[;)]/) | 
| 1333 |  |  |  |  |  |  | || ($rest =~ m/(MSN.+?)[;)]/) | 
| 1334 |  |  |  |  |  |  | || ($rest =~ m/(MSIE.+?)[;)]/))) { | 
| 1335 | 19 |  |  |  |  | 47 | $browser = $1; | 
| 1336 | 19 |  |  |  |  | 51 | $browser{$1}++; | 
| 1337 |  |  |  |  |  |  | } elsif (($UAGENT =~ m/Mozilla/) && ($rest =~ m/compatible\;\s+(.+?)[;)]/)) { | 
| 1338 | 0 |  |  |  |  | 0 | $browser = $1; | 
| 1339 | 0 |  |  |  |  | 0 | $browser{$1}++; | 
| 1340 |  |  |  |  |  |  | } else { | 
| 1341 | 101 |  |  |  |  | 120 | $browser = $parser; | 
| 1342 | 101 |  |  |  |  | 148 | $browser{$browser}++; | 
| 1343 |  |  |  |  |  |  | } | 
| 1344 | 120 |  |  |  |  | 173 | my($plat); | 
| 1345 | 120 | 100 |  |  |  | 526 | if ($rest =~ m/(Win.+?)[;)]/) { | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 1346 | 75 |  |  |  |  | 99 | $plat = $1; | 
| 1347 | 75 |  |  |  |  | 119 | $platform{$1}++; | 
| 1348 |  |  |  |  |  |  | } elsif ($rest =~ m/(Mac.+?)[;)]/) { | 
| 1349 | 9 |  |  |  |  | 13 | $plat = $1; | 
| 1350 | 9 |  |  |  |  | 13 | $platform{$1}++; | 
| 1351 |  |  |  |  |  |  | } elsif ($rest =~ m/X11\;\s+.+?\;\s+(.+?)[;)]/) { | 
| 1352 | 34 |  |  |  |  | 61 | $plat = $1; | 
| 1353 | 34 |  |  |  |  | 67 | $platform{$1}++; | 
| 1354 |  |  |  |  |  |  | } else { | 
| 1355 | 2 |  |  |  |  | 3 | $plat = $rest; | 
| 1356 | 2 |  |  |  |  | 23 | $plat =~ s#(?:\(|\)|\;)##g; | 
| 1357 | 2 |  |  |  |  | 6 | $platform{$plat}++; | 
| 1358 |  |  |  |  |  |  | } | 
| 1359 | 120 |  |  |  |  | 206 | my($bandp) = "$browser ($plat)"; | 
| 1360 | 120 |  |  |  |  | 246 | $browserbyos{$bandp}++; | 
| 1361 |  |  |  |  |  |  | } | 
| 1362 |  |  |  |  |  |  | # hit | 
| 1363 | 241 |  |  |  |  | 1286 | $hit{'Total'}++; | 
| 1364 |  |  |  |  |  |  | } | 
| 1365 | 6 |  |  |  |  | 124 | close($fh); | 
| 1366 |  |  |  |  |  |  | # Construct %visitorxxx hashes | 
| 1367 | 6 |  |  |  |  | 44 | %visitorbydate = map { $_ => scalar(keys %{$_}), } keys %hitbydate; | 
|  | 12 |  |  |  |  | 20 |  | 
|  | 12 |  |  |  |  | 58 |  | 
| 1368 | 6 |  |  |  |  | 27 | %visitorbytime = map { $_ => scalar(keys %{$_}), } keys %hitbytime; | 
|  | 14 |  |  |  |  | 20 |  | 
|  | 14 |  |  |  |  | 59 |  | 
| 1369 | 6 |  |  |  |  | 70 | %visitorbydatetime = map { $_ => scalar(keys %{$_}), } keys %hitbydatetime; | 
|  | 20 |  |  |  |  | 24 |  | 
|  | 20 |  |  |  |  | 76 |  | 
| 1370 | 6 |  |  |  |  | 1781 | return bless { | 
| 1371 |  |  |  |  |  |  | 'host'               => { %host }, | 
| 1372 |  |  |  |  |  |  | 'topdomain'          => { %topdomain }, | 
| 1373 |  |  |  |  |  |  | 'secdomain'          => { %secdomain }, | 
| 1374 |  |  |  |  |  |  | 'login'              => { %login }, | 
| 1375 |  |  |  |  |  |  | 'user'               => { %user }, | 
| 1376 |  |  |  |  |  |  | 'hitbydate'          => { %hitbydate }, | 
| 1377 |  |  |  |  |  |  | 'hitbytime'          => { %hitbytime }, | 
| 1378 |  |  |  |  |  |  | 'hitbydatetime'      => { %hitbydatetime }, | 
| 1379 |  |  |  |  |  |  | 'visitorbydate'      => { %visitorbydate }, | 
| 1380 |  |  |  |  |  |  | 'visitorbytime'      => { %visitorbytime }, | 
| 1381 |  |  |  |  |  |  | 'visitorbydatetime'  => { %visitorbydatetime }, | 
| 1382 |  |  |  |  |  |  | 'method'             => { %method }, | 
| 1383 |  |  |  |  |  |  | 'file'               => { %file }, | 
| 1384 |  |  |  |  |  |  | 'querystring'        => { %querystring }, | 
| 1385 |  |  |  |  |  |  | 'proto'              => { %proto }, | 
| 1386 |  |  |  |  |  |  | 'ostatus'            => { %ostatus }, | 
| 1387 |  |  |  |  |  |  | 'lstatus'            => { %lstatus }, | 
| 1388 |  |  |  |  |  |  | 'byte'               => { %byte }, | 
| 1389 |  |  |  |  |  |  | 'bytebydate'         => { %bytebydate }, | 
| 1390 |  |  |  |  |  |  | 'bytebytime'         => { %bytebytime }, | 
| 1391 |  |  |  |  |  |  | 'bytebydatetime'     => { %bytebydatetime }, | 
| 1392 |  |  |  |  |  |  | 'filename'           => { %filename }, | 
| 1393 |  |  |  |  |  |  | 'addr'               => { %addr }, | 
| 1394 |  |  |  |  |  |  | 'port'               => { %port }, | 
| 1395 |  |  |  |  |  |  | 'proc'               => { %proc }, | 
| 1396 |  |  |  |  |  |  | 'sec'                => { %sec }, | 
| 1397 |  |  |  |  |  |  | 'url'                => { %url }, | 
| 1398 |  |  |  |  |  |  | 'hostname'           => { %hostname }, | 
| 1399 |  |  |  |  |  |  | 'referer'            => { %referer }, | 
| 1400 |  |  |  |  |  |  | 'refererdetail'      => { %refererdetail }, | 
| 1401 |  |  |  |  |  |  | 'uagent'             => { %uagent }, | 
| 1402 |  |  |  |  |  |  | 'uaversion'          => { %uaversion }, | 
| 1403 |  |  |  |  |  |  | 'browser'            => { %browser }, | 
| 1404 |  |  |  |  |  |  | 'platform'           => { %platform }, | 
| 1405 |  |  |  |  |  |  | 'browserbyos'        => { %browserbyos }, | 
| 1406 |  |  |  |  |  |  | 'hit'                => { %hit }, | 
| 1407 |  |  |  |  |  |  | 'methods'            => [ @METHODS ], | 
| 1408 |  |  |  |  |  |  | }; | 
| 1409 |  |  |  |  |  |  | } | 
| 1410 |  |  |  |  |  |  |  | 
| 1411 |  |  |  |  |  |  | ####################################################################### | 
| 1412 |  |  |  |  |  |  | # LOG OBJECT METHODS | 
| 1413 |  |  |  |  |  |  | ####################################################################### | 
| 1414 |  |  |  |  |  |  | =pod | 
| 1415 |  |  |  |  |  |  |  | 
| 1416 |  |  |  |  |  |  | =head1 LOG OBJECT METHODS | 
| 1417 |  |  |  |  |  |  |  | 
| 1418 |  |  |  |  |  |  | This section describes the methods available for the log object created | 
| 1419 |  |  |  |  |  |  | by any of the following base object methods: B, | 
| 1420 |  |  |  |  |  |  | B, B, B, and | 
| 1421 |  |  |  |  |  |  | B. | 
| 1422 |  |  |  |  |  |  |  | 
| 1423 |  |  |  |  |  |  | This section is devided into six subsections, each of which describes | 
| 1424 |  |  |  |  |  |  | the available methods for a certain log object. | 
| 1425 |  |  |  |  |  |  |  | 
| 1426 |  |  |  |  |  |  | Note that all the methods for F, F, and F | 
| 1427 |  |  |  |  |  |  | can be used for the object created with C. | 
| 1428 |  |  |  |  |  |  |  | 
| 1429 |  |  |  |  |  |  | =cut | 
| 1430 |  |  |  |  |  |  |  | 
| 1431 |  |  |  |  |  |  | ####################################################################### | 
| 1432 |  |  |  |  |  |  | # TRANSFERLOG METHODS | 
| 1433 |  |  |  |  |  |  | =pod | 
| 1434 |  |  |  |  |  |  |  | 
| 1435 |  |  |  |  |  |  | =head2 TransferLog/CustomLog Methods | 
| 1436 |  |  |  |  |  |  |  | 
| 1437 |  |  |  |  |  |  | The following methods are available for the F object | 
| 1438 |  |  |  |  |  |  | (created by C method), as well as the F | 
| 1439 |  |  |  |  |  |  | object that logs appropriate arguments to the corresponding F. | 
| 1440 |  |  |  |  |  |  |  | 
| 1441 |  |  |  |  |  |  | =over 4 | 
| 1442 |  |  |  |  |  |  |  | 
| 1443 |  |  |  |  |  |  | =cut | 
| 1444 |  |  |  |  |  |  |  | 
| 1445 |  |  |  |  |  |  | ###################################################################### | 
| 1446 |  |  |  |  |  |  | # hit(); returns %hit | 
| 1447 |  |  |  |  |  |  | =pod | 
| 1448 |  |  |  |  |  |  |  | 
| 1449 |  |  |  |  |  |  | =item * | 
| 1450 |  |  |  |  |  |  |  | 
| 1451 |  |  |  |  |  |  | C | 
| 1452 |  |  |  |  |  |  |  | 
| 1453 |  |  |  |  |  |  | %hit = $logobject->hit(); | 
| 1454 |  |  |  |  |  |  |  | 
| 1455 |  |  |  |  |  |  | Returns a hash containing at least a key 'Total' with the total | 
| 1456 |  |  |  |  |  |  | hit count as its value, and the file extensions (i.e., html, | 
| 1457 |  |  |  |  |  |  | jpg, gif, cgi, pl, etc.) as keys with the hit count for each key as | 
| 1458 |  |  |  |  |  |  | values. | 
| 1459 |  |  |  |  |  |  |  | 
| 1460 |  |  |  |  |  |  | =cut | 
| 1461 |  |  |  |  |  |  |  | 
| 1462 |  |  |  |  |  |  | sub hit { | 
| 1463 | 1 |  |  | 1 | 0 | 369 | my($this) = shift; | 
| 1464 | 1 | 50 |  |  |  | 3 | return %{($this->{'hit'} || undef)}; | 
|  | 1 |  |  |  |  | 14 |  | 
| 1465 |  |  |  |  |  |  | } | 
| 1466 |  |  |  |  |  |  |  | 
| 1467 |  |  |  |  |  |  | ####################################################################### | 
| 1468 |  |  |  |  |  |  | # host(); returns %host | 
| 1469 |  |  |  |  |  |  | =pod | 
| 1470 |  |  |  |  |  |  |  | 
| 1471 |  |  |  |  |  |  | =item * | 
| 1472 |  |  |  |  |  |  |  | 
| 1473 |  |  |  |  |  |  | C | 
| 1474 |  |  |  |  |  |  |  | 
| 1475 |  |  |  |  |  |  | %host = $logobject->host(); | 
| 1476 |  |  |  |  |  |  |  | 
| 1477 |  |  |  |  |  |  | Returns a hash containing host names (or IPs if names are unresolved) | 
| 1478 |  |  |  |  |  |  | of the visitors as keys, and the hit count for each key as values. | 
| 1479 |  |  |  |  |  |  |  | 
| 1480 |  |  |  |  |  |  | =cut | 
| 1481 |  |  |  |  |  |  |  | 
| 1482 |  |  |  |  |  |  | sub host { | 
| 1483 | 1 |  |  | 1 | 0 | 201 | my($this) = shift; | 
| 1484 | 1 | 50 |  |  |  | 4 | my(%host) = %{($this->{'host'} || undef)}; | 
|  | 1 |  |  |  |  | 11 |  | 
| 1485 | 1 |  |  |  |  | 8 | return %host; | 
| 1486 |  |  |  |  |  |  | } | 
| 1487 |  |  |  |  |  |  |  | 
| 1488 |  |  |  |  |  |  | ####################################################################### | 
| 1489 |  |  |  |  |  |  | # topdomain(); returns %topdomain | 
| 1490 |  |  |  |  |  |  | =pod | 
| 1491 |  |  |  |  |  |  |  | 
| 1492 |  |  |  |  |  |  | =item * | 
| 1493 |  |  |  |  |  |  |  | 
| 1494 |  |  |  |  |  |  | C | 
| 1495 |  |  |  |  |  |  |  | 
| 1496 |  |  |  |  |  |  | %topdomain = $logobject->topdomain(); | 
| 1497 |  |  |  |  |  |  |  | 
| 1498 |  |  |  |  |  |  | Returns a hash containing topdomain names (com, net, etc.) of the | 
| 1499 |  |  |  |  |  |  | visitors as keys, and the hit count for each key as values. | 
| 1500 |  |  |  |  |  |  |  | 
| 1501 |  |  |  |  |  |  | Note that if the hostname is unresolved and remains as an IP address, | 
| 1502 |  |  |  |  |  |  | the visitor will not be counted toward the (and the next C) | 
| 1503 |  |  |  |  |  |  | returned value of this method. | 
| 1504 |  |  |  |  |  |  |  | 
| 1505 |  |  |  |  |  |  | =cut | 
| 1506 |  |  |  |  |  |  |  | 
| 1507 |  |  |  |  |  |  | sub topdomain { | 
| 1508 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1509 | 0 | 0 |  |  |  | 0 | return %{($this->{'topdomain'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1510 |  |  |  |  |  |  | } | 
| 1511 |  |  |  |  |  |  |  | 
| 1512 |  |  |  |  |  |  | ###################################################################### | 
| 1513 |  |  |  |  |  |  | # secdomain(); returns %secdomain | 
| 1514 |  |  |  |  |  |  | =pod | 
| 1515 |  |  |  |  |  |  |  | 
| 1516 |  |  |  |  |  |  | =item * | 
| 1517 |  |  |  |  |  |  |  | 
| 1518 |  |  |  |  |  |  | C | 
| 1519 |  |  |  |  |  |  |  | 
| 1520 |  |  |  |  |  |  | %secdomain = $logobject->secdomain(); | 
| 1521 |  |  |  |  |  |  |  | 
| 1522 |  |  |  |  |  |  | Returns a hash containing secondary domain names (xxx.com, yyy.net, | 
| 1523 |  |  |  |  |  |  | etc.) as keys, and the hit count for each key as values. | 
| 1524 |  |  |  |  |  |  |  | 
| 1525 |  |  |  |  |  |  | For the unresolved IPs, the same rule applies as the above C | 
| 1526 |  |  |  |  |  |  | method. | 
| 1527 |  |  |  |  |  |  |  | 
| 1528 |  |  |  |  |  |  | =cut | 
| 1529 |  |  |  |  |  |  |  | 
| 1530 |  |  |  |  |  |  | sub secdomain { | 
| 1531 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1532 | 0 | 0 |  |  |  | 0 | return %{($this->{'secdomain'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1533 |  |  |  |  |  |  | } | 
| 1534 |  |  |  |  |  |  |  | 
| 1535 |  |  |  |  |  |  | ###################################################################### | 
| 1536 |  |  |  |  |  |  | # login(); returns %login | 
| 1537 |  |  |  |  |  |  | =pod | 
| 1538 |  |  |  |  |  |  |  | 
| 1539 |  |  |  |  |  |  | =item * | 
| 1540 |  |  |  |  |  |  |  | 
| 1541 |  |  |  |  |  |  | C | 
| 1542 |  |  |  |  |  |  |  | 
| 1543 |  |  |  |  |  |  | %login = $logobject->login(); | 
| 1544 |  |  |  |  |  |  |  | 
| 1545 |  |  |  |  |  |  | Returns a hash containing login names (authenticated user logins) | 
| 1546 |  |  |  |  |  |  | of the visitors as keys, and the hit count for each key as values. | 
| 1547 |  |  |  |  |  |  |  | 
| 1548 |  |  |  |  |  |  | Log entries for non-authenticated files have a character "-" as the | 
| 1549 |  |  |  |  |  |  | login name. | 
| 1550 |  |  |  |  |  |  |  | 
| 1551 |  |  |  |  |  |  | =cut | 
| 1552 |  |  |  |  |  |  |  | 
| 1553 |  |  |  |  |  |  | sub login { | 
| 1554 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1555 | 0 | 0 |  |  |  | 0 | return %{($this->{'login'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1556 |  |  |  |  |  |  | } | 
| 1557 |  |  |  |  |  |  |  | 
| 1558 |  |  |  |  |  |  | ###################################################################### | 
| 1559 |  |  |  |  |  |  | # user(); returns %user | 
| 1560 |  |  |  |  |  |  | =pod | 
| 1561 |  |  |  |  |  |  |  | 
| 1562 |  |  |  |  |  |  | =item * | 
| 1563 |  |  |  |  |  |  |  | 
| 1564 |  |  |  |  |  |  | C | 
| 1565 |  |  |  |  |  |  |  | 
| 1566 |  |  |  |  |  |  | %user = $logobject->user(); | 
| 1567 |  |  |  |  |  |  |  | 
| 1568 |  |  |  |  |  |  | Returns a hash containing user names (for access-controlled directories, | 
| 1569 |  |  |  |  |  |  | refer to the access.conf file of the Apache server) of the visitors as | 
| 1570 |  |  |  |  |  |  | keys, and the hit count for each key as values. | 
| 1571 |  |  |  |  |  |  |  | 
| 1572 |  |  |  |  |  |  | Non-access-controlled log entries have a character "-" as the user name. | 
| 1573 |  |  |  |  |  |  |  | 
| 1574 |  |  |  |  |  |  | =cut | 
| 1575 |  |  |  |  |  |  |  | 
| 1576 |  |  |  |  |  |  | sub user { | 
| 1577 | 1 |  |  | 1 | 0 | 178 | my($this) = shift; | 
| 1578 | 1 | 50 |  |  |  | 3 | return %{($this->{'user'} || undef)}; | 
|  | 1 |  |  |  |  | 9 |  | 
| 1579 |  |  |  |  |  |  | } | 
| 1580 |  |  |  |  |  |  |  | 
| 1581 |  |  |  |  |  |  | ###################################################################### | 
| 1582 |  |  |  |  |  |  | # hitbydate(); returns %hitbydate | 
| 1583 |  |  |  |  |  |  | =pod | 
| 1584 |  |  |  |  |  |  |  | 
| 1585 |  |  |  |  |  |  | =item * | 
| 1586 |  |  |  |  |  |  |  | 
| 1587 |  |  |  |  |  |  | C | 
| 1588 |  |  |  |  |  |  |  | 
| 1589 |  |  |  |  |  |  | %hitbydate = $logobject->hitbydate(); | 
| 1590 |  |  |  |  |  |  |  | 
| 1591 |  |  |  |  |  |  | Returns a hash containing date (mm/dd/yyyy) when visitors visited the | 
| 1592 |  |  |  |  |  |  | particular file (html, jpg, etc.) as keys, and the hit count | 
| 1593 |  |  |  |  |  |  | for each key as values. | 
| 1594 |  |  |  |  |  |  |  | 
| 1595 |  |  |  |  |  |  | =cut | 
| 1596 |  |  |  |  |  |  |  | 
| 1597 |  |  |  |  |  |  | sub hitbydate { | 
| 1598 | 1 |  |  | 1 | 0 | 392 | my($this) = shift; | 
| 1599 | 1 | 50 |  |  |  | 3 | return %{($this->{'hitbydate'} || undef)}; | 
|  | 1 |  |  |  |  | 11 |  | 
| 1600 |  |  |  |  |  |  | } | 
| 1601 |  |  |  |  |  |  |  | 
| 1602 |  |  |  |  |  |  | ###################################################################### | 
| 1603 |  |  |  |  |  |  | # hitbytime(); returns %hitbytime | 
| 1604 |  |  |  |  |  |  | =pod | 
| 1605 |  |  |  |  |  |  |  | 
| 1606 |  |  |  |  |  |  | =item * | 
| 1607 |  |  |  |  |  |  |  | 
| 1608 |  |  |  |  |  |  | C | 
| 1609 |  |  |  |  |  |  |  | 
| 1610 |  |  |  |  |  |  | %hitbytime = $logobject->hitbytime(); | 
| 1611 |  |  |  |  |  |  |  | 
| 1612 |  |  |  |  |  |  | Returns a hash containing time (00-23) each file was visited as keys, | 
| 1613 |  |  |  |  |  |  | and the hit count for each key as values. | 
| 1614 |  |  |  |  |  |  |  | 
| 1615 |  |  |  |  |  |  | =cut | 
| 1616 |  |  |  |  |  |  |  | 
| 1617 |  |  |  |  |  |  | sub hitbytime { | 
| 1618 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1619 | 0 | 0 |  |  |  | 0 | return %{($this->{'hitbytime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1620 |  |  |  |  |  |  | } | 
| 1621 |  |  |  |  |  |  |  | 
| 1622 |  |  |  |  |  |  | ###################################################################### | 
| 1623 |  |  |  |  |  |  | # hitbydatetime(); returns %hitbydatetime | 
| 1624 |  |  |  |  |  |  | =pod | 
| 1625 |  |  |  |  |  |  |  | 
| 1626 |  |  |  |  |  |  | =item * | 
| 1627 |  |  |  |  |  |  |  | 
| 1628 |  |  |  |  |  |  | C | 
| 1629 |  |  |  |  |  |  |  | 
| 1630 |  |  |  |  |  |  | %hitbydatetime = $logobject->hitbydatetime(); | 
| 1631 |  |  |  |  |  |  |  | 
| 1632 |  |  |  |  |  |  | Returns a hash containing date/time (mm/dd/yyyy-hh) | 
| 1633 |  |  |  |  |  |  | as keys, and the hit count for each key as values. | 
| 1634 |  |  |  |  |  |  |  | 
| 1635 |  |  |  |  |  |  | =cut | 
| 1636 |  |  |  |  |  |  |  | 
| 1637 |  |  |  |  |  |  | sub hitbydatetime { | 
| 1638 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1639 | 0 | 0 |  |  |  | 0 | return %{($this->{'hitbydatetime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1640 |  |  |  |  |  |  | } | 
| 1641 |  |  |  |  |  |  |  | 
| 1642 |  |  |  |  |  |  | ###################################################################### | 
| 1643 |  |  |  |  |  |  | # visitorbydate(); returns %visitorbydate | 
| 1644 |  |  |  |  |  |  | =pod | 
| 1645 |  |  |  |  |  |  |  | 
| 1646 |  |  |  |  |  |  | =item * | 
| 1647 |  |  |  |  |  |  |  | 
| 1648 |  |  |  |  |  |  | C | 
| 1649 |  |  |  |  |  |  |  | 
| 1650 |  |  |  |  |  |  | %visitorbydate = $logobject->visitorbydate(); | 
| 1651 |  |  |  |  |  |  |  | 
| 1652 |  |  |  |  |  |  | Returns a hash containing date (mm/dd/yyyy) as keys, and the unique | 
| 1653 |  |  |  |  |  |  | visitor count for each key as values. | 
| 1654 |  |  |  |  |  |  |  | 
| 1655 |  |  |  |  |  |  | =cut | 
| 1656 |  |  |  |  |  |  |  | 
| 1657 |  |  |  |  |  |  | sub visitorbydate { | 
| 1658 | 1 |  |  | 1 | 0 | 139 | my($this) = shift; | 
| 1659 | 1 | 50 |  |  |  | 2 | return %{($this->{'visitorbydate'} || undef)}; | 
|  | 1 |  |  |  |  | 7 |  | 
| 1660 |  |  |  |  |  |  | } | 
| 1661 |  |  |  |  |  |  |  | 
| 1662 |  |  |  |  |  |  | ###################################################################### | 
| 1663 |  |  |  |  |  |  | # visitorbytime(); returns %visitorbytime | 
| 1664 |  |  |  |  |  |  | =pod | 
| 1665 |  |  |  |  |  |  |  | 
| 1666 |  |  |  |  |  |  | =item * | 
| 1667 |  |  |  |  |  |  |  | 
| 1668 |  |  |  |  |  |  | C | 
| 1669 |  |  |  |  |  |  |  | 
| 1670 |  |  |  |  |  |  | %visitorbytime = $logobject->visitorbytime(); | 
| 1671 |  |  |  |  |  |  |  | 
| 1672 |  |  |  |  |  |  | Returns a hash containing time (00-23) as keys, and the unique visitor | 
| 1673 |  |  |  |  |  |  | count for each key as values. | 
| 1674 |  |  |  |  |  |  |  | 
| 1675 |  |  |  |  |  |  | =cut | 
| 1676 |  |  |  |  |  |  |  | 
| 1677 |  |  |  |  |  |  | sub visitorbytime { | 
| 1678 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1679 | 0 | 0 |  |  |  | 0 | return %{($this->{'visitorbytime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1680 |  |  |  |  |  |  | } | 
| 1681 |  |  |  |  |  |  |  | 
| 1682 |  |  |  |  |  |  | ###################################################################### | 
| 1683 |  |  |  |  |  |  | # visitorbydatetime(); returns %visitorbydatetime | 
| 1684 |  |  |  |  |  |  | =pod | 
| 1685 |  |  |  |  |  |  |  | 
| 1686 |  |  |  |  |  |  | =item * | 
| 1687 |  |  |  |  |  |  |  | 
| 1688 |  |  |  |  |  |  | C | 
| 1689 |  |  |  |  |  |  |  | 
| 1690 |  |  |  |  |  |  | %visitorbydatetime = $logobject->visitorbydatetime(); | 
| 1691 |  |  |  |  |  |  |  | 
| 1692 |  |  |  |  |  |  | Returns a hash containing date/time (mm/dd/yyyy-hh) | 
| 1693 |  |  |  |  |  |  | as keys, and the unique visitor count for each key as values. | 
| 1694 |  |  |  |  |  |  |  | 
| 1695 |  |  |  |  |  |  | =cut | 
| 1696 |  |  |  |  |  |  |  | 
| 1697 |  |  |  |  |  |  | sub visitorbydatetime { | 
| 1698 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1699 | 0 | 0 |  |  |  | 0 | return %{($this->{'visitorbydatetime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1700 |  |  |  |  |  |  | } | 
| 1701 |  |  |  |  |  |  |  | 
| 1702 |  |  |  |  |  |  | ###################################################################### | 
| 1703 |  |  |  |  |  |  | # method(); returns %method | 
| 1704 |  |  |  |  |  |  | =pod | 
| 1705 |  |  |  |  |  |  |  | 
| 1706 |  |  |  |  |  |  | =item * | 
| 1707 |  |  |  |  |  |  |  | 
| 1708 |  |  |  |  |  |  | C | 
| 1709 |  |  |  |  |  |  |  | 
| 1710 |  |  |  |  |  |  | %method = $logobject->method(); | 
| 1711 |  |  |  |  |  |  |  | 
| 1712 |  |  |  |  |  |  | Returns a hash containing HTTP method (GET, POST, PUT, etc.) | 
| 1713 |  |  |  |  |  |  | as keys, and the hit count for each key as values. | 
| 1714 |  |  |  |  |  |  |  | 
| 1715 |  |  |  |  |  |  | =cut | 
| 1716 |  |  |  |  |  |  |  | 
| 1717 |  |  |  |  |  |  | sub method { | 
| 1718 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1719 | 0 | 0 |  |  |  | 0 | return %{($this->{'method'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1720 |  |  |  |  |  |  | } | 
| 1721 |  |  |  |  |  |  |  | 
| 1722 |  |  |  |  |  |  | ###################################################################### | 
| 1723 |  |  |  |  |  |  | # file(); returns %file | 
| 1724 |  |  |  |  |  |  | =pod | 
| 1725 |  |  |  |  |  |  |  | 
| 1726 |  |  |  |  |  |  | =item * | 
| 1727 |  |  |  |  |  |  |  | 
| 1728 |  |  |  |  |  |  | C | 
| 1729 |  |  |  |  |  |  |  | 
| 1730 |  |  |  |  |  |  | %file = $logobject->file(); | 
| 1731 |  |  |  |  |  |  |  | 
| 1732 |  |  |  |  |  |  | Returns a hash containing the file names relative to the F | 
| 1733 |  |  |  |  |  |  | of the server as keys, and the hit count for each key as values. | 
| 1734 |  |  |  |  |  |  |  | 
| 1735 |  |  |  |  |  |  | =cut | 
| 1736 |  |  |  |  |  |  |  | 
| 1737 |  |  |  |  |  |  | sub file { | 
| 1738 | 1 |  |  | 1 | 0 | 120 | my($this) = shift; | 
| 1739 | 1 | 50 |  |  |  | 1 | return %{($this->{'file'} || undef)}; | 
|  | 1 |  |  |  |  | 13 |  | 
| 1740 |  |  |  |  |  |  | } | 
| 1741 |  |  |  |  |  |  |  | 
| 1742 |  |  |  |  |  |  | ###################################################################### | 
| 1743 |  |  |  |  |  |  | # querystring(); returns %querystring | 
| 1744 |  |  |  |  |  |  | =pod | 
| 1745 |  |  |  |  |  |  |  | 
| 1746 |  |  |  |  |  |  | =item * | 
| 1747 |  |  |  |  |  |  |  | 
| 1748 |  |  |  |  |  |  | C | 
| 1749 |  |  |  |  |  |  |  | 
| 1750 |  |  |  |  |  |  | %querystring = $logobject->querystring(); | 
| 1751 |  |  |  |  |  |  |  | 
| 1752 |  |  |  |  |  |  | Returns a hash containing the query string | 
| 1753 |  |  |  |  |  |  | as keys, and the hit count for each key as values. | 
| 1754 |  |  |  |  |  |  |  | 
| 1755 |  |  |  |  |  |  | =cut | 
| 1756 |  |  |  |  |  |  |  | 
| 1757 |  |  |  |  |  |  | sub querystring { | 
| 1758 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1759 | 0 | 0 |  |  |  | 0 | return %{($this->{'querystring'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1760 |  |  |  |  |  |  | } | 
| 1761 |  |  |  |  |  |  |  | 
| 1762 |  |  |  |  |  |  | ###################################################################### | 
| 1763 |  |  |  |  |  |  | # proto(); returns %proto | 
| 1764 |  |  |  |  |  |  | =pod | 
| 1765 |  |  |  |  |  |  |  | 
| 1766 |  |  |  |  |  |  | =item * | 
| 1767 |  |  |  |  |  |  |  | 
| 1768 |  |  |  |  |  |  | C | 
| 1769 |  |  |  |  |  |  |  | 
| 1770 |  |  |  |  |  |  | %proto = $logobject->proto(); | 
| 1771 |  |  |  |  |  |  |  | 
| 1772 |  |  |  |  |  |  | Returns a hash containing the protocols used (HTTP/1.0, HTTP/1.1, etc.) | 
| 1773 |  |  |  |  |  |  | as keys, and the hit count for each key as values. | 
| 1774 |  |  |  |  |  |  |  | 
| 1775 |  |  |  |  |  |  | =cut | 
| 1776 |  |  |  |  |  |  |  | 
| 1777 |  |  |  |  |  |  | sub proto { | 
| 1778 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1779 | 0 | 0 |  |  |  | 0 | return %{($this->{'proto'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1780 |  |  |  |  |  |  | } | 
| 1781 |  |  |  |  |  |  |  | 
| 1782 |  |  |  |  |  |  | ###################################################################### | 
| 1783 |  |  |  |  |  |  | # lstatus(); returns %lstatus | 
| 1784 |  |  |  |  |  |  | =pod | 
| 1785 |  |  |  |  |  |  |  | 
| 1786 |  |  |  |  |  |  | =item * | 
| 1787 |  |  |  |  |  |  |  | 
| 1788 |  |  |  |  |  |  | C | 
| 1789 |  |  |  |  |  |  |  | 
| 1790 |  |  |  |  |  |  | %lstatus = $logobject->lstatus(); | 
| 1791 |  |  |  |  |  |  |  | 
| 1792 |  |  |  |  |  |  | Returns a hash containing HTTP codes and messages (e.g. "404 Not Found") | 
| 1793 |  |  |  |  |  |  | for the last status (i.e., when the httpd finishes processing that | 
| 1794 |  |  |  |  |  |  | request) as keys, and the hit count for each key as values. | 
| 1795 |  |  |  |  |  |  |  | 
| 1796 |  |  |  |  |  |  | =cut | 
| 1797 |  |  |  |  |  |  |  | 
| 1798 |  |  |  |  |  |  | sub lstatus { | 
| 1799 | 1 |  |  | 1 | 0 | 123 | my($this) = shift; | 
| 1800 | 1 | 50 |  |  |  | 2 | return %{($this->{'lstatus'} || undef)}; | 
|  | 1 |  |  |  |  | 14 |  | 
| 1801 |  |  |  |  |  |  | } | 
| 1802 |  |  |  |  |  |  |  | 
| 1803 |  |  |  |  |  |  | ###################################################################### | 
| 1804 |  |  |  |  |  |  | # byte(); returns %byte | 
| 1805 |  |  |  |  |  |  | =pod | 
| 1806 |  |  |  |  |  |  |  | 
| 1807 |  |  |  |  |  |  | =item * | 
| 1808 |  |  |  |  |  |  |  | 
| 1809 |  |  |  |  |  |  | C | 
| 1810 |  |  |  |  |  |  |  | 
| 1811 |  |  |  |  |  |  | %byte = $logobject->byte(); | 
| 1812 |  |  |  |  |  |  |  | 
| 1813 |  |  |  |  |  |  | Returns a hash containing at least a key 'Total' with the total | 
| 1814 |  |  |  |  |  |  | transferred bytes as its value, and the file extensions (i.e., html, | 
| 1815 |  |  |  |  |  |  | jpg, gif, cgi, pl, etc.) as keys, and the transferred bytes for each | 
| 1816 |  |  |  |  |  |  | key as values. | 
| 1817 |  |  |  |  |  |  |  | 
| 1818 |  |  |  |  |  |  | =cut | 
| 1819 |  |  |  |  |  |  |  | 
| 1820 |  |  |  |  |  |  | sub byte { | 
| 1821 | 1 |  |  | 1 | 0 | 140 | my($this) = shift; | 
| 1822 | 1 | 50 |  |  |  | 2 | return %{($this->{'byte'} || undef)}; | 
|  | 1 |  |  |  |  | 10 |  | 
| 1823 |  |  |  |  |  |  | } | 
| 1824 |  |  |  |  |  |  |  | 
| 1825 |  |  |  |  |  |  | ###################################################################### | 
| 1826 |  |  |  |  |  |  | # bytebydate(); returns %bytebydate | 
| 1827 |  |  |  |  |  |  | =pod | 
| 1828 |  |  |  |  |  |  |  | 
| 1829 |  |  |  |  |  |  | =item * | 
| 1830 |  |  |  |  |  |  |  | 
| 1831 |  |  |  |  |  |  | C | 
| 1832 |  |  |  |  |  |  |  | 
| 1833 |  |  |  |  |  |  | %bytebydate = $logobject->bytebydate(); | 
| 1834 |  |  |  |  |  |  |  | 
| 1835 |  |  |  |  |  |  | Returns a hash containing date (mm/dd/yyyy) as keys, and the hit | 
| 1836 |  |  |  |  |  |  | count for each key as values. | 
| 1837 |  |  |  |  |  |  |  | 
| 1838 |  |  |  |  |  |  | =cut | 
| 1839 |  |  |  |  |  |  |  | 
| 1840 |  |  |  |  |  |  | sub bytebydate { | 
| 1841 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1842 | 0 | 0 |  |  |  | 0 | return %{($this->{'bytebydate'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1843 |  |  |  |  |  |  | } | 
| 1844 |  |  |  |  |  |  |  | 
| 1845 |  |  |  |  |  |  | ###################################################################### | 
| 1846 |  |  |  |  |  |  | # bytebytime(); returns %bytebytime | 
| 1847 |  |  |  |  |  |  | =pod | 
| 1848 |  |  |  |  |  |  |  | 
| 1849 |  |  |  |  |  |  | =item * | 
| 1850 |  |  |  |  |  |  |  | 
| 1851 |  |  |  |  |  |  | C | 
| 1852 |  |  |  |  |  |  |  | 
| 1853 |  |  |  |  |  |  | %bytebytime = $logobject->bytebytime(); | 
| 1854 |  |  |  |  |  |  |  | 
| 1855 |  |  |  |  |  |  | Returns a hash containing time (00-23) as keys, and the hit count | 
| 1856 |  |  |  |  |  |  | for each key as values. | 
| 1857 |  |  |  |  |  |  |  | 
| 1858 |  |  |  |  |  |  | =cut | 
| 1859 |  |  |  |  |  |  |  | 
| 1860 |  |  |  |  |  |  | sub bytebytime { | 
| 1861 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1862 | 0 | 0 |  |  |  | 0 | return %{($this->{'bytebytime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1863 |  |  |  |  |  |  | } | 
| 1864 |  |  |  |  |  |  |  | 
| 1865 |  |  |  |  |  |  | ###################################################################### | 
| 1866 |  |  |  |  |  |  | # bytebydatetime(); returns %bytebydatetime | 
| 1867 |  |  |  |  |  |  | =pod | 
| 1868 |  |  |  |  |  |  |  | 
| 1869 |  |  |  |  |  |  | =item * | 
| 1870 |  |  |  |  |  |  |  | 
| 1871 |  |  |  |  |  |  | C | 
| 1872 |  |  |  |  |  |  |  | 
| 1873 |  |  |  |  |  |  | %bytebydatetime = $logobject->bytebydatetime(); | 
| 1874 |  |  |  |  |  |  |  | 
| 1875 |  |  |  |  |  |  | Returns a hash containing date/time (mm/dd/yyyy-hh) as keys, and the | 
| 1876 |  |  |  |  |  |  | hit count for each key as values. | 
| 1877 |  |  |  |  |  |  |  | 
| 1878 |  |  |  |  |  |  | =back | 
| 1879 |  |  |  |  |  |  |  | 
| 1880 |  |  |  |  |  |  | =cut | 
| 1881 |  |  |  |  |  |  |  | 
| 1882 |  |  |  |  |  |  | sub bytebydatetime { | 
| 1883 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1884 | 0 | 0 |  |  |  | 0 | return %{($this->{'bytebydatetime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1885 |  |  |  |  |  |  | } | 
| 1886 |  |  |  |  |  |  |  | 
| 1887 |  |  |  |  |  |  | ####################################################################### | 
| 1888 |  |  |  |  |  |  | # ERRORLOG METHODS | 
| 1889 |  |  |  |  |  |  | =pod | 
| 1890 |  |  |  |  |  |  |  | 
| 1891 |  |  |  |  |  |  | =head2 ErrorLog Methods | 
| 1892 |  |  |  |  |  |  |  | 
| 1893 |  |  |  |  |  |  | Until the Apache version 1.2.x, each error log entry was just an error, | 
| 1894 |  |  |  |  |  |  | meaning that there was no distinction between "real" errors (e.g., File | 
| 1895 |  |  |  |  |  |  | Not Found, malfunctioning CGI, etc.) and non-significant errors (e.g., | 
| 1896 |  |  |  |  |  |  | kill -1 the httpd processes, etc.). | 
| 1897 |  |  |  |  |  |  |  | 
| 1898 |  |  |  |  |  |  | Starting from the version 1.3.x, the Apache httpd logs the "type" of | 
| 1899 |  |  |  |  |  |  | each error log entry, namely "error", "notice" and "warn". | 
| 1900 |  |  |  |  |  |  |  | 
| 1901 |  |  |  |  |  |  | If you use Apache 1.2.x, the C, C, | 
| 1902 |  |  |  |  |  |  | and C should not be used, because those methods for | 
| 1903 |  |  |  |  |  |  | that are for 1.3.x only will merely return an empty hash. | 
| 1904 |  |  |  |  |  |  | The C methods will return desired results. | 
| 1905 |  |  |  |  |  |  |  | 
| 1906 |  |  |  |  |  |  | The following methods are available for the F object | 
| 1907 |  |  |  |  |  |  | (created by C method). | 
| 1908 |  |  |  |  |  |  |  | 
| 1909 |  |  |  |  |  |  | =over 4 | 
| 1910 |  |  |  |  |  |  |  | 
| 1911 |  |  |  |  |  |  | =cut | 
| 1912 |  |  |  |  |  |  |  | 
| 1913 |  |  |  |  |  |  | ####################################################################### | 
| 1914 |  |  |  |  |  |  | # total(); returns $total; | 
| 1915 |  |  |  |  |  |  | =pod | 
| 1916 |  |  |  |  |  |  |  | 
| 1917 |  |  |  |  |  |  | =item * | 
| 1918 |  |  |  |  |  |  |  | 
| 1919 |  |  |  |  |  |  | C | 
| 1920 |  |  |  |  |  |  |  | 
| 1921 |  |  |  |  |  |  | %errors = $errorlogobject->count(); | 
| 1922 |  |  |  |  |  |  |  | 
| 1923 |  |  |  |  |  |  | Returns a hash containing count for each type of messages | 
| 1924 |  |  |  |  |  |  | logged in the error log file. | 
| 1925 |  |  |  |  |  |  |  | 
| 1926 |  |  |  |  |  |  | The keys and values are: 'Total' (total number of errors), 'error' | 
| 1927 |  |  |  |  |  |  | (total number of errors of type "error"), 'notice' total number of | 
| 1928 |  |  |  |  |  |  | errors of type "notice"),  'warn' (total number of errors of type | 
| 1929 |  |  |  |  |  |  | "warn"), 'dated' (total number of error entries with date logged), | 
| 1930 |  |  |  |  |  |  | and 'nodate' (total number of error entires with no date logged). | 
| 1931 |  |  |  |  |  |  | So: | 
| 1932 |  |  |  |  |  |  |  | 
| 1933 |  |  |  |  |  |  | print "Total Errors: ", $errors{'Total'}, "\n"; | 
| 1934 |  |  |  |  |  |  | print "Total 1.3.x Errors: ", $errors{'error'}, "\n"; | 
| 1935 |  |  |  |  |  |  | print "Total 1.3.x Notices: ", $errors{'notice'}, "\n"; | 
| 1936 |  |  |  |  |  |  | print "Total 1.3.x Warns: ", $errors{'warn'}, "\n"; | 
| 1937 |  |  |  |  |  |  | print "Total Errors with date: ", $errors{'dated'}, "\n"; | 
| 1938 |  |  |  |  |  |  | print "Total Errors with no date: ", $errors{'nodate'}, "\n"; | 
| 1939 |  |  |  |  |  |  |  | 
| 1940 |  |  |  |  |  |  | Note that with the F file generated by Apache version | 
| 1941 |  |  |  |  |  |  | before 1.3.x, the value for 'error', 'notice', and 'warn' will | 
| 1942 |  |  |  |  |  |  | be zero. | 
| 1943 |  |  |  |  |  |  |  | 
| 1944 |  |  |  |  |  |  | =cut | 
| 1945 |  |  |  |  |  |  |  | 
| 1946 |  |  |  |  |  |  | sub count { | 
| 1947 | 1 |  |  | 1 | 0 | 229 | my($this) = shift; | 
| 1948 | 1 | 50 |  |  |  | 2 | return %{($this->{'count'} || undef)}; | 
|  | 1 |  |  |  |  | 12 |  | 
| 1949 |  |  |  |  |  |  | } | 
| 1950 |  |  |  |  |  |  |  | 
| 1951 |  |  |  |  |  |  | ####################################################################### | 
| 1952 |  |  |  |  |  |  | # allbydate(); returns %allbydate; | 
| 1953 |  |  |  |  |  |  | =pod | 
| 1954 |  |  |  |  |  |  |  | 
| 1955 |  |  |  |  |  |  | =item * | 
| 1956 |  |  |  |  |  |  |  | 
| 1957 |  |  |  |  |  |  | C | 
| 1958 |  |  |  |  |  |  |  | 
| 1959 |  |  |  |  |  |  | %allbydate = $errorlogobject->allbydate(); | 
| 1960 |  |  |  |  |  |  |  | 
| 1961 |  |  |  |  |  |  | Returns a hash containing date (mm/dd/yyyy) when the error was logged | 
| 1962 |  |  |  |  |  |  | as keys, and the number of error occurrances as values. | 
| 1963 |  |  |  |  |  |  |  | 
| 1964 |  |  |  |  |  |  | =cut | 
| 1965 |  |  |  |  |  |  |  | 
| 1966 |  |  |  |  |  |  | sub allbydate { | 
| 1967 | 1 |  |  | 1 | 0 | 167 | my($this) = shift; | 
| 1968 | 1 | 50 |  |  |  | 2 | return %{($this->{'allbydate'} || undef)}; | 
|  | 1 |  |  |  |  | 100 |  | 
| 1969 |  |  |  |  |  |  | } | 
| 1970 |  |  |  |  |  |  |  | 
| 1971 |  |  |  |  |  |  | ####################################################################### | 
| 1972 |  |  |  |  |  |  | # allbytime(); returns %allbytime; | 
| 1973 |  |  |  |  |  |  | =pod | 
| 1974 |  |  |  |  |  |  |  | 
| 1975 |  |  |  |  |  |  | =item * | 
| 1976 |  |  |  |  |  |  |  | 
| 1977 |  |  |  |  |  |  | C | 
| 1978 |  |  |  |  |  |  |  | 
| 1979 |  |  |  |  |  |  | %allbytime = $errorlogobject->allbytime(); | 
| 1980 |  |  |  |  |  |  |  | 
| 1981 |  |  |  |  |  |  | Returns a hash containing time (00-23) as keys and the number | 
| 1982 |  |  |  |  |  |  | of error occurrances as values. | 
| 1983 |  |  |  |  |  |  |  | 
| 1984 |  |  |  |  |  |  | =cut | 
| 1985 |  |  |  |  |  |  |  | 
| 1986 |  |  |  |  |  |  | sub allbytime { | 
| 1987 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 1988 | 0 | 0 |  |  |  | 0 | return %{($this->{'allbytime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 1989 |  |  |  |  |  |  | } | 
| 1990 |  |  |  |  |  |  |  | 
| 1991 |  |  |  |  |  |  | ####################################################################### | 
| 1992 |  |  |  |  |  |  | # allbydatetime(); returns %allbydatetime; | 
| 1993 |  |  |  |  |  |  | =pod | 
| 1994 |  |  |  |  |  |  |  | 
| 1995 |  |  |  |  |  |  | =item * | 
| 1996 |  |  |  |  |  |  |  | 
| 1997 |  |  |  |  |  |  | C | 
| 1998 |  |  |  |  |  |  |  | 
| 1999 |  |  |  |  |  |  | %allbydatetime = $errorlogobject->allbydatetime(); | 
| 2000 |  |  |  |  |  |  |  | 
| 2001 |  |  |  |  |  |  | Returns a hash containing date/time (mm/dd/yyyy-hh) as keys and the | 
| 2002 |  |  |  |  |  |  | number of error occurrances as values. | 
| 2003 |  |  |  |  |  |  |  | 
| 2004 |  |  |  |  |  |  | =cut | 
| 2005 |  |  |  |  |  |  |  | 
| 2006 |  |  |  |  |  |  | sub allbydatetime { | 
| 2007 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2008 | 0 | 0 |  |  |  | 0 | return %{($this->{'allbydatetime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2009 |  |  |  |  |  |  | } | 
| 2010 |  |  |  |  |  |  |  | 
| 2011 |  |  |  |  |  |  | ####################################################################### | 
| 2012 |  |  |  |  |  |  | # allmessage(); returns %allmessage; | 
| 2013 |  |  |  |  |  |  | =pod | 
| 2014 |  |  |  |  |  |  |  | 
| 2015 |  |  |  |  |  |  | =item * | 
| 2016 |  |  |  |  |  |  |  | 
| 2017 |  |  |  |  |  |  | C | 
| 2018 |  |  |  |  |  |  |  | 
| 2019 |  |  |  |  |  |  | %allmessage = $errorlogobject->allmessage(); | 
| 2020 |  |  |  |  |  |  |  | 
| 2021 |  |  |  |  |  |  | Returns a hash containing error messages as keys and the number of | 
| 2022 |  |  |  |  |  |  | occurrances as values. | 
| 2023 |  |  |  |  |  |  |  | 
| 2024 |  |  |  |  |  |  | =cut | 
| 2025 |  |  |  |  |  |  |  | 
| 2026 |  |  |  |  |  |  | sub allmessage { | 
| 2027 | 1 |  |  | 1 | 0 | 161 | my($this) = shift; | 
| 2028 | 1 | 50 |  |  |  | 2 | return %{($this->{'allmessage'} || undef)}; | 
|  | 1 |  |  |  |  | 26 |  | 
| 2029 |  |  |  |  |  |  | } | 
| 2030 |  |  |  |  |  |  |  | 
| 2031 |  |  |  |  |  |  | ####################################################################### | 
| 2032 |  |  |  |  |  |  | # errorbydate(); returns %errorbydate; | 
| 2033 |  |  |  |  |  |  | =pod | 
| 2034 |  |  |  |  |  |  |  | 
| 2035 |  |  |  |  |  |  | =item * | 
| 2036 |  |  |  |  |  |  |  | 
| 2037 |  |  |  |  |  |  | C | 
| 2038 |  |  |  |  |  |  |  | 
| 2039 |  |  |  |  |  |  | %errorbydate = $errorlogobject->errorbydate(); | 
| 2040 |  |  |  |  |  |  |  | 
| 2041 |  |  |  |  |  |  | Returns a hash containing date (mm/dd/yyyy) as keys and the number | 
| 2042 |  |  |  |  |  |  | of error occurrances as values. For the Apache 1.3.x log only. | 
| 2043 |  |  |  |  |  |  |  | 
| 2044 |  |  |  |  |  |  | =cut | 
| 2045 |  |  |  |  |  |  |  | 
| 2046 |  |  |  |  |  |  | sub errorbydate { | 
| 2047 | 1 |  |  | 1 | 0 | 161 | my($this) = shift; | 
| 2048 | 1 | 50 |  |  |  | 2 | return %{($this->{'errorbydate'} || undef)}; | 
|  | 1 |  |  |  |  | 10 |  | 
| 2049 |  |  |  |  |  |  | } | 
| 2050 |  |  |  |  |  |  |  | 
| 2051 |  |  |  |  |  |  | ####################################################################### | 
| 2052 |  |  |  |  |  |  | # errorbytime(); returns %errorbytime; | 
| 2053 |  |  |  |  |  |  | =pod | 
| 2054 |  |  |  |  |  |  |  | 
| 2055 |  |  |  |  |  |  | =item * | 
| 2056 |  |  |  |  |  |  |  | 
| 2057 |  |  |  |  |  |  | C | 
| 2058 |  |  |  |  |  |  |  | 
| 2059 |  |  |  |  |  |  | %errorbytime = $errorlogobject->errorbytime(); | 
| 2060 |  |  |  |  |  |  |  | 
| 2061 |  |  |  |  |  |  | Returns a hash containing time (00-23) as keys and the number | 
| 2062 |  |  |  |  |  |  | of error occurrances as values. For the Apache 1.3.x log only. | 
| 2063 |  |  |  |  |  |  |  | 
| 2064 |  |  |  |  |  |  | =cut | 
| 2065 |  |  |  |  |  |  |  | 
| 2066 |  |  |  |  |  |  | sub errorbytime { | 
| 2067 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2068 | 0 | 0 |  |  |  | 0 | return %{($this->{'errorbytime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2069 |  |  |  |  |  |  | } | 
| 2070 |  |  |  |  |  |  |  | 
| 2071 |  |  |  |  |  |  | ####################################################################### | 
| 2072 |  |  |  |  |  |  | # errorbydatetime(); returns %errorbydatetime; | 
| 2073 |  |  |  |  |  |  | =pod | 
| 2074 |  |  |  |  |  |  |  | 
| 2075 |  |  |  |  |  |  | =item * | 
| 2076 |  |  |  |  |  |  |  | 
| 2077 |  |  |  |  |  |  | C | 
| 2078 |  |  |  |  |  |  |  | 
| 2079 |  |  |  |  |  |  | %errorbydatetime = $errorlogobject->errorbydatetime(); | 
| 2080 |  |  |  |  |  |  |  | 
| 2081 |  |  |  |  |  |  | Returns a hash containing date/time (mm/dd/yyyy-hh) as keys and the | 
| 2082 |  |  |  |  |  |  | number of error occurrances as values. For the Apache 1.3.x log only. | 
| 2083 |  |  |  |  |  |  |  | 
| 2084 |  |  |  |  |  |  | =cut | 
| 2085 |  |  |  |  |  |  |  | 
| 2086 |  |  |  |  |  |  | sub errorbydatetime { | 
| 2087 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2088 | 0 | 0 |  |  |  | 0 | return %{($this->{'errorbydatetime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2089 |  |  |  |  |  |  | } | 
| 2090 |  |  |  |  |  |  |  | 
| 2091 |  |  |  |  |  |  | ####################################################################### | 
| 2092 |  |  |  |  |  |  | # errormessage(); returns %errormessage; | 
| 2093 |  |  |  |  |  |  | =pod | 
| 2094 |  |  |  |  |  |  |  | 
| 2095 |  |  |  |  |  |  | =item * | 
| 2096 |  |  |  |  |  |  |  | 
| 2097 |  |  |  |  |  |  | C | 
| 2098 |  |  |  |  |  |  |  | 
| 2099 |  |  |  |  |  |  | %errormessage = $errorlogobject->errormessage(); | 
| 2100 |  |  |  |  |  |  |  | 
| 2101 |  |  |  |  |  |  | Returns a hash containing error messages as keys and the number of | 
| 2102 |  |  |  |  |  |  | occurrances as values. For the Apache 1.3.x log only. | 
| 2103 |  |  |  |  |  |  |  | 
| 2104 |  |  |  |  |  |  | =cut | 
| 2105 |  |  |  |  |  |  |  | 
| 2106 |  |  |  |  |  |  | sub errormessage { | 
| 2107 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2108 | 0 | 0 |  |  |  | 0 | return %{($this->{'errormessage'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2109 |  |  |  |  |  |  | } | 
| 2110 |  |  |  |  |  |  |  | 
| 2111 |  |  |  |  |  |  | ####################################################################### | 
| 2112 |  |  |  |  |  |  | # noticebydate(); returns %noticebydate; | 
| 2113 |  |  |  |  |  |  | =pod | 
| 2114 |  |  |  |  |  |  |  | 
| 2115 |  |  |  |  |  |  | =item * | 
| 2116 |  |  |  |  |  |  |  | 
| 2117 |  |  |  |  |  |  | C | 
| 2118 |  |  |  |  |  |  |  | 
| 2119 |  |  |  |  |  |  | %noticebydate = $errorlogobject->noticebydate(); | 
| 2120 |  |  |  |  |  |  |  | 
| 2121 |  |  |  |  |  |  | Returns a hash containing date (mm/dd/yyyy) as keys and the number | 
| 2122 |  |  |  |  |  |  | of error occurrances as values. For the Apache 1.3.x log only. | 
| 2123 |  |  |  |  |  |  |  | 
| 2124 |  |  |  |  |  |  | =cut | 
| 2125 |  |  |  |  |  |  |  | 
| 2126 |  |  |  |  |  |  | sub noticebydate { | 
| 2127 | 1 |  |  | 1 | 0 | 147 | my($this) = shift; | 
| 2128 | 1 | 50 |  |  |  | 3 | return %{($this->{'noticebydate'} || undef)}; | 
|  | 1 |  |  |  |  | 9 |  | 
| 2129 |  |  |  |  |  |  | } | 
| 2130 |  |  |  |  |  |  |  | 
| 2131 |  |  |  |  |  |  | ####################################################################### | 
| 2132 |  |  |  |  |  |  | # noticebytime(); returns %noticebytime; | 
| 2133 |  |  |  |  |  |  | =pod | 
| 2134 |  |  |  |  |  |  |  | 
| 2135 |  |  |  |  |  |  | =item * | 
| 2136 |  |  |  |  |  |  |  | 
| 2137 |  |  |  |  |  |  | C | 
| 2138 |  |  |  |  |  |  |  | 
| 2139 |  |  |  |  |  |  | %noticebytime = $errorlogobject->noticebytime(); | 
| 2140 |  |  |  |  |  |  |  | 
| 2141 |  |  |  |  |  |  | Returns a hash containing time (00-23) as keys and the number | 
| 2142 |  |  |  |  |  |  | of error occurrances as values. For the Apache 1.3.x log only. | 
| 2143 |  |  |  |  |  |  |  | 
| 2144 |  |  |  |  |  |  | =cut | 
| 2145 |  |  |  |  |  |  |  | 
| 2146 |  |  |  |  |  |  | sub noticebytime { | 
| 2147 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2148 | 0 | 0 |  |  |  | 0 | return %{($this->{'noticebytime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2149 |  |  |  |  |  |  | } | 
| 2150 |  |  |  |  |  |  |  | 
| 2151 |  |  |  |  |  |  | ####################################################################### | 
| 2152 |  |  |  |  |  |  | # noticebydatetime(); returns %noticebydatetime; | 
| 2153 |  |  |  |  |  |  | =pod | 
| 2154 |  |  |  |  |  |  |  | 
| 2155 |  |  |  |  |  |  | =item * | 
| 2156 |  |  |  |  |  |  |  | 
| 2157 |  |  |  |  |  |  | C | 
| 2158 |  |  |  |  |  |  |  | 
| 2159 |  |  |  |  |  |  | %noticebydatetime = $errorlogobject->noticebydatetime(); | 
| 2160 |  |  |  |  |  |  |  | 
| 2161 |  |  |  |  |  |  | Returns a hash containing date/time (mm/dd/yyyy-hh) as keys and the | 
| 2162 |  |  |  |  |  |  | number of error occurrances as values. For the Apache 1.3.x log only. | 
| 2163 |  |  |  |  |  |  |  | 
| 2164 |  |  |  |  |  |  | =cut | 
| 2165 |  |  |  |  |  |  |  | 
| 2166 |  |  |  |  |  |  | sub noticebydatetime { | 
| 2167 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2168 | 0 | 0 |  |  |  | 0 | return %{($this->{'noticebydatetime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2169 |  |  |  |  |  |  | } | 
| 2170 |  |  |  |  |  |  |  | 
| 2171 |  |  |  |  |  |  | ####################################################################### | 
| 2172 |  |  |  |  |  |  | # noticemessage(); returns %noticemessage; | 
| 2173 |  |  |  |  |  |  | =pod | 
| 2174 |  |  |  |  |  |  |  | 
| 2175 |  |  |  |  |  |  | =item * | 
| 2176 |  |  |  |  |  |  |  | 
| 2177 |  |  |  |  |  |  | C | 
| 2178 |  |  |  |  |  |  |  | 
| 2179 |  |  |  |  |  |  | %noticemessage = $errorlogobject->noticemessage(); | 
| 2180 |  |  |  |  |  |  |  | 
| 2181 |  |  |  |  |  |  | Returns a hash containing notice messages as keys and the number of | 
| 2182 |  |  |  |  |  |  | occurrances as values. For the Apache 1.3.x log only. | 
| 2183 |  |  |  |  |  |  |  | 
| 2184 |  |  |  |  |  |  | =cut | 
| 2185 |  |  |  |  |  |  |  | 
| 2186 |  |  |  |  |  |  | sub noticemessage { | 
| 2187 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2188 | 0 | 0 |  |  |  | 0 | return %{($this->{'noticemessage'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2189 |  |  |  |  |  |  | } | 
| 2190 |  |  |  |  |  |  |  | 
| 2191 |  |  |  |  |  |  | ####################################################################### | 
| 2192 |  |  |  |  |  |  | # warnbydate(); returns %warnbydate; | 
| 2193 |  |  |  |  |  |  | =pod | 
| 2194 |  |  |  |  |  |  |  | 
| 2195 |  |  |  |  |  |  | =item * | 
| 2196 |  |  |  |  |  |  |  | 
| 2197 |  |  |  |  |  |  | C | 
| 2198 |  |  |  |  |  |  |  | 
| 2199 |  |  |  |  |  |  | %warnbydate = $errorlogobject->warnbydate(); | 
| 2200 |  |  |  |  |  |  |  | 
| 2201 |  |  |  |  |  |  | Returns a hash containing date (mm/dd/yyyy) as keys and the number | 
| 2202 |  |  |  |  |  |  | of error occurrances as values. For the Apache 1.3.x only. | 
| 2203 |  |  |  |  |  |  |  | 
| 2204 |  |  |  |  |  |  | =cut | 
| 2205 |  |  |  |  |  |  |  | 
| 2206 |  |  |  |  |  |  | sub warnbydate { | 
| 2207 | 1 |  |  | 1 | 0 | 155 | my($this) = shift; | 
| 2208 | 1 | 50 |  |  |  | 2 | return %{($this->{'warnbydate'} || undef)}; | 
|  | 1 |  |  |  |  | 10 |  | 
| 2209 |  |  |  |  |  |  | } | 
| 2210 |  |  |  |  |  |  |  | 
| 2211 |  |  |  |  |  |  | ####################################################################### | 
| 2212 |  |  |  |  |  |  | # warnbytime(); returns %warnbytime; | 
| 2213 |  |  |  |  |  |  | =pod | 
| 2214 |  |  |  |  |  |  |  | 
| 2215 |  |  |  |  |  |  | =item * | 
| 2216 |  |  |  |  |  |  |  | 
| 2217 |  |  |  |  |  |  | C | 
| 2218 |  |  |  |  |  |  |  | 
| 2219 |  |  |  |  |  |  | %warnbytime = $errorlogobject->warnbytime(); | 
| 2220 |  |  |  |  |  |  |  | 
| 2221 |  |  |  |  |  |  | Returns a hash containing time (00-23) as keys and the number | 
| 2222 |  |  |  |  |  |  | of error occurrances as values. For the Apache 1.3.x only. | 
| 2223 |  |  |  |  |  |  |  | 
| 2224 |  |  |  |  |  |  | =cut | 
| 2225 |  |  |  |  |  |  |  | 
| 2226 |  |  |  |  |  |  | sub warnbytime { | 
| 2227 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2228 | 0 | 0 |  |  |  | 0 | return %{($this->{'warnbytime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2229 |  |  |  |  |  |  | } | 
| 2230 |  |  |  |  |  |  |  | 
| 2231 |  |  |  |  |  |  | ####################################################################### | 
| 2232 |  |  |  |  |  |  | # warnbydatetime(); returns %warnbydatetime; | 
| 2233 |  |  |  |  |  |  | =pod | 
| 2234 |  |  |  |  |  |  |  | 
| 2235 |  |  |  |  |  |  | =item * | 
| 2236 |  |  |  |  |  |  |  | 
| 2237 |  |  |  |  |  |  | C | 
| 2238 |  |  |  |  |  |  |  | 
| 2239 |  |  |  |  |  |  | %warnbydatetime = $errorlogobject->warnbydatetime(); | 
| 2240 |  |  |  |  |  |  |  | 
| 2241 |  |  |  |  |  |  | Returns a hash containing date/time (mm/dd/yyyy-hh) as keys and the | 
| 2242 |  |  |  |  |  |  | number of error occurrances as values. For the Apache 1.3.x only. | 
| 2243 |  |  |  |  |  |  |  | 
| 2244 |  |  |  |  |  |  | =cut | 
| 2245 |  |  |  |  |  |  |  | 
| 2246 |  |  |  |  |  |  | sub warnbydatetime { | 
| 2247 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2248 | 0 | 0 |  |  |  | 0 | return %{($this->{'warnbydatetime'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2249 |  |  |  |  |  |  | } | 
| 2250 |  |  |  |  |  |  |  | 
| 2251 |  |  |  |  |  |  | ####################################################################### | 
| 2252 |  |  |  |  |  |  | # warnmessage(); returns %warnmessage; | 
| 2253 |  |  |  |  |  |  | =pod | 
| 2254 |  |  |  |  |  |  |  | 
| 2255 |  |  |  |  |  |  | =item * | 
| 2256 |  |  |  |  |  |  |  | 
| 2257 |  |  |  |  |  |  | C | 
| 2258 |  |  |  |  |  |  |  | 
| 2259 |  |  |  |  |  |  | %warnmessage = $errorlogobject->warnmessage(); | 
| 2260 |  |  |  |  |  |  |  | 
| 2261 |  |  |  |  |  |  | Returns a hash containing warn messages as keys and the number of | 
| 2262 |  |  |  |  |  |  | occurrances as values. For the Apache 1.3.x only. | 
| 2263 |  |  |  |  |  |  |  | 
| 2264 |  |  |  |  |  |  | =back | 
| 2265 |  |  |  |  |  |  |  | 
| 2266 |  |  |  |  |  |  | =cut | 
| 2267 |  |  |  |  |  |  |  | 
| 2268 |  |  |  |  |  |  | sub warnmessage { | 
| 2269 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2270 | 0 | 0 |  |  |  | 0 | return %{($this->{'warnmessage'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2271 |  |  |  |  |  |  | } | 
| 2272 |  |  |  |  |  |  |  | 
| 2273 |  |  |  |  |  |  | ####################################################################### | 
| 2274 |  |  |  |  |  |  | # REFERERLOG METHODS | 
| 2275 |  |  |  |  |  |  | =pod | 
| 2276 |  |  |  |  |  |  |  | 
| 2277 |  |  |  |  |  |  | =head2 RefererLog/CustomLog Methods | 
| 2278 |  |  |  |  |  |  |  | 
| 2279 |  |  |  |  |  |  | The following methods are available for the F object | 
| 2280 |  |  |  |  |  |  | (created by C method), as well as the F | 
| 2281 |  |  |  |  |  |  | object that logs C<%{Referer}i> to the corresponding F. | 
| 2282 |  |  |  |  |  |  |  | 
| 2283 |  |  |  |  |  |  | =over 4 | 
| 2284 |  |  |  |  |  |  |  | 
| 2285 |  |  |  |  |  |  | =cut | 
| 2286 |  |  |  |  |  |  |  | 
| 2287 |  |  |  |  |  |  | ###################################################################### | 
| 2288 |  |  |  |  |  |  | # referer(); returns %referer | 
| 2289 |  |  |  |  |  |  | =pod | 
| 2290 |  |  |  |  |  |  |  | 
| 2291 |  |  |  |  |  |  | =item * | 
| 2292 |  |  |  |  |  |  |  | 
| 2293 |  |  |  |  |  |  | C | 
| 2294 |  |  |  |  |  |  |  | 
| 2295 |  |  |  |  |  |  | %referer = $logobject->referer(); | 
| 2296 |  |  |  |  |  |  |  | 
| 2297 |  |  |  |  |  |  | Returns a hash containing the name of the web site the visitor comes from | 
| 2298 |  |  |  |  |  |  | as keys, and the hit count for each key as values. | 
| 2299 |  |  |  |  |  |  |  | 
| 2300 |  |  |  |  |  |  | Note that the returned data from this method contains B the | 
| 2301 |  |  |  |  |  |  | site name of the referer, e.g. "www.altavista.digital.com", so if you want to | 
| 2302 |  |  |  |  |  |  | obtain the full details of the referer as well as the referred files, | 
| 2303 |  |  |  |  |  |  | use C method described below. | 
| 2304 |  |  |  |  |  |  |  | 
| 2305 |  |  |  |  |  |  | =cut | 
| 2306 |  |  |  |  |  |  |  | 
| 2307 |  |  |  |  |  |  | sub referer { | 
| 2308 | 1 |  |  | 1 | 0 | 957 | my($this) = shift; | 
| 2309 | 1 | 50 |  |  |  | 4 | return %{($this->{'referer'} || undef)}; | 
|  | 1 |  |  |  |  | 13 |  | 
| 2310 |  |  |  |  |  |  |  | 
| 2311 |  |  |  |  |  |  | } | 
| 2312 |  |  |  |  |  |  |  | 
| 2313 |  |  |  |  |  |  | ####################################################################### | 
| 2314 |  |  |  |  |  |  | # refererdetail(); returns %refererdetail | 
| 2315 |  |  |  |  |  |  | =pod | 
| 2316 |  |  |  |  |  |  |  | 
| 2317 |  |  |  |  |  |  | =item * | 
| 2318 |  |  |  |  |  |  |  | 
| 2319 |  |  |  |  |  |  | C | 
| 2320 |  |  |  |  |  |  |  | 
| 2321 |  |  |  |  |  |  | Returns a hash containing the full URL of the referer as keys, and the | 
| 2322 |  |  |  |  |  |  | hit count for each key as values. | 
| 2323 |  |  |  |  |  |  |  | 
| 2324 |  |  |  |  |  |  | The standard log format for the F is  -> I>. | 
| 2325 |  |  |  |  |  |  | With the F object, the object attempts to use the URL first, | 
| 2326 |  |  |  |  |  |  | and if the URL is not logged, then the relative path, and then the absolute | 
| 2327 |  |  |  |  |  |  | path to create the key for the returned data I<%referer>. If none of the URL, | 
| 2328 |  |  |  |  |  |  | relative or absolute paths are logged, the object will use only the referer | 
| 2329 |  |  |  |  |  |  | URL itself (without refererd files) as the key. | 
| 2330 |  |  |  |  |  |  |  | 
| 2331 |  |  |  |  |  |  | =back | 
| 2332 |  |  |  |  |  |  |  | 
| 2333 |  |  |  |  |  |  | =cut | 
| 2334 |  |  |  |  |  |  |  | 
| 2335 |  |  |  |  |  |  | sub refererdetail { | 
| 2336 | 1 |  |  | 1 | 0 | 360 | my($this) = shift; | 
| 2337 | 1 | 50 |  |  |  | 2 | return %{($this->{'refererdetail'} || undef)}; | 
|  | 1 |  |  |  |  | 19 |  | 
| 2338 |  |  |  |  |  |  | } | 
| 2339 |  |  |  |  |  |  |  | 
| 2340 |  |  |  |  |  |  | ####################################################################### | 
| 2341 |  |  |  |  |  |  | # AGENTLOG METHODS | 
| 2342 |  |  |  |  |  |  | =pod | 
| 2343 |  |  |  |  |  |  |  | 
| 2344 |  |  |  |  |  |  | =head2 AgentLog/CustomLog Methods | 
| 2345 |  |  |  |  |  |  |  | 
| 2346 |  |  |  |  |  |  | This subsection describes the methods available for the F object | 
| 2347 |  |  |  |  |  |  | (created by C method), as well as the F | 
| 2348 |  |  |  |  |  |  | object that logs C<%{User-agent}i> to the corresponding F. | 
| 2349 |  |  |  |  |  |  |  | 
| 2350 |  |  |  |  |  |  | =over 4 | 
| 2351 |  |  |  |  |  |  |  | 
| 2352 |  |  |  |  |  |  | =cut | 
| 2353 |  |  |  |  |  |  |  | 
| 2354 |  |  |  |  |  |  | ###################################################################### | 
| 2355 |  |  |  |  |  |  | # uagent(); returns %uagent | 
| 2356 |  |  |  |  |  |  | =pod | 
| 2357 |  |  |  |  |  |  |  | 
| 2358 |  |  |  |  |  |  | =item * | 
| 2359 |  |  |  |  |  |  |  | 
| 2360 |  |  |  |  |  |  | C | 
| 2361 |  |  |  |  |  |  |  | 
| 2362 |  |  |  |  |  |  | %uagent = $logobject->uagent(); | 
| 2363 |  |  |  |  |  |  |  | 
| 2364 |  |  |  |  |  |  | Returns a hash containing the user agent (the "full name", as you | 
| 2365 |  |  |  |  |  |  | see in the log file itself) as keys, and the hit count for each | 
| 2366 |  |  |  |  |  |  | key as values. | 
| 2367 |  |  |  |  |  |  |  | 
| 2368 |  |  |  |  |  |  | =cut | 
| 2369 |  |  |  |  |  |  |  | 
| 2370 |  |  |  |  |  |  | sub uagent { | 
| 2371 | 1 |  |  | 1 | 0 | 380 | my($this) = shift; | 
| 2372 | 1 | 50 |  |  |  | 2 | return %{($this->{'uagent'} || undef)}; | 
|  | 1 |  |  |  |  | 38 |  | 
| 2373 |  |  |  |  |  |  | } | 
| 2374 |  |  |  |  |  |  |  | 
| 2375 |  |  |  |  |  |  | ###################################################################### | 
| 2376 |  |  |  |  |  |  | # uaversion(); returns %uaversion | 
| 2377 |  |  |  |  |  |  | =pod | 
| 2378 |  |  |  |  |  |  |  | 
| 2379 |  |  |  |  |  |  | =item * | 
| 2380 |  |  |  |  |  |  |  | 
| 2381 |  |  |  |  |  |  | C | 
| 2382 |  |  |  |  |  |  |  | 
| 2383 |  |  |  |  |  |  | %uaversion = $logobject->uaversion(); | 
| 2384 |  |  |  |  |  |  |  | 
| 2385 |  |  |  |  |  |  | Returns a hash containing the most basic and simple information about | 
| 2386 |  |  |  |  |  |  | the user agent (the first column in the agent log file, e.g. | 
| 2387 |  |  |  |  |  |  | "C") as keys, and the hit count for each | 
| 2388 |  |  |  |  |  |  | key as values. Useful to collect the information about the parser engine | 
| 2389 |  |  |  |  |  |  | and its version, to determine which specs of HTML and/or JavaScript to | 
| 2390 |  |  |  |  |  |  | deploy, for example. | 
| 2391 |  |  |  |  |  |  |  | 
| 2392 |  |  |  |  |  |  | =cut | 
| 2393 |  |  |  |  |  |  |  | 
| 2394 |  |  |  |  |  |  | sub uaversion { | 
| 2395 | 1 |  |  | 1 | 0 | 132 | my($this) = shift; | 
| 2396 | 1 | 50 |  |  |  | 1 | return %{($this->{'uaversion'} || undef)}; | 
|  | 1 |  |  |  |  | 13 |  | 
| 2397 |  |  |  |  |  |  | } | 
| 2398 |  |  |  |  |  |  |  | 
| 2399 |  |  |  |  |  |  | ###################################################################### | 
| 2400 |  |  |  |  |  |  | # browser(); returns %browser | 
| 2401 |  |  |  |  |  |  | =pod | 
| 2402 |  |  |  |  |  |  |  | 
| 2403 |  |  |  |  |  |  | =item * | 
| 2404 |  |  |  |  |  |  |  | 
| 2405 |  |  |  |  |  |  | C | 
| 2406 |  |  |  |  |  |  |  | 
| 2407 |  |  |  |  |  |  | %browser = $logobject->browser(); | 
| 2408 |  |  |  |  |  |  |  | 
| 2409 |  |  |  |  |  |  | Returns a hash containing the actual browsers (as logged in the file) | 
| 2410 |  |  |  |  |  |  | as keys, and the hit count for each key as values. | 
| 2411 |  |  |  |  |  |  |  | 
| 2412 |  |  |  |  |  |  | For example, Netscape Navigator/Communicator will (still) be reported as | 
| 2413 |  |  |  |  |  |  | "C>", Microsoft Internet Explorer  as "C>", | 
| 2414 |  |  |  |  |  |  | and so on. | 
| 2415 |  |  |  |  |  |  |  | 
| 2416 |  |  |  |  |  |  | =cut | 
| 2417 |  |  |  |  |  |  |  | 
| 2418 |  |  |  |  |  |  | sub browser { | 
| 2419 | 1 |  |  | 1 | 0 | 120 | my($this) = shift; | 
| 2420 | 1 | 50 |  |  |  | 2 | return %{($this->{'browser'} || undef)}; | 
|  | 1 |  |  |  |  | 14 |  | 
| 2421 |  |  |  |  |  |  | } | 
| 2422 |  |  |  |  |  |  |  | 
| 2423 |  |  |  |  |  |  | ###################################################################### | 
| 2424 |  |  |  |  |  |  | # platform(); returns %platform | 
| 2425 |  |  |  |  |  |  | =pod | 
| 2426 |  |  |  |  |  |  |  | 
| 2427 |  |  |  |  |  |  | =item * | 
| 2428 |  |  |  |  |  |  |  | 
| 2429 |  |  |  |  |  |  | C | 
| 2430 |  |  |  |  |  |  |  | 
| 2431 |  |  |  |  |  |  | %platform = $logobject->platform(); | 
| 2432 |  |  |  |  |  |  |  | 
| 2433 |  |  |  |  |  |  | Returns a hash containing the names of OS (and possibly its version, | 
| 2434 |  |  |  |  |  |  | hardware architecture, etc.) as keys, and the hit count for each | 
| 2435 |  |  |  |  |  |  | key as values. | 
| 2436 |  |  |  |  |  |  |  | 
| 2437 |  |  |  |  |  |  | For example, Solaris 2.6 on UltraSPARC will be reported as | 
| 2438 |  |  |  |  |  |  | "C", | 
| 2439 |  |  |  |  |  |  |  | 
| 2440 |  |  |  |  |  |  | =cut | 
| 2441 |  |  |  |  |  |  |  | 
| 2442 |  |  |  |  |  |  | sub platform { | 
| 2443 | 1 |  |  | 1 | 0 | 120 | my($this) = shift; | 
| 2444 | 1 | 50 |  |  |  | 1 | return %{($this->{'platform'} || undef)}; | 
|  | 1 |  |  |  |  | 13 |  | 
| 2445 |  |  |  |  |  |  | } | 
| 2446 |  |  |  |  |  |  |  | 
| 2447 |  |  |  |  |  |  | ###################################################################### | 
| 2448 |  |  |  |  |  |  | # browserbyos(); returns %browserbyos | 
| 2449 |  |  |  |  |  |  | =pod | 
| 2450 |  |  |  |  |  |  |  | 
| 2451 |  |  |  |  |  |  | =item * | 
| 2452 |  |  |  |  |  |  |  | 
| 2453 |  |  |  |  |  |  | C | 
| 2454 |  |  |  |  |  |  |  | 
| 2455 |  |  |  |  |  |  | %browserbyos = $logobject->browserbyos(); | 
| 2456 |  |  |  |  |  |  |  | 
| 2457 |  |  |  |  |  |  | Returns a hash containing the browser names with OS (in the form, | 
| 2458 |  |  |  |  |  |  | I) as keys, and the hit count for each key as values. | 
| 2459 |  |  |  |  |  |  |  | 
| 2460 |  |  |  |  |  |  | =back | 
| 2461 |  |  |  |  |  |  |  | 
| 2462 |  |  |  |  |  |  | =cut | 
| 2463 |  |  |  |  |  |  |  | 
| 2464 |  |  |  |  |  |  | sub browserbyos { | 
| 2465 | 1 |  |  | 1 | 0 | 119 | my($this) = shift; | 
| 2466 | 1 | 50 |  |  |  | 2 | return %{($this->{'browserbyos'} || undef)}; | 
|  | 1 |  |  |  |  | 20 |  | 
| 2467 |  |  |  |  |  |  | } | 
| 2468 |  |  |  |  |  |  |  | 
| 2469 |  |  |  |  |  |  | ####################################################################### | 
| 2470 |  |  |  |  |  |  | # CUSTOMLOG METHODS | 
| 2471 |  |  |  |  |  |  | =pod | 
| 2472 |  |  |  |  |  |  |  | 
| 2473 |  |  |  |  |  |  | =head2 CustomLog Methods | 
| 2474 |  |  |  |  |  |  |  | 
| 2475 |  |  |  |  |  |  | This subsection describes the methods available only for the F | 
| 2476 |  |  |  |  |  |  | object. See each method for what Apache directive is used for each | 
| 2477 |  |  |  |  |  |  | returned result. | 
| 2478 |  |  |  |  |  |  |  | 
| 2479 |  |  |  |  |  |  | =over 4 | 
| 2480 |  |  |  |  |  |  |  | 
| 2481 |  |  |  |  |  |  | =cut | 
| 2482 |  |  |  |  |  |  |  | 
| 2483 |  |  |  |  |  |  | ###################################################################### | 
| 2484 |  |  |  |  |  |  | # addr(); returns %addr | 
| 2485 |  |  |  |  |  |  | =pod | 
| 2486 |  |  |  |  |  |  |  | 
| 2487 |  |  |  |  |  |  | =item * | 
| 2488 |  |  |  |  |  |  |  | 
| 2489 |  |  |  |  |  |  | C | 
| 2490 |  |  |  |  |  |  |  | 
| 2491 |  |  |  |  |  |  | %addr = $logobject->addr(); | 
| 2492 |  |  |  |  |  |  |  | 
| 2493 |  |  |  |  |  |  | Returns a hash containing the IP addresses of the B (instead of | 
| 2494 |  |  |  |  |  |  | the F) visited as keys, and the hit count for each key as | 
| 2495 |  |  |  |  |  |  | values. (LogFormat C<%a>) | 
| 2496 |  |  |  |  |  |  |  | 
| 2497 |  |  |  |  |  |  | =cut | 
| 2498 |  |  |  |  |  |  |  | 
| 2499 |  |  |  |  |  |  | sub addr { | 
| 2500 | 1 |  |  | 1 | 0 | 344 | my($this) = shift; | 
| 2501 | 1 | 50 |  |  |  | 2 | return %{($this->{'addr'} || undef)}; | 
|  | 1 |  |  |  |  | 11 |  | 
| 2502 |  |  |  |  |  |  | } | 
| 2503 |  |  |  |  |  |  |  | 
| 2504 |  |  |  |  |  |  | ###################################################################### | 
| 2505 |  |  |  |  |  |  | # filename(); returns %filename | 
| 2506 |  |  |  |  |  |  | =pod | 
| 2507 |  |  |  |  |  |  |  | 
| 2508 |  |  |  |  |  |  | =item * | 
| 2509 |  |  |  |  |  |  |  | 
| 2510 |  |  |  |  |  |  | C | 
| 2511 |  |  |  |  |  |  |  | 
| 2512 |  |  |  |  |  |  | %filename = $logobject->filename(); | 
| 2513 |  |  |  |  |  |  |  | 
| 2514 |  |  |  |  |  |  | Returns a hash containing the absolute paths to the files as keys, and | 
| 2515 |  |  |  |  |  |  | the hit count for each key as values. (LogFormat C<%f>) | 
| 2516 |  |  |  |  |  |  |  | 
| 2517 |  |  |  |  |  |  | =cut | 
| 2518 |  |  |  |  |  |  |  | 
| 2519 |  |  |  |  |  |  | sub filename { | 
| 2520 | 1 |  |  | 1 | 0 | 3847 | my($this) = shift; | 
| 2521 | 1 | 50 |  |  |  | 5 | return %{($this->{'filename'} || undef)}; | 
|  | 1 |  |  |  |  | 38 |  | 
| 2522 |  |  |  |  |  |  | } | 
| 2523 |  |  |  |  |  |  |  | 
| 2524 |  |  |  |  |  |  | ###################################################################### | 
| 2525 |  |  |  |  |  |  | # hostname(); returns %hostname | 
| 2526 |  |  |  |  |  |  | =pod | 
| 2527 |  |  |  |  |  |  |  | 
| 2528 |  |  |  |  |  |  | =item * | 
| 2529 |  |  |  |  |  |  |  | 
| 2530 |  |  |  |  |  |  | C | 
| 2531 |  |  |  |  |  |  |  | 
| 2532 |  |  |  |  |  |  | %hostname = $logobject->hostname(); | 
| 2533 |  |  |  |  |  |  |  | 
| 2534 |  |  |  |  |  |  | Returns a hash containing the hostnames of the visitors as keys, and | 
| 2535 |  |  |  |  |  |  | the hit count for each key as values. (LogFormat C<%v>) | 
| 2536 |  |  |  |  |  |  |  | 
| 2537 |  |  |  |  |  |  | =cut | 
| 2538 |  |  |  |  |  |  |  | 
| 2539 |  |  |  |  |  |  | sub hostname { | 
| 2540 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2541 | 0 | 0 |  |  |  | 0 | return %{($this->{'hostname'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2542 |  |  |  |  |  |  | } | 
| 2543 |  |  |  |  |  |  |  | 
| 2544 |  |  |  |  |  |  | ###################################################################### | 
| 2545 |  |  |  |  |  |  | # ostatus(); returns %ostatus | 
| 2546 |  |  |  |  |  |  | =pod | 
| 2547 |  |  |  |  |  |  |  | 
| 2548 |  |  |  |  |  |  | =item * | 
| 2549 |  |  |  |  |  |  |  | 
| 2550 |  |  |  |  |  |  | C | 
| 2551 |  |  |  |  |  |  |  | 
| 2552 |  |  |  |  |  |  | %ostatus = $logobject->ostatus(); | 
| 2553 |  |  |  |  |  |  |  | 
| 2554 |  |  |  |  |  |  | Returns a hash containing HTTP codes and messages (e.g. "404 Not Found") | 
| 2555 |  |  |  |  |  |  | for the original status (i.e., when the httpd starts processing that | 
| 2556 |  |  |  |  |  |  | request) as keys, and the hit count for each key as values. | 
| 2557 |  |  |  |  |  |  |  | 
| 2558 |  |  |  |  |  |  | =cut | 
| 2559 |  |  |  |  |  |  |  | 
| 2560 |  |  |  |  |  |  | sub ostatus { | 
| 2561 | 1 |  |  | 1 | 0 | 52 | my($this) = shift; | 
| 2562 | 1 | 50 |  |  |  | 2 | return %{($this->{'ostatus'} || undef)}; | 
|  | 1 |  |  |  |  | 13 |  | 
| 2563 |  |  |  |  |  |  | } | 
| 2564 |  |  |  |  |  |  |  | 
| 2565 |  |  |  |  |  |  | ###################################################################### | 
| 2566 |  |  |  |  |  |  | # port(); returns %port | 
| 2567 |  |  |  |  |  |  | =pod | 
| 2568 |  |  |  |  |  |  |  | 
| 2569 |  |  |  |  |  |  | =item * | 
| 2570 |  |  |  |  |  |  |  | 
| 2571 |  |  |  |  |  |  | C | 
| 2572 |  |  |  |  |  |  |  | 
| 2573 |  |  |  |  |  |  | %port = $logobject->port(); | 
| 2574 |  |  |  |  |  |  |  | 
| 2575 |  |  |  |  |  |  | Returns a hash containing the port used for the transfer as keys, and | 
| 2576 |  |  |  |  |  |  | the hit count for each key as values (there will probably be the only | 
| 2577 |  |  |  |  |  |  | one key-value pair value for each server). (LogFormat C<%p>) | 
| 2578 |  |  |  |  |  |  |  | 
| 2579 |  |  |  |  |  |  | =cut | 
| 2580 |  |  |  |  |  |  |  | 
| 2581 |  |  |  |  |  |  | sub port { | 
| 2582 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2583 | 0 | 0 |  |  |  | 0 | return %{($this->{'port'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2584 |  |  |  |  |  |  | } | 
| 2585 |  |  |  |  |  |  |  | 
| 2586 |  |  |  |  |  |  | ###################################################################### | 
| 2587 |  |  |  |  |  |  | # proc(); returns %proc | 
| 2588 |  |  |  |  |  |  | =pod | 
| 2589 |  |  |  |  |  |  |  | 
| 2590 |  |  |  |  |  |  | =item * | 
| 2591 |  |  |  |  |  |  |  | 
| 2592 |  |  |  |  |  |  | C | 
| 2593 |  |  |  |  |  |  |  | 
| 2594 |  |  |  |  |  |  | %proc = $logobject->proc(); | 
| 2595 |  |  |  |  |  |  |  | 
| 2596 |  |  |  |  |  |  | Returns a hash containing the process ID of the server used for | 
| 2597 |  |  |  |  |  |  | each file transfer as keys, and the hit count for each key as values. | 
| 2598 |  |  |  |  |  |  | (LogFormat C<%P>) | 
| 2599 |  |  |  |  |  |  |  | 
| 2600 |  |  |  |  |  |  | =cut | 
| 2601 |  |  |  |  |  |  |  | 
| 2602 |  |  |  |  |  |  | sub proc { | 
| 2603 | 1 |  |  | 1 | 0 | 19 | my($this) = shift; | 
| 2604 | 1 | 50 |  |  |  | 2 | return %{($this->{'proc'} || undef)}; | 
|  | 1 |  |  |  |  | 15 |  | 
| 2605 |  |  |  |  |  |  | } | 
| 2606 |  |  |  |  |  |  |  | 
| 2607 |  |  |  |  |  |  | ###################################################################### | 
| 2608 |  |  |  |  |  |  | # sec(); returns %sec | 
| 2609 |  |  |  |  |  |  | =pod | 
| 2610 |  |  |  |  |  |  |  | 
| 2611 |  |  |  |  |  |  | =item * | 
| 2612 |  |  |  |  |  |  |  | 
| 2613 |  |  |  |  |  |  | C | 
| 2614 |  |  |  |  |  |  |  | 
| 2615 |  |  |  |  |  |  | %sec = $logobject->sec(); | 
| 2616 |  |  |  |  |  |  |  | 
| 2617 |  |  |  |  |  |  | Returns a hash containing the file names (either relative paths, | 
| 2618 |  |  |  |  |  |  | absolute paths, or the URL, depending on your log format) | 
| 2619 |  |  |  |  |  |  | as keys, and the maximum seconds it takes to finish the process | 
| 2620 |  |  |  |  |  |  | as values. Thus, note that the values are not accumulated results, | 
| 2621 |  |  |  |  |  |  | but rather the highest number of seconds it took to process the file. | 
| 2622 |  |  |  |  |  |  | (LogFormat C<%T>) | 
| 2623 |  |  |  |  |  |  |  | 
| 2624 |  |  |  |  |  |  | =cut | 
| 2625 |  |  |  |  |  |  |  | 
| 2626 |  |  |  |  |  |  | sub sec { | 
| 2627 | 1 |  |  | 1 | 0 | 17 | my($this) = shift; | 
| 2628 | 1 | 50 |  |  |  | 3 | return %{($this->{'sec'} || undef)}; | 
|  | 1 |  |  |  |  | 26 |  | 
| 2629 |  |  |  |  |  |  | } | 
| 2630 |  |  |  |  |  |  |  | 
| 2631 |  |  |  |  |  |  | ###################################################################### | 
| 2632 |  |  |  |  |  |  | # url(); returns %url | 
| 2633 |  |  |  |  |  |  | =pod | 
| 2634 |  |  |  |  |  |  |  | 
| 2635 |  |  |  |  |  |  | =item * | 
| 2636 |  |  |  |  |  |  |  | 
| 2637 |  |  |  |  |  |  | C | 
| 2638 |  |  |  |  |  |  |  | 
| 2639 |  |  |  |  |  |  | %url = $logobject->url(); | 
| 2640 |  |  |  |  |  |  |  | 
| 2641 |  |  |  |  |  |  | Returns a hash containing the URLs (path relative to the F> | 
| 2642 |  |  |  |  |  |  | as keys, and the hit count for each key as values. (LogFormat C<%U>) | 
| 2643 |  |  |  |  |  |  |  | 
| 2644 |  |  |  |  |  |  | =back | 
| 2645 |  |  |  |  |  |  |  | 
| 2646 |  |  |  |  |  |  | =cut | 
| 2647 |  |  |  |  |  |  |  | 
| 2648 |  |  |  |  |  |  | sub url { | 
| 2649 | 1 |  |  | 1 | 0 | 378 | my($this) = shift; | 
| 2650 | 1 | 50 |  |  |  | 3 | return %{($this->{'url'} || undef)}; | 
|  | 1 |  |  |  |  | 25 |  | 
| 2651 |  |  |  |  |  |  | } | 
| 2652 |  |  |  |  |  |  |  | 
| 2653 |  |  |  |  |  |  | ####################################################################### | 
| 2654 |  |  |  |  |  |  | # SPECIAL METHOD | 
| 2655 |  |  |  |  |  |  | =pod | 
| 2656 |  |  |  |  |  |  |  | 
| 2657 |  |  |  |  |  |  | =head2 Special Method | 
| 2658 |  |  |  |  |  |  |  | 
| 2659 |  |  |  |  |  |  | The special method described below, C, can be used with | 
| 2660 |  |  |  |  |  |  | B of the B to extract the methods available for the | 
| 2661 |  |  |  |  |  |  | calling object. | 
| 2662 |  |  |  |  |  |  |  | 
| 2663 |  |  |  |  |  |  | =over 4 | 
| 2664 |  |  |  |  |  |  |  | 
| 2665 |  |  |  |  |  |  | =cut | 
| 2666 |  |  |  |  |  |  |  | 
| 2667 |  |  |  |  |  |  | ####################################################################### | 
| 2668 |  |  |  |  |  |  | # getMethods(); returns @methods; | 
| 2669 |  |  |  |  |  |  | =pod | 
| 2670 |  |  |  |  |  |  |  | 
| 2671 |  |  |  |  |  |  | =item * | 
| 2672 |  |  |  |  |  |  |  | 
| 2673 |  |  |  |  |  |  | C | 
| 2674 |  |  |  |  |  |  |  | 
| 2675 |  |  |  |  |  |  | @object_methods = $logobject->getMethods(); | 
| 2676 |  |  |  |  |  |  |  | 
| 2677 |  |  |  |  |  |  | Returns an array containing the names of the available methods for | 
| 2678 |  |  |  |  |  |  | that log object. Each of the elements in the array is the name of | 
| 2679 |  |  |  |  |  |  | one of the methods described in this section. | 
| 2680 |  |  |  |  |  |  |  | 
| 2681 |  |  |  |  |  |  | By using this method, you can write a I simple Apache log parsing | 
| 2682 |  |  |  |  |  |  | and reporting script, like so: | 
| 2683 |  |  |  |  |  |  |  | 
| 2684 |  |  |  |  |  |  | #!/usr/local/bin/perl | 
| 2685 |  |  |  |  |  |  | $|++; # flush buffer | 
| 2686 |  |  |  |  |  |  | use Apache::ParseLog; | 
| 2687 |  |  |  |  |  |  | # Construct the Apache::ParseLog object | 
| 2688 |  |  |  |  |  |  | $base = new Apache::ParseLog("/usr/local/httpd/conf/httpd.conf"); | 
| 2689 |  |  |  |  |  |  | # Get the CustomLog object for "my_custom_log" | 
| 2690 |  |  |  |  |  |  | $customlog = $base->getCustomLog("my_custom_log"); | 
| 2691 |  |  |  |  |  |  | # Get the available methods for the CustomLog object | 
| 2692 |  |  |  |  |  |  | @methods = $customlog->getMethods(); | 
| 2693 |  |  |  |  |  |  | # Iterate through the @methods | 
| 2694 |  |  |  |  |  |  | foreach $method (@methods) { | 
| 2695 |  |  |  |  |  |  | print "$method log report\n"; | 
| 2696 |  |  |  |  |  |  | # Get the returned value for each method | 
| 2697 |  |  |  |  |  |  | %{$method} = $customlog->$method(); | 
| 2698 |  |  |  |  |  |  | # Iterate through the returned hash | 
| 2699 |  |  |  |  |  |  | foreach (sort keys %{$method}) { | 
| 2700 |  |  |  |  |  |  | print "$_: ${$method}{$_}\n"; | 
| 2701 |  |  |  |  |  |  | } | 
| 2702 |  |  |  |  |  |  | print "\n"; | 
| 2703 |  |  |  |  |  |  | } | 
| 2704 |  |  |  |  |  |  | exit; | 
| 2705 |  |  |  |  |  |  |  | 
| 2706 |  |  |  |  |  |  | =back | 
| 2707 |  |  |  |  |  |  |  | 
| 2708 |  |  |  |  |  |  | =cut | 
| 2709 |  |  |  |  |  |  |  | 
| 2710 |  |  |  |  |  |  | sub getMethods { | 
| 2711 | 0 |  |  | 0 | 0 | 0 | my($this) = shift; | 
| 2712 | 0 | 0 |  |  |  | 0 | return @{($this->{'methods'} || undef)}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2713 |  |  |  |  |  |  | } | 
| 2714 |  |  |  |  |  |  |  | 
| 2715 |  |  |  |  |  |  | ####################################################################### | 
| 2716 |  |  |  |  |  |  | # MISCELLANEOUS | 
| 2717 |  |  |  |  |  |  | ####################################################################### | 
| 2718 |  |  |  |  |  |  | =pod | 
| 2719 |  |  |  |  |  |  |  | 
| 2720 |  |  |  |  |  |  | =head1 MISCELLANEOUS | 
| 2721 |  |  |  |  |  |  |  | 
| 2722 |  |  |  |  |  |  | This section describes some miscellaneous methods that might be useful. | 
| 2723 |  |  |  |  |  |  |  | 
| 2724 |  |  |  |  |  |  | =cut | 
| 2725 |  |  |  |  |  |  |  | 
| 2726 |  |  |  |  |  |  | ####################################################################### | 
| 2727 |  |  |  |  |  |  | # version(); returns $VERSION | 
| 2728 |  |  |  |  |  |  | =pod | 
| 2729 |  |  |  |  |  |  |  | 
| 2730 |  |  |  |  |  |  | =over 4 | 
| 2731 |  |  |  |  |  |  |  | 
| 2732 |  |  |  |  |  |  | =item * | 
| 2733 |  |  |  |  |  |  |  | 
| 2734 |  |  |  |  |  |  | C | 
| 2735 |  |  |  |  |  |  |  | 
| 2736 |  |  |  |  |  |  | Returns a scalar containing the version of the Apache::ParseLog module. | 
| 2737 |  |  |  |  |  |  |  | 
| 2738 |  |  |  |  |  |  | =back | 
| 2739 |  |  |  |  |  |  |  | 
| 2740 |  |  |  |  |  |  | =cut | 
| 2741 |  |  |  |  |  |  |  | 
| 2742 | 1 |  |  | 1 | 1 | 51 | sub Version { $VERSION } | 
| 2743 |  |  |  |  |  |  |  | 
| 2744 |  |  |  |  |  |  | ####################################################################### | 
| 2745 |  |  |  |  |  |  | # EXPORTED METHODS | 
| 2746 |  |  |  |  |  |  | =pod | 
| 2747 |  |  |  |  |  |  |  | 
| 2748 |  |  |  |  |  |  | =head2 Exported Methods | 
| 2749 |  |  |  |  |  |  |  | 
| 2750 |  |  |  |  |  |  | This subsection describes B methods provided by the | 
| 2751 |  |  |  |  |  |  | Apache::ParseLog module. (For the information about exported methods, | 
| 2752 |  |  |  |  |  |  | see Exporter(3).) | 
| 2753 |  |  |  |  |  |  |  | 
| 2754 |  |  |  |  |  |  | Note that those exported modules can be used (called) just like | 
| 2755 |  |  |  |  |  |  | local (main package) subroutines. | 
| 2756 |  |  |  |  |  |  |  | 
| 2757 |  |  |  |  |  |  | =over 4 | 
| 2758 |  |  |  |  |  |  |  | 
| 2759 |  |  |  |  |  |  | =cut | 
| 2760 |  |  |  |  |  |  |  | 
| 2761 |  |  |  |  |  |  | ####################################################################### | 
| 2762 |  |  |  |  |  |  | # countryByCode(); returns %COUNTRY_BY_CODE | 
| 2763 |  |  |  |  |  |  | =pod | 
| 2764 |  |  |  |  |  |  |  | 
| 2765 |  |  |  |  |  |  | =item * | 
| 2766 |  |  |  |  |  |  |  | 
| 2767 |  |  |  |  |  |  | C | 
| 2768 |  |  |  |  |  |  |  | 
| 2769 |  |  |  |  |  |  | %countryByCode = countryByCode(); | 
| 2770 |  |  |  |  |  |  |  | 
| 2771 |  |  |  |  |  |  | Returns a hash containing a hashtable of country-code top-level domain | 
| 2772 |  |  |  |  |  |  | names as keys and country names as values. Useful for creating a report | 
| 2773 |  |  |  |  |  |  | on "hits" by countries. | 
| 2774 |  |  |  |  |  |  |  | 
| 2775 |  |  |  |  |  |  | =cut | 
| 2776 |  |  |  |  |  |  |  | 
| 2777 |  |  |  |  |  |  | sub countryByCode { | 
| 2778 | 0 |  |  | 0 | 0 | 0 | return %COUNTRY_BY_CODE; | 
| 2779 |  |  |  |  |  |  | } | 
| 2780 |  |  |  |  |  |  |  | 
| 2781 |  |  |  |  |  |  | ####################################################################### | 
| 2782 |  |  |  |  |  |  | # statusByCode(); returns %STATUS_BY_CODE | 
| 2783 |  |  |  |  |  |  | =pod | 
| 2784 |  |  |  |  |  |  |  | 
| 2785 |  |  |  |  |  |  | =item * | 
| 2786 |  |  |  |  |  |  |  | 
| 2787 |  |  |  |  |  |  | C | 
| 2788 |  |  |  |  |  |  |  | 
| 2789 |  |  |  |  |  |  | %statusByCode = statusByCode(); | 
| 2790 |  |  |  |  |  |  |  | 
| 2791 |  |  |  |  |  |  | Returns a hash containing a hashtable of status code of the Apache HTTPD | 
| 2792 |  |  |  |  |  |  | server, as defined by RFC2068, as keys and meanings as values. | 
| 2793 |  |  |  |  |  |  |  | 
| 2794 |  |  |  |  |  |  | =cut | 
| 2795 |  |  |  |  |  |  |  | 
| 2796 |  |  |  |  |  |  | sub statusByCode { | 
| 2797 | 0 |  |  | 0 | 0 | 0 | return %STATUS_BY_CODE; | 
| 2798 |  |  |  |  |  |  | } | 
| 2799 |  |  |  |  |  |  |  | 
| 2800 |  |  |  |  |  |  | ####################################################################### | 
| 2801 |  |  |  |  |  |  | # sortHashByValue(); returns @sorted | 
| 2802 |  |  |  |  |  |  | =pod | 
| 2803 |  |  |  |  |  |  |  | 
| 2804 |  |  |  |  |  |  | =item * | 
| 2805 |  |  |  |  |  |  |  | 
| 2806 |  |  |  |  |  |  | C | 
| 2807 |  |  |  |  |  |  |  | 
| 2808 |  |  |  |  |  |  | @sorted_keys = sortHashByValue(%hash); | 
| 2809 |  |  |  |  |  |  |  | 
| 2810 |  |  |  |  |  |  | Returns an array containing keys of the I<%hash> B sorted | 
| 2811 |  |  |  |  |  |  | by the values of the I<%hash>, by the descending order. | 
| 2812 |  |  |  |  |  |  |  | 
| 2813 |  |  |  |  |  |  | Example | 
| 2814 |  |  |  |  |  |  |  | 
| 2815 |  |  |  |  |  |  | # Get the custom log object | 
| 2816 |  |  |  |  |  |  | $customlog = $log->getCustomLog("combined"); | 
| 2817 |  |  |  |  |  |  | # Get the log report on "file" | 
| 2818 |  |  |  |  |  |  | %file = $customlog->file(); | 
| 2819 |  |  |  |  |  |  | # Sort the %file by hit counts, descending order | 
| 2820 |  |  |  |  |  |  | @sorted_keys = sortHashByValue(%hash); | 
| 2821 |  |  |  |  |  |  | foreach (@sorted_keys) { | 
| 2822 |  |  |  |  |  |  | print "$_: $file{$_}\n"; # print : | 
| 2823 |  |  |  |  |  |  | } | 
| 2824 |  |  |  |  |  |  |  | 
| 2825 |  |  |  |  |  |  | =back | 
| 2826 |  |  |  |  |  |  |  | 
| 2827 |  |  |  |  |  |  | =cut | 
| 2828 |  |  |  |  |  |  |  | 
| 2829 |  |  |  |  |  |  | sub sortHashByValue { | 
| 2830 | 0 |  |  | 0 | 0 | 0 | my(%hash) = @_; | 
| 2831 | 0 |  |  |  |  | 0 | return sort { $hash{$b} <=> $hash{$a} } keys %hash; | 
|  | 0 |  |  |  |  | 0 |  | 
| 2832 |  |  |  |  |  |  | } | 
| 2833 |  |  |  |  |  |  |  | 
| 2834 |  |  |  |  |  |  | ####################################################################### | 
| 2835 |  |  |  |  |  |  | # PRIVATE METHODS | 
| 2836 |  |  |  |  |  |  | ####################################################################### | 
| 2837 |  |  |  |  |  |  |  | 
| 2838 |  |  |  |  |  |  | ####################################################################### | 
| 2839 |  |  |  |  |  |  | # openFile($any_file); returns a filehandle | 
| 2840 |  |  |  |  |  |  | sub openFile { | 
| 2841 | 15 |  |  | 15 | 0 | 54 | my($file) = shift; | 
| 2842 | 15 |  |  |  |  | 85 | my($METHOD) = "Apache::ParseLog::openFile"; | 
| 2843 | 15 |  |  |  |  | 57 | local(*FH); | 
| 2844 | 15 | 50 |  |  |  | 1659 | open(FH, "<$file") or croak "$METHOD: Cannot open $file. Exiting "; | 
| 2845 | 15 |  |  |  |  | 182 | return *FH; | 
| 2846 |  |  |  |  |  |  | } | 
| 2847 |  |  |  |  |  |  |  | 
| 2848 |  |  |  |  |  |  | ####################################################################### | 
| 2849 |  |  |  |  |  |  | # ADDITIONAL DOCUMENTATION | 
| 2850 |  |  |  |  |  |  | ####################################################################### | 
| 2851 |  |  |  |  |  |  | =pod | 
| 2852 |  |  |  |  |  |  |  | 
| 2853 |  |  |  |  |  |  | =head1 EXAMPLES | 
| 2854 |  |  |  |  |  |  |  | 
| 2855 |  |  |  |  |  |  | The most basic, easiest way to create reports is presented as an | 
| 2856 |  |  |  |  |  |  | example in the C section above, but the format of the | 
| 2857 |  |  |  |  |  |  | output is pretty crude and less user-friendly. | 
| 2858 |  |  |  |  |  |  |  | 
| 2859 |  |  |  |  |  |  | Shown below are some other examples to use Apache::ParseLog. | 
| 2860 |  |  |  |  |  |  |  | 
| 2861 |  |  |  |  |  |  | =head2 Example 1: Basic Report | 
| 2862 |  |  |  |  |  |  |  | 
| 2863 |  |  |  |  |  |  | The example code below checks the F and F | 
| 2864 |  |  |  |  |  |  | generated by the Apache 1.2.x, and prints the reports to STDOUT. | 
| 2865 |  |  |  |  |  |  | (To run this code, all you have to do is to change the I<$conf> | 
| 2866 |  |  |  |  |  |  | value.) | 
| 2867 |  |  |  |  |  |  |  | 
| 2868 |  |  |  |  |  |  | #!/usr/local/bin/perl | 
| 2869 |  |  |  |  |  |  | $|++; | 
| 2870 |  |  |  |  |  |  | use Apache::ParseLog; | 
| 2871 |  |  |  |  |  |  |  | 
| 2872 |  |  |  |  |  |  | $conf = "/usr/local/httpd/conf/httpd.conf"; | 
| 2873 |  |  |  |  |  |  | $base = new Apache::ParseLog($conf); | 
| 2874 |  |  |  |  |  |  |  | 
| 2875 |  |  |  |  |  |  | print "TransferLog Report\n\n"; | 
| 2876 |  |  |  |  |  |  | $transferlog = $base->getTransferLog(); | 
| 2877 |  |  |  |  |  |  |  | 
| 2878 |  |  |  |  |  |  | %hit = $transferlog->hit(); | 
| 2879 |  |  |  |  |  |  | %hitbydate = $transferlog->hitbydate(); | 
| 2880 |  |  |  |  |  |  | print "Total Hit Counts: ", $hit{'Total'}, "\n"; | 
| 2881 |  |  |  |  |  |  | foreach (sort keys %hitbydate) { | 
| 2882 |  |  |  |  |  |  | print "$_:\t$hitbydate{$_}\n"; # : | 
| 2883 |  |  |  |  |  |  | } | 
| 2884 |  |  |  |  |  |  | $hitaverage = int($hit{'Total'} / scalar(keys %hitbydate)); | 
| 2885 |  |  |  |  |  |  | print "Average Daily Hits: $hitaverage\n\n"; | 
| 2886 |  |  |  |  |  |  |  | 
| 2887 |  |  |  |  |  |  | %byte = $transferlog->byte(); | 
| 2888 |  |  |  |  |  |  | %bytebydate = $transferlog->bytebydate(); | 
| 2889 |  |  |  |  |  |  | print "Total Bytes Transferred: ", $byte{'Total'}, "\n"; | 
| 2890 |  |  |  |  |  |  | foreach (sort keys %bytebydate) { | 
| 2891 |  |  |  |  |  |  | print "$_:\t$bytebydate{$_}\n"; # : | 
| 2892 |  |  |  |  |  |  | } | 
| 2893 |  |  |  |  |  |  | $byteaverage = int($byte{'Total'} / scalar(keys %bytebydate)); | 
| 2894 |  |  |  |  |  |  | print "Average Daily Bytes Transferred: $byteaverage\n\n"; | 
| 2895 |  |  |  |  |  |  |  | 
| 2896 |  |  |  |  |  |  | %visitorbydate = $transferlog->visitorbydate(); | 
| 2897 |  |  |  |  |  |  | %host = $transferlog->host(); | 
| 2898 |  |  |  |  |  |  | print "Total Unique Visitors: ", scalar(keys %host), "\n"; | 
| 2899 |  |  |  |  |  |  | foreach (sort keys %visitorbydate) { | 
| 2900 |  |  |  |  |  |  | print "$_:\t$visitorbydate{$_}\n"; # | 
| 2901 |  |  |  |  |  |  | } | 
| 2902 |  |  |  |  |  |  | $visitoraverage = int(scalar(keys %host) / scalar(keys %visitorbydate)); | 
| 2903 |  |  |  |  |  |  | print "Average Daily Unique Visitors: $visitoraverage\n\n"; | 
| 2904 |  |  |  |  |  |  |  | 
| 2905 |  |  |  |  |  |  | print "ErrorLog Report\n\n"; | 
| 2906 |  |  |  |  |  |  | $errorlog = $base->getErrorLog(); | 
| 2907 |  |  |  |  |  |  |  | 
| 2908 |  |  |  |  |  |  | %count = $errorlog->count(); | 
| 2909 |  |  |  |  |  |  | %allbydate = $errorlog->allbydate(); | 
| 2910 |  |  |  |  |  |  | print "Total Errors: ", $count{'Total'}, "\n"; | 
| 2911 |  |  |  |  |  |  | foreach (sort keys %allbydate) { | 
| 2912 |  |  |  |  |  |  | print "$_:\t$allbydate{$_}\n"; # : | 
| 2913 |  |  |  |  |  |  | } | 
| 2914 |  |  |  |  |  |  | $erroraverage = int($count{'Total'} / scalar(keys %allbydate)); | 
| 2915 |  |  |  |  |  |  | print "Average Daily Errors: $erroraverage\n\n"; | 
| 2916 |  |  |  |  |  |  |  | 
| 2917 |  |  |  |  |  |  | exit; | 
| 2918 |  |  |  |  |  |  |  | 
| 2919 |  |  |  |  |  |  | =head2 Example 2: Referer Report | 
| 2920 |  |  |  |  |  |  |  | 
| 2921 |  |  |  |  |  |  | The F (or F with referer logged) contains the | 
| 2922 |  |  |  |  |  |  | referer for every single file requested. It means that everytime a page | 
| 2923 |  |  |  |  |  |  | that contains 10 images is requested, 11 lines are added to the | 
| 2924 |  |  |  |  |  |  | F, one line for the actual referer (where the visitor | 
| 2925 |  |  |  |  |  |  | comes from), and the other 10 lines for the images with the | 
| 2926 |  |  |  |  |  |  | I page containing the 10 images as the referer, | 
| 2927 |  |  |  |  |  |  | which is probably a little too much more than what you want to know. | 
| 2928 |  |  |  |  |  |  |  | 
| 2929 |  |  |  |  |  |  | The example code below checks the F that contains referer, | 
| 2930 |  |  |  |  |  |  | (among other things), and reports the names of the referer sites that | 
| 2931 |  |  |  |  |  |  | are not the local server itself. | 
| 2932 |  |  |  |  |  |  |  | 
| 2933 |  |  |  |  |  |  | #!/usr/local/bin/perl | 
| 2934 |  |  |  |  |  |  | $|++; | 
| 2935 |  |  |  |  |  |  | use Apache::ParseLog; | 
| 2936 |  |  |  |  |  |  |  | 
| 2937 |  |  |  |  |  |  | $conf = "/usr/local/httpd/conf/httpd.conf"; | 
| 2938 |  |  |  |  |  |  | $base = new Apache::ParseLog($conf); | 
| 2939 |  |  |  |  |  |  |  | 
| 2940 |  |  |  |  |  |  | $localserver = $base->servername(); | 
| 2941 |  |  |  |  |  |  |  | 
| 2942 |  |  |  |  |  |  | $log = $base->getCustomLog("combined"); | 
| 2943 |  |  |  |  |  |  | %referer = $log->referer(); | 
| 2944 |  |  |  |  |  |  | @sortedkeys = sortHashByValue(%referer); | 
| 2945 |  |  |  |  |  |  |  | 
| 2946 |  |  |  |  |  |  | print "External Referers Report\n"; | 
| 2947 |  |  |  |  |  |  | foreach (@sortedkeys) { | 
| 2948 |  |  |  |  |  |  | print "$_:\t$referer{$_}\n" unless m/$localserver/i or m/^\-/; | 
| 2949 |  |  |  |  |  |  | } | 
| 2950 |  |  |  |  |  |  |  | 
| 2951 |  |  |  |  |  |  | exit; | 
| 2952 |  |  |  |  |  |  |  | 
| 2953 |  |  |  |  |  |  | =head2 Example 3: Access-Controlled User Report | 
| 2954 |  |  |  |  |  |  |  | 
| 2955 |  |  |  |  |  |  | Let's suppose that you have a directory tree on your site that is | 
| 2956 |  |  |  |  |  |  | access-controlled by F<.htaccess> or the like, and you want to check | 
| 2957 |  |  |  |  |  |  | how frequently the section is used by the users. | 
| 2958 |  |  |  |  |  |  |  | 
| 2959 |  |  |  |  |  |  | #!/usr/local/bin/perl | 
| 2960 |  |  |  |  |  |  | $|++; | 
| 2961 |  |  |  |  |  |  | use Apache::ParseLog; | 
| 2962 |  |  |  |  |  |  |  | 
| 2963 |  |  |  |  |  |  | $conf = "/usr/local/httpd/conf/httpd.conf"; | 
| 2964 |  |  |  |  |  |  | $base = new Apache::ParseLog($conf); | 
| 2965 |  |  |  |  |  |  |  | 
| 2966 |  |  |  |  |  |  | $log = $base->getCustomLog("common"); | 
| 2967 |  |  |  |  |  |  | %user = $log->user(); | 
| 2968 |  |  |  |  |  |  |  | 
| 2969 |  |  |  |  |  |  | print "Users Report\n"; | 
| 2970 |  |  |  |  |  |  | foreach (sort keys %user) { | 
| 2971 |  |  |  |  |  |  | print "$_:\t$user{$_}\n" unless m/^-$/; | 
| 2972 |  |  |  |  |  |  | } | 
| 2973 |  |  |  |  |  |  |  | 
| 2974 |  |  |  |  |  |  | exit; | 
| 2975 |  |  |  |  |  |  |  | 
| 2976 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 2977 |  |  |  |  |  |  |  | 
| 2978 |  |  |  |  |  |  | perl(1), perlop(1), perlre(1), Exporter(3) | 
| 2979 |  |  |  |  |  |  |  | 
| 2980 |  |  |  |  |  |  | =head1 BUGS | 
| 2981 |  |  |  |  |  |  |  | 
| 2982 |  |  |  |  |  |  | The reports on lesser-known browsers returned from the F methods | 
| 2983 |  |  |  |  |  |  | are not always informative. | 
| 2984 |  |  |  |  |  |  |  | 
| 2985 |  |  |  |  |  |  | The data returned from the C method for F may | 
| 2986 |  |  |  |  |  |  | be irrelvant if the referred files are not accessed via HTTP (i.e., | 
| 2987 |  |  |  |  |  |  | the referer does not start with "http://" string). | 
| 2988 |  |  |  |  |  |  |  | 
| 2989 |  |  |  |  |  |  | If the base object is created with the I<$virtualhost> specified, | 
| 2990 |  |  |  |  |  |  | unless the F and F are specified within | 
| 2991 |  |  |  |  |  |  | the  ... , those values specified | 
| 2992 |  |  |  |  |  |  | in the global section of the I are not shared with | 
| 2993 |  |  |  |  |  |  | the I<$virtualhost>. | 
| 2994 |  |  |  |  |  |  |  | 
| 2995 |  |  |  |  |  |  | =head1 TO DO | 
| 2996 |  |  |  |  |  |  |  | 
| 2997 |  |  |  |  |  |  | Increase the performance (speed). | 
| 2998 |  |  |  |  |  |  |  | 
| 2999 |  |  |  |  |  |  | =head1 VERSION | 
| 3000 |  |  |  |  |  |  |  | 
| 3001 |  |  |  |  |  |  | Apache::ParseLog 1.01 (10/01/1998). | 
| 3002 |  |  |  |  |  |  |  | 
| 3003 |  |  |  |  |  |  | =head1 AUTHOR | 
| 3004 |  |  |  |  |  |  |  | 
| 3005 |  |  |  |  |  |  | Apache::ParseLog was written and is maintained by Akira Hangai | 
| 3006 |  |  |  |  |  |  | (akira@discover-net.net) | 
| 3007 |  |  |  |  |  |  |  | 
| 3008 |  |  |  |  |  |  | For the bug reports, comments, suggestions, etc., please email me. | 
| 3009 |  |  |  |  |  |  |  | 
| 3010 |  |  |  |  |  |  | =head1 COPYRIGHT | 
| 3011 |  |  |  |  |  |  |  | 
| 3012 |  |  |  |  |  |  | Copyright 1998, Akira Hangai. All rights reserved. | 
| 3013 |  |  |  |  |  |  |  | 
| 3014 |  |  |  |  |  |  | This program is free software; You can redistribute it and/or modify | 
| 3015 |  |  |  |  |  |  | it under the same terms as Perl itself. | 
| 3016 |  |  |  |  |  |  |  | 
| 3017 |  |  |  |  |  |  | =head1 DISCLAIMER | 
| 3018 |  |  |  |  |  |  |  | 
| 3019 |  |  |  |  |  |  | This package is distributed in the hope that it will be useful for | 
| 3020 |  |  |  |  |  |  | many web administrators/webmasters who are too busy to write their own | 
| 3021 |  |  |  |  |  |  | programs to analyze the Apache log files. However, this package is | 
| 3022 |  |  |  |  |  |  | so distributed WITHOUT ANY WARRANTY in that any use of the data | 
| 3023 |  |  |  |  |  |  | generated by this package must be used at the user's own discretion, | 
| 3024 |  |  |  |  |  |  | and the author shall not be held accountable for any results | 
| 3025 |  |  |  |  |  |  | from the use of this package. | 
| 3026 |  |  |  |  |  |  |  | 
| 3027 |  |  |  |  |  |  | =cut | 
| 3028 |  |  |  |  |  |  |  | 
| 3029 |  |  |  |  |  |  | ####################################################################### | 
| 3030 |  |  |  |  |  |  | # DATA | 
| 3031 |  |  |  |  |  |  | ####################################################################### | 
| 3032 |  |  |  |  |  |  | __DATA__ |