File Coverage

blib/lib/Nginx/Log/Entry.pm
Criterion Covered Total %
statement 15 59 25.4
branch 0 6 0.0
condition n/a
subroutine 5 22 22.7
pod 17 17 100.0
total 37 104 35.5


line stmt bran cond sub pod time code
1             package Nginx::Log::Entry;
2 1     1   23591 use strict;
  1         3  
  1         38  
3 1     1   4 use warnings;
  1         2  
  1         32  
4 1     1   990 use Time::Piece;
  1         15963  
  1         6  
5 1     1   995 use Nginx::ParseLog;
  1         307  
  1         25  
6 1     1   1109 use HTTP::BrowserDetect;
  1         13761  
  1         780  
7              
8             our $VERSION = 0.05;
9              
10             =head1 NAME
11              
12             Nginx::Log::Entry - This class represents a single line from the Nginx combined access log (the default access log format). It provides methods to extract information from the log entry, such as the browser, operating system, request type, ip address and more. If you want to gather statistics about an Nginx log, consider using L which uses this class.
13              
14             =cut
15              
16             =head1 SYNOPSIS
17              
18             use Nginx::Log::Entry;
19             my $entry = Nginx::Log::Entry->new(q{66.108.215.71 - - [24/Mar/2013:10:00:58 -0400] "GET / HTTP/1.1" 200 727 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:19.0) Gecko/20100101 Firefox/19.0"});
20             print $entry->get_ip;
21             # 66.108.215.71
22            
23             print $entry->get_os;
24             # Linux
25              
26             =cut
27              
28             =head1 METHODS
29              
30             =head2 new
31              
32             Instantiates a new entry object, requires a line from the Nginx access.log as a string argument.
33              
34             =cut
35              
36             sub new {
37 0     0 1   my ( $class, $log_line ) = @_;
38 0 0         die "Error: no log string was passed to new" unless $log_line;
39 0           my $self = Nginx::ParseLog::parse($log_line);
40 0           $self->{detector} = HTTP::BrowserDetect->new( $self->{user_agent} );
41 0           return bless $self, $class;
42             }
43              
44             =head2 get_ip
45              
46             Returns the requestor's ip address.
47              
48             =cut
49              
50             sub get_ip {
51 0     0 1   my $self = shift;
52 0           return $self->{ip};
53             }
54              
55             =head2 get_datetime_obj
56              
57             Returns a L object of the request datetime.
58              
59             =cut
60              
61             sub get_datetime_obj {
62 0     0 1   my $self = shift;
63 0 0         unless ( exists $self->{datetime_obj} ) {
64 0           my $date_string = substr( $self->{time}, 0, -6 );
65 0           $self->{datetime_obj} =
66             Time::Piece->strptime( $date_string, "%d/%b/%Y:%H:%M:%S" );
67             }
68 0           return $self->{datetime_obj};
69             }
70              
71             =head2 get_timezone
72              
73             Returns the timezone GMT modifier, e.g. -400.
74              
75             =cut
76              
77             sub get_timezone {
78 0     0 1   my $self = shift;
79 0           return substr( $self->{time}, -5 );
80             }
81              
82             =head2 was_robot
83              
84             Returns 1 if the useragent string was a known robot, else returns 0.
85              
86             =cut
87              
88             sub was_robot {
89 0     0 1   my $self = shift;
90 0           return $self->{detector}->robot;
91             }
92              
93             =head2 get_status
94              
95             Returns the http status number of the request.
96              
97             =cut
98              
99             sub get_status {
100 0     0 1   my $self = shift;
101 0           return $self->{status};
102             }
103              
104             =head2 get_request
105              
106             Returns the request string.
107              
108             =cut
109              
110             sub get_request {
111 0     0 1   my $self = shift;
112 0           return $self->{request};
113             }
114              
115             =head2 get_request_type
116              
117             Returns the http request type, e.g. GET.
118              
119             =cut
120              
121             sub get_request_type {
122 0     0 1   my $self = shift;
123 0           my @request = split( ' ', $self->get_request );
124 0           return $request[0];
125             }
126              
127             =head2 get_request_url
128              
129             Returns the requested url (excluding the base).
130              
131             =cut
132              
133             sub get_request_url {
134 0     0 1   my $self = shift;
135 0           my @request = split( ' ', $self->get_request );
136 0           return $request[1];
137             }
138              
139             =head2 get_request_http_version
140              
141             Returns http/1 or http/1.1.
142              
143             =cut
144              
145             sub get_request_http_version {
146 0     0 1   my $self = shift;
147 0           my @request = split( ' ', $self->get_request );
148 0           return $request[2];
149             }
150              
151             =head2 was_request_successful
152              
153             Returns 1 if the http status is a 200 series number (e.g. 200, 201, 202 etc), else returns 0.
154              
155             =cut
156              
157             sub was_request_successful {
158 0     0 1   my $self = shift;
159 0           my $status = $self->get_status;
160 0 0         return substr( $status, 0, 1 ) == 2 ? 1 : 0;
161             }
162              
163             =head2 get_useragent
164              
165             Returns the useragent string.
166              
167             =cut
168              
169             sub get_useragent {
170 0     0 1   my $self = shift;
171 0           return $self->{user_agent};
172             }
173              
174             =head2 get_os
175              
176             Returns the operating system, e.g. Windows.
177              
178             =cut
179              
180             sub get_os {
181 0     0 1   my $self = shift;
182 0           return $self->{detector}->os_string;
183             }
184              
185             =head2 get_browser
186              
187             Returns the browser type, e.g. Firefox.
188              
189             =cut
190              
191             sub get_browser {
192 0     0 1   my $self = shift;
193 0           return $self->{detector}->browser_string;
194             }
195              
196             =head2 get_referer
197              
198             Returns the referer, e.g. google.com.
199              
200             =cut
201              
202             sub get_referer {
203 0     0 1   my $self = shift;
204 0           return $self->{referer};
205             }
206              
207             =head2 get_bytes
208              
209             Returns the number of bytes sent, e.g. 754.
210              
211             =cut
212              
213             sub get_bytes {
214 0     0 1   my $self = shift;
215 0           return $self->{bytes_send};
216             }
217              
218             =head2 get_remote_user
219              
220             Returns the remote username. This is usually not set, and if not, returns '-' instead.
221              
222             =cut
223              
224             sub get_remote_user {
225 0     0 1   my $self = shift;
226 0           return $self->{remote_user};
227             }
228              
229             =head1 AUTHOR
230              
231             David Farrell, C<< >>, L
232              
233             =head1 BUGS
234              
235             Please report any bugs or feature requests to C, or through
236             the web interface at L. I will be notified, and then you'll
237             automatically be notified of progress on your bug as I make changes.
238              
239             =head1 SUPPORT
240              
241             You can find documentation for this module with the perldoc command.
242              
243             perldoc Nginx::Log::Entry
244              
245              
246             You can also look for information at:
247              
248             =over 4
249              
250             =item * RT: CPAN's request tracker (report bugs here)
251              
252             L
253              
254             =item * AnnoCPAN: Annotated CPAN documentation
255              
256             L
257              
258             =item * CPAN Ratings
259              
260             L
261              
262             =item * Search CPAN
263              
264             L
265              
266             =back
267              
268              
269             =head1 ACKNOWLEDGEMENTS
270              
271              
272             =head1 LICENSE AND COPYRIGHT
273              
274             Copyright 2013 David Farrell.
275              
276             This program is free software; you can redistribute it and/or modify it
277             under the terms of the the Artistic License (2.0). You may obtain a
278             copy of the full license at:
279              
280             L
281              
282             Any use, modification, and distribution of the Standard or Modified
283             Versions is governed by this Artistic License. By using, modifying or
284             distributing the Package, you accept this license. Do not use, modify,
285             or distribute the Package, if you do not accept this license.
286              
287             If your Modified Version has been derived from a Modified Version made
288             by someone other than you, you are nevertheless required to ensure that
289             your Modified Version complies with the requirements of this license.
290              
291             This license does not grant you the right to use any trademark, service
292             mark, tradename, or logo of the Copyright Holder.
293              
294             This license includes the non-exclusive, worldwide, free-of-charge
295             patent license to make, have made, use, offer to sell, sell, import and
296             otherwise transfer the Package with respect to any patent claims
297             licensable by the Copyright Holder that are necessarily infringed by the
298             Package. If you institute patent litigation (including a cross-claim or
299             counterclaim) against any party alleging that the Package constitutes
300             direct or contributory patent infringement, then this Artistic License
301             to you shall terminate on the date that such litigation is filed.
302              
303             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
304             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
305             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
306             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
307             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
308             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
309             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
310             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
311              
312             =cut
313              
314             1;