| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | # Log::Rolling | 
| 2 |  |  |  |  |  |  | # Written by Fairlight | 
| 3 |  |  |  |  |  |  | # Copyright 2008-2009, Fairlight Consulting | 
| 4 |  |  |  |  |  |  | # Last Modified:  07/27/09 | 
| 5 |  |  |  |  |  |  | ############################################################################## | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | ########## Initialise. | 
| 8 |  |  |  |  |  |  | ##### Package name. | 
| 9 |  |  |  |  |  |  | package Log::Rolling; | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | ##### Pragmas. | 
| 12 | 2 |  |  | 2 |  | 51094 | use 5.006; | 
|  | 2 |  |  |  |  | 8 |  | 
|  | 2 |  |  |  |  | 362 |  | 
| 13 | 2 |  |  | 2 |  | 15 | use warnings; | 
|  | 2 |  |  |  |  | 5 |  | 
|  | 2 |  |  |  |  | 68 |  | 
| 14 | 2 |  |  | 2 |  | 13 | use strict; | 
|  | 2 |  |  |  |  | 18 |  | 
|  | 2 |  |  |  |  | 92 |  | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | ##### Need a few modules. | 
| 17 | 2 |  |  | 2 |  | 12 | use Fcntl; | 
|  | 2 |  |  |  |  | 4 |  | 
|  | 2 |  |  |  |  | 896 |  | 
| 18 | 2 |  |  | 2 |  | 14 | use Fcntl qw(:seek :flock); | 
|  | 2 |  |  |  |  | 3 |  | 
|  | 2 |  |  |  |  | 323 |  | 
| 19 | 2 |  |  | 2 |  | 110 | use Carp; | 
|  | 2 |  |  |  |  | 5 |  | 
|  | 2 |  |  |  |  | 4287 |  | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | =head1 NAME | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | Log::Rolling - Log to simple and self-limiting logfiles. | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | =head1 VERSION | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | Version 1.02 | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | =cut | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | ##### Set version. | 
| 32 |  |  |  |  |  |  | our $VERSION = '1.02'; | 
| 33 |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | ########## Begin meat of module. | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  | Log::Rolling is a module designed to give programs lightweight, yet | 
| 40 |  |  |  |  |  |  | powerful logging facilities.  One of the primary benefits is that, while the | 
| 41 |  |  |  |  |  |  | logs I be infinitely long and handled by something like C, | 
| 42 |  |  |  |  |  |  | the module is capable of limiting the number of lines in the log in a fashion | 
| 43 |  |  |  |  |  |  | where by the oldest lines roll off to keep the size constant at the maximum | 
| 44 |  |  |  |  |  |  | allowed size, if so tuned. | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | This module is particularly useful when you need to keep logs around for a | 
| 47 |  |  |  |  |  |  | certain amount of available data, but do not need to incur the complexity | 
| 48 |  |  |  |  |  |  | and overhead of using something as heavy as C or other methods | 
| 49 |  |  |  |  |  |  | of archiving.  Since the rolling is built into the logging facility, no | 
| 50 |  |  |  |  |  |  | extra cron jobs or the like are necessary. | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | Data is buffered throughout the run of a program with each call to C. | 
| 53 |  |  |  |  |  |  | Once C is called, that buffer is written to the log file, and the | 
| 54 |  |  |  |  |  |  | log buffer is cleared.  The C method may be called as many times as | 
| 55 |  |  |  |  |  |  | necessary; however, it is best to do so as few times as required due to the | 
| 56 |  |  |  |  |  |  | overhead of file operations involved in rolling the log--hence the reason the | 
| 57 |  |  |  |  |  |  | entries are stored in memory until manually committed in the first place. | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | use Log::Rolling; | 
| 60 |  |  |  |  |  |  | my $log = Log::Rolling->new('/path/to/logfile.txt'); | 
| 61 |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  | # Define the maximum log size in lines.  Default is 0 (infinite). | 
| 63 |  |  |  |  |  |  | $log->max_size(50000); | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | # Add a log entry line. | 
| 66 |  |  |  |  |  |  | $log->entry("Log information string here..."); | 
| 67 |  |  |  |  |  |  |  | 
| 68 |  |  |  |  |  |  | # Commit all log entry lines in memory to file and roll the log lines | 
| 69 |  |  |  |  |  |  | # to accomodate max_size. | 
| 70 |  |  |  |  |  |  | $log->commit; | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | =head1 METHODS | 
| 73 |  |  |  |  |  |  |  | 
| 74 |  |  |  |  |  |  | =head2 new() | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | my $log = Log::Rolling->new('/path/to/logfile.txt'); | 
| 77 |  |  |  |  |  |  | my $log = Log::Rolling->new(log_file => '/path/to/file', | 
| 78 |  |  |  |  |  |  | max_size => 5000, | 
| 79 |  |  |  |  |  |  | wait_attempts => 30, | 
| 80 |  |  |  |  |  |  | wait_interval => 1, | 
| 81 |  |  |  |  |  |  | mode => 0600 | 
| 82 |  |  |  |  |  |  | pid => 1); | 
| 83 |  |  |  |  |  |  |  | 
| 84 |  |  |  |  |  |  | If no logfile is given, or if the logfile is unusable, the constructor | 
| 85 |  |  |  |  |  |  | returns false (0). | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | =cut | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | sub new { | 
| 90 | 2 |  |  | 2 | 1 | 404 | my $class = shift; | 
| 91 | 2 |  |  |  |  | 3 | my $self = {}; | 
| 92 | 2 |  |  |  |  | 5 | ${self}->{'log_file'} = undef; | 
| 93 | 2 |  |  |  |  | 6 | ${self}->{'max_size'} = 0;  # Unlimited by default. | 
| 94 | 2 |  |  |  |  | 4 | ${self}->{'wait_attempts'} = 30; | 
| 95 | 2 |  |  |  |  | 4 | ${self}->{'wait_interval'} = 1; | 
| 96 | 2 |  |  |  |  | 4 | ${self}->{'mode'} = 0600; | 
| 97 | 2 |  |  |  |  | 5 | ${self}->{'acc'} = ''; | 
| 98 | 2 |  |  |  |  | 4 | ${self}->{'pid'} = 0; | 
| 99 | 2 |  |  |  |  | 5 | ${self}->{'roll_allowed'} = 0; | 
| 100 | 2 | 100 |  |  |  | 13 | if (scalar(@_) % 2) { | 
| 101 | 1 | 50 |  |  |  | 9 | ${self}->{'log_file'} = shift if scalar(@_) == 1; | 
| 102 |  |  |  |  |  |  | } else { | 
| 103 | 1 |  |  |  |  | 3 | my %attrs = @_; | 
| 104 | 1 |  |  |  |  | 6 | while (my ($key, $val) = each %attrs) { | 
| 105 | 0 | 0 | 0 |  |  | 0 | if (${key} eq 'log_file') { | 
|  |  | 0 | 0 |  |  |  |  | 
|  |  | 0 | 0 |  |  |  |  | 
|  |  | 0 | 0 |  |  |  |  | 
|  |  | 0 | 0 |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 106 | 0 |  |  |  |  | 0 | ${self}->{'log_file'} = ${val}; | 
| 107 |  |  |  |  |  |  | } elsif (${key} eq 'max_size' and ${val} =~ /^\d+$/) { | 
| 108 | 0 |  |  |  |  | 0 | ${self}->{'max_size'} = ${val}; | 
| 109 |  |  |  |  |  |  | } elsif (${key} eq 'wait_attempts' and ${val} =~ /^\d+$/) { | 
| 110 | 0 |  |  |  |  | 0 | ${self}->{'wait_attempts'} = ${val}; | 
| 111 |  |  |  |  |  |  | } elsif (${key} eq 'wait_interval' and ${val} =~ /^\d+$/) { | 
| 112 | 0 |  |  |  |  | 0 | ${self}->{'wait_interval'} = ${val}; | 
| 113 |  |  |  |  |  |  | } elsif (${key} eq 'pid' and ${val} =~ /^(?:0|1)$/) { | 
| 114 | 0 |  |  |  |  | 0 | ${self}->{'pid'} = ${val}; | 
| 115 |  |  |  |  |  |  | } elsif (${key} eq 'mode' and ${val} =~ /^\d{4}$/) { | 
| 116 | 0 |  |  |  |  | 0 | ${self}->{'mode'} = ${val}; | 
| 117 |  |  |  |  |  |  | } | 
| 118 |  |  |  |  |  |  | } | 
| 119 |  |  |  |  |  |  | } | 
| 120 | 2 | 100 |  |  |  | 10 | return(0) unless defined(${self}->{'log_file'}); | 
| 121 | 1 | 50 |  |  |  | 129 | if (not sysopen(LOG,${self}->{'log_file'},O_CREAT|O_WRONLY,${self}->{'mode'})) { | 
| 122 | 0 |  |  |  |  | 0 | return(0); | 
| 123 |  |  |  |  |  |  | } else { | 
| 124 | 1 | 50 |  |  |  | 14 | close(LOG) or croak('Could not close log file.'); | 
| 125 |  |  |  |  |  |  | } | 
| 126 | 1 |  |  |  |  | 3 | bless(${self},${class}); | 
| 127 | 1 |  |  |  |  | 3 | return(${self}); | 
| 128 |  |  |  |  |  |  | } | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | =head2 log_file() | 
| 131 |  |  |  |  |  |  |  | 
| 132 |  |  |  |  |  |  | This method defines the path of the logfile.  Returns the value of the | 
| 133 |  |  |  |  |  |  | logfile, or false (0) if the logfile is unusable. | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | =cut | 
| 136 |  |  |  |  |  |  |  | 
| 137 |  |  |  |  |  |  | sub log_file { | 
| 138 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 139 | 0 | 0 |  |  |  | 0 | if (@_) { | 
| 140 | 0 |  |  |  |  | 0 | ${self}->{'log_file'} = shift; | 
| 141 |  |  |  |  |  |  | } | 
| 142 | 0 | 0 |  |  |  | 0 | if (not sysopen(LOG,${self}->{'log_file'},O_CREAT|O_WRONLY,${self}->{'mode'})) { | 
| 143 | 0 |  |  |  |  | 0 | return(0); | 
| 144 |  |  |  |  |  |  | } else { | 
| 145 | 0 | 0 |  |  |  | 0 | close(LOG) or croak('Could not close log file.'); | 
| 146 |  |  |  |  |  |  | } | 
| 147 | 0 |  |  |  |  | 0 | return(${self}->{'log_file'}); | 
| 148 |  |  |  |  |  |  | } | 
| 149 |  |  |  |  |  |  |  | 
| 150 |  |  |  |  |  |  | =head2 max_size() | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  | This method sets the maximum size of the logfile in lines.  The size | 
| 153 |  |  |  |  |  |  | is infinite (0) unless this method is called, or unless the size was | 
| 154 |  |  |  |  |  |  | defined using C.  Returns the maximum size. | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | =cut | 
| 157 |  |  |  |  |  |  |  | 
| 158 |  |  |  |  |  |  | sub max_size { | 
| 159 | 1 |  |  | 1 | 1 | 323 | my $self = shift; | 
| 160 | 1 | 50 |  |  |  | 4 | if (@_) { | 
| 161 | 1 |  |  |  |  | 3 | ${self}->{'max_size'} = shift; | 
| 162 |  |  |  |  |  |  | } | 
| 163 | 1 | 50 | 33 |  |  | 12 | ${self}->{'max_size'} = 0, return(0) if defined(${self}->{'max_size'}) and ${self}->{'max_size'} !~ /^\d+$/; | 
| 164 | 1 |  |  |  |  | 5 | return(${self}->{'max_size'}); | 
| 165 |  |  |  |  |  |  | } | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | =head2 wait_attempts() | 
| 168 |  |  |  |  |  |  |  | 
| 169 |  |  |  |  |  |  | This method sets the maximum number of attempts to wait for a lock on | 
| 170 |  |  |  |  |  |  | the logfile.  Returns the maximum wait attempt setting. | 
| 171 |  |  |  |  |  |  |  | 
| 172 |  |  |  |  |  |  | =cut | 
| 173 |  |  |  |  |  |  |  | 
| 174 |  |  |  |  |  |  | sub wait_attempts { | 
| 175 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 176 | 0 | 0 |  |  |  | 0 | if (@_) { | 
| 177 | 0 |  |  |  |  | 0 | ${self}->{'wait_attempts'} = shift; | 
| 178 |  |  |  |  |  |  | } | 
| 179 | 0 | 0 | 0 |  |  | 0 | ${self}->{'wait_attempts'} = 30, return(0) if defined(${self}->{'wait_attempts'}) and ${self}->{'wait_attempts'} !~ /^\d+$/; | 
| 180 | 0 |  |  |  |  | 0 | return(${self}->{'wait_attempts'}); | 
| 181 |  |  |  |  |  |  | } | 
| 182 |  |  |  |  |  |  |  | 
| 183 |  |  |  |  |  |  | =head2 wait_interval() | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | This method sets the interval in seconds between attempts to wait for | 
| 186 |  |  |  |  |  |  | a lock on the logfile.  Returns the wait interval setting. | 
| 187 |  |  |  |  |  |  |  | 
| 188 |  |  |  |  |  |  | =cut | 
| 189 |  |  |  |  |  |  |  | 
| 190 |  |  |  |  |  |  | sub wait_interval { | 
| 191 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 192 | 0 | 0 |  |  |  | 0 | if (@_) { | 
| 193 | 0 |  |  |  |  | 0 | ${self}->{'wait_interval'} = shift; | 
| 194 |  |  |  |  |  |  | } | 
| 195 | 0 | 0 | 0 |  |  | 0 | ${self}->{'wait_interval'} = 1, return(0) if defined(${self}->{'wait_interval'}) and ${self}->{'wait_interval'} !~ /^\d+$/; | 
| 196 | 0 |  |  |  |  | 0 | return(${self}->{'wait_interval'}); | 
| 197 |  |  |  |  |  |  | } | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | =head2 mode() | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | This method sets the file mode to be used when creating the log file | 
| 202 |  |  |  |  |  |  | if the file does not yet exist.  The value should be an octal value | 
| 203 |  |  |  |  |  |  | (e.g., 0644).  Returns the file mode. | 
| 204 |  |  |  |  |  |  |  | 
| 205 |  |  |  |  |  |  | =cut | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | sub mode { | 
| 208 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 209 | 0 | 0 |  |  |  | 0 | if (@_) { | 
| 210 | 0 |  |  |  |  | 0 | ${self}->{'mode'} = shift; | 
| 211 |  |  |  |  |  |  | } | 
| 212 | 0 | 0 | 0 |  |  | 0 | ${self}->{'mode'} = 0600, return(0) if defined(${self}->{'mode'}) and ${self}->{'mode'} !~ /^\d{4}$/; | 
| 213 | 0 |  |  |  |  | 0 | return(${self}->{'mode'}); | 
| 214 |  |  |  |  |  |  | } | 
| 215 |  |  |  |  |  |  |  | 
| 216 |  |  |  |  |  |  | =head2 pid() | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  | This method sets whether the process ID will be recorded in the log | 
| 219 |  |  |  |  |  |  | entry.  Enable PID with 1, disable with 0.  Returns the value of the | 
| 220 |  |  |  |  |  |  | setting. | 
| 221 |  |  |  |  |  |  |  | 
| 222 |  |  |  |  |  |  | =cut | 
| 223 |  |  |  |  |  |  |  | 
| 224 |  |  |  |  |  |  | sub pid { | 
| 225 | 1 |  |  | 1 | 1 | 2 | my $self = shift; | 
| 226 | 1 | 50 |  |  |  | 5 | if (@_) { | 
| 227 | 1 |  |  |  |  | 2 | my $pset = shift; | 
| 228 | 1 | 50 |  |  |  | 9 | ${self}->{'pid'} = ${pset} if ${pset} =~ /^(?:0|1)$/; | 
| 229 |  |  |  |  |  |  | } | 
| 230 | 1 |  |  |  |  | 5 | return(${self}->{'pid'}); | 
| 231 |  |  |  |  |  |  | } | 
| 232 |  |  |  |  |  |  |  | 
| 233 |  |  |  |  |  |  | =head2 entry() | 
| 234 |  |  |  |  |  |  |  | 
| 235 |  |  |  |  |  |  | Adds an entry to the log file accumulation buffer B.  No | 
| 236 |  |  |  |  |  |  | entries are ever written to disk unless and until C is | 
| 237 |  |  |  |  |  |  | called. | 
| 238 |  |  |  |  |  |  |  | 
| 239 |  |  |  |  |  |  | =cut | 
| 240 |  |  |  |  |  |  |  | 
| 241 |  |  |  |  |  |  | sub entry { | 
| 242 | 2 |  |  | 2 | 1 | 4 | my $self = shift; | 
| 243 | 2 |  |  |  |  | 7 | my $pid = "[$$] - "; | 
| 244 | 2 | 100 |  |  |  | 8 | $pid = '' unless ${self}->{'pid'}; | 
| 245 | 2 | 50 |  |  |  | 7 | if (@_) { | 
| 246 | 2 |  |  |  |  | 7 | my @entries = @_; | 
| 247 | 2 |  |  |  |  | 4 | foreach my $item (@entries) { | 
| 248 | 10 |  |  |  |  | 18 | chomp(${item}); | 
| 249 | 10 |  |  |  |  | 393 | ${self}->{'acc'} .= scalar(localtime(time)). ": ${pid}" . ${item} . "\n"; | 
| 250 |  |  |  |  |  |  | } | 
| 251 |  |  |  |  |  |  | } | 
| 252 | 2 |  |  |  |  | 10 | return(1); | 
| 253 |  |  |  |  |  |  | } | 
| 254 |  |  |  |  |  |  |  | 
| 255 |  |  |  |  |  |  | =head2 commit() | 
| 256 |  |  |  |  |  |  |  | 
| 257 |  |  |  |  |  |  | Commits the current log file data in memory to the actual file on | 
| 258 |  |  |  |  |  |  | disk, and clears the log accumulation buffer. | 
| 259 |  |  |  |  |  |  |  | 
| 260 |  |  |  |  |  |  | =cut | 
| 261 |  |  |  |  |  |  |  | 
| 262 |  |  |  |  |  |  | sub commit { | 
| 263 | 2 |  |  | 2 | 1 | 4 | my $self = shift; | 
| 264 | 2 | 50 |  |  |  | 8 | return(0) unless defined(${self}->{'log_file'}); | 
| 265 | 2 |  |  |  |  | 4 | my $track_waits = 0; | 
| 266 | 2 |  |  |  |  | 21 | my $fres = 0; | 
| 267 | 2 | 50 |  |  |  | 73 | sysopen(LOG,${self}->{'log_file'},O_RDWR|O_CREAT|O_APPEND,${self}->{'mode'}) or croak('Could not open log file.'); | 
| 268 | 2 |  |  |  |  | 8 | my $switchhandle = select(LOG); | 
| 269 | 2 |  |  |  |  | 6 | $| = 1; | 
| 270 | 2 |  |  |  |  | 7 | select(${switchhandle}); | 
| 271 | 2 |  |  |  |  | 4 | ${self}->{'roll_allowed'} = 1; | 
| 272 | 2 |  |  |  |  | 16 | $fres = flock(LOG,LOCK_EX|LOCK_NB); | 
| 273 | 2 |  | 33 |  |  | 9 | while (${fres} != 1 and ${track_waits} < ${self}->{'wait_attempts'}) { | 
| 274 | 0 |  |  |  |  | 0 | sleep(${self}->{'wait_interval'}); | 
| 275 | 0 |  |  |  |  | 0 | $track_waits++; | 
| 276 | 0 |  |  |  |  | 0 | $fres = flock(LOG,LOCK_EX|LOCK_NB); | 
| 277 |  |  |  |  |  |  | } | 
| 278 | 2 | 50 |  |  |  | 8 | croak('Could not lock log file.') if ${track_waits} == ${self}->{'wait_attempts'}; | 
| 279 | 2 |  |  |  |  | 97 | print LOG (${self}->{'acc'}); | 
| 280 | 2 |  |  |  |  | 5 | ${self}->{'acc'} = ''; | 
| 281 | 2 | 50 | 33 |  |  | 41 | &roll(${self}) if defined(${self}->{'max_size'}) and ${self}->{'max_size'} =~ /^\d+$/ and ${self}->{'max_size'} > 0; | 
|  |  |  | 33 |  |  |  |  | 
| 282 | 2 |  |  |  |  | 5 | ${self}->{'roll_allowed'} = 0; | 
| 283 | 2 | 50 |  |  |  | 17 | flock(LOG,LOCK_UN) or croak('Could not unlock log file.') | 
| 284 |  |  |  |  |  |  | ; | 
| 285 | 2 | 50 |  |  |  | 26 | close(LOG) or croak('Could not close log file.'); | 
| 286 | 2 |  |  |  |  | 9 | return(1); | 
| 287 |  |  |  |  |  |  | } | 
| 288 |  |  |  |  |  |  |  | 
| 289 |  |  |  |  |  |  | =head2 roll() | 
| 290 |  |  |  |  |  |  |  | 
| 291 |  |  |  |  |  |  | This method rolls the oldest entries out of the logfile and leaves | 
| 292 |  |  |  |  |  |  | only up to max_size lines (or less, if the contents are not that | 
| 293 |  |  |  |  |  |  | long) within the logfile.  Returns true (1) if log was successfully | 
| 294 |  |  |  |  |  |  | rolled, or false (0) if it was not.  B | 
| 295 |  |  |  |  |  |  | called independantly.  Doing so will simply return false (0).> | 
| 296 |  |  |  |  |  |  |  | 
| 297 |  |  |  |  |  |  | =cut | 
| 298 |  |  |  |  |  |  |  | 
| 299 |  |  |  |  |  |  | sub roll { | 
| 300 | 3 |  |  | 3 | 1 | 4 | my $self = shift; | 
| 301 | 3 | 100 |  |  |  | 13 | return(0) unless ${self}->{'roll_allowed'}; | 
| 302 | 2 |  |  |  |  | 3 | my (@loglines,$line); | 
| 303 | 2 | 50 |  |  |  | 18 | seek(LOG,0,SEEK_SET) or croak('Unable to seek to zero to roll logfile.'); | 
| 304 | 2 |  |  |  |  | 55 | @loglines = ; | 
| 305 | 2 | 50 |  |  |  | 11 | seek(LOG,0,SEEK_END), return(0) if not defined(${self}->{'log_file'}); | 
| 306 | 2 | 100 |  |  |  | 13 | seek(LOG,0,SEEK_END), return(0) if scalar(@loglines) < ${self}->{'max_size'}; | 
| 307 | 1 |  |  |  |  | 3 | my $length_delete_log = (scalar(@loglines)-${self}->{'max_size'}); | 
| 308 | 1 |  |  |  |  | 5 | splice(@loglines,0,${length_delete_log}); | 
| 309 | 1 | 50 |  |  |  | 71 | truncate(LOG,0) or croak('Unable to truncate while rolling logfile.') | 
| 310 |  |  |  |  |  |  | ; | 
| 311 | 1 | 50 |  |  |  | 9 | seek(LOG,0,SEEK_SET) or croak('Unable to seek to zero after truncation while rolling logfile.'); | 
| 312 | 1 |  |  |  |  | 31 | print LOG (@loglines); | 
| 313 | 1 |  |  |  |  | 15 | return(1); | 
| 314 |  |  |  |  |  |  | } | 
| 315 |  |  |  |  |  |  |  | 
| 316 |  |  |  |  |  |  | =head2 clear() | 
| 317 |  |  |  |  |  |  |  | 
| 318 |  |  |  |  |  |  | This method clears the buffered log entries B writing them | 
| 319 |  |  |  |  |  |  | to file, should it be deemed necessary to "revoke" log entries | 
| 320 |  |  |  |  |  |  | already made but not yet committed to file.  Returns true (1). | 
| 321 |  |  |  |  |  |  |  | 
| 322 |  |  |  |  |  |  | =cut | 
| 323 |  |  |  |  |  |  |  | 
| 324 |  |  |  |  |  |  | sub clear { | 
| 325 | 0 |  |  | 0 | 1 |  | my $self = shift; | 
| 326 | 0 |  |  |  |  |  | ${self}->{'acc'} = ''; | 
| 327 | 0 |  |  |  |  |  | return(1); | 
| 328 |  |  |  |  |  |  | } | 
| 329 |  |  |  |  |  |  |  | 
| 330 |  |  |  |  |  |  | =head1 AUTHOR | 
| 331 |  |  |  |  |  |  |  | 
| 332 |  |  |  |  |  |  | Mark Luljak, | 
| 333 |  |  |  |  |  |  |  | 
| 334 |  |  |  |  |  |  | Fairlight Consulting - L | 
| 335 |  |  |  |  |  |  |  | 
| 336 |  |  |  |  |  |  | =head1 BUGS | 
| 337 |  |  |  |  |  |  |  | 
| 338 |  |  |  |  |  |  | Please report any bugs or feature requests to C, or through | 
| 339 |  |  |  |  |  |  | the web interface at L.  I will be notified, and then you'll | 
| 340 |  |  |  |  |  |  | automatically be notified of progress on your bug as I make changes. | 
| 341 |  |  |  |  |  |  |  | 
| 342 |  |  |  |  |  |  |  | 
| 343 |  |  |  |  |  |  |  | 
| 344 |  |  |  |  |  |  |  | 
| 345 |  |  |  |  |  |  | =head1 SUPPORT | 
| 346 |  |  |  |  |  |  |  | 
| 347 |  |  |  |  |  |  | You can find documentation for this module with the perldoc command. | 
| 348 |  |  |  |  |  |  |  | 
| 349 |  |  |  |  |  |  | perldoc Log::Rolling | 
| 350 |  |  |  |  |  |  |  | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  | You can also look for information at: | 
| 353 |  |  |  |  |  |  |  | 
| 354 |  |  |  |  |  |  | =over 5 | 
| 355 |  |  |  |  |  |  |  | 
| 356 |  |  |  |  |  |  | =item * RT: CPAN's request tracker | 
| 357 |  |  |  |  |  |  |  | 
| 358 |  |  |  |  |  |  | L | 
| 359 |  |  |  |  |  |  |  | 
| 360 |  |  |  |  |  |  | =item * AnnoCPAN: Annotated CPAN documentation | 
| 361 |  |  |  |  |  |  |  | 
| 362 |  |  |  |  |  |  | L | 
| 363 |  |  |  |  |  |  |  | 
| 364 |  |  |  |  |  |  | =item * CPAN Ratings | 
| 365 |  |  |  |  |  |  |  | 
| 366 |  |  |  |  |  |  | L | 
| 367 |  |  |  |  |  |  |  | 
| 368 |  |  |  |  |  |  | =item * Search CPAN | 
| 369 |  |  |  |  |  |  |  | 
| 370 |  |  |  |  |  |  | L | 
| 371 |  |  |  |  |  |  |  | 
| 372 |  |  |  |  |  |  | =back | 
| 373 |  |  |  |  |  |  |  | 
| 374 |  |  |  |  |  |  | =head1 COPYRIGHT & LICENSE | 
| 375 |  |  |  |  |  |  |  | 
| 376 |  |  |  |  |  |  | Copyright 2008-2009 Mark Luljak, all rights reserved. | 
| 377 |  |  |  |  |  |  |  | 
| 378 |  |  |  |  |  |  | This program is free software; you can redistribute it and/or modify it | 
| 379 |  |  |  |  |  |  | under the same terms as Perl itself. | 
| 380 |  |  |  |  |  |  |  | 
| 381 |  |  |  |  |  |  |  | 
| 382 |  |  |  |  |  |  | =cut | 
| 383 |  |  |  |  |  |  |  | 
| 384 |  |  |  |  |  |  | 1; # End of Log::Rolling |