Skip Menu |
 

This queue is for tickets about the Log-Dispatch-File-Rolling CPAN distribution.

Report information
The Basics
Id: 95900
Status: open
Priority: 0/
Queue: Log-Dispatch-File-Rolling

People
Owner: Nobody in particular
Requestors: FRACTAL [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: (no value)



Subject: Feature request: Maintain a current symlink to latest log file
Download (untitled) / with headers
text/plain 681b
First off, thanks for this module. We've used to generate many many gigs of logs. However, most of the other logging systems we've used maintain a ".current" symlink to the latest log file. This is handy because you can do "tail -F app.current" and see an uninterrupted tail of the logs without worrying about rollovers. I would really appreciate it if Log::Dispatch::File::Rolling could do something similar so I'm attaching a patch that adds this feature. If you feel that this is at the wrong layer, no worries. I'll make a module that sub-classes your module. It feels like it makes sense here though since it's related to the "rolling" aspect of the logging. Cheers, Doug
Subject: current-symlink.patch
diff --git a/lib/Log/Dispatch/File/Rolling.pm b/lib/Log/Dispatch/File/Rolling.pm index 2928c1e..957deba 100755 --- a/lib/Log/Dispatch/File/Rolling.pm +++ b/lib/Log/Dispatch/File/Rolling.pm @@ -62,6 +62,10 @@ sub new { $self->{filename} = $self->_createFilename(); } + if (exists $p{current_symlink}) { + $self->{current_symlink} = $p{current_symlink}; + } + $self->{rolling_fh_pid} = $$; $self->_make_handle(); @@ -79,7 +83,7 @@ sub log_message { # parts borrowed from Log::Dispatch::FileRotate, Thanks! } if ( $self->{close} ) { - $self->_open_file; + $self->_rolling_open_file; $self->_lock(); my $fh = $self->{fh}; print $fh $p{message}; @@ -90,7 +94,9 @@ sub log_message { # parts borrowed from Log::Dispatch::FileRotate, Thanks! my $inode = (stat($self->{fh}))[1]; # get real inode my $finode = (stat($self->{filename}))[1]; # Stat the name for comparision if(!defined($finode) || $inode != $finode) { # Oops someone moved things on us. So just reopen our log - $self->_open_file; + $self->_rolling_open_file; + } elsif (!$self->{current_symlink_inited}) { + $self->_update_current_symlink; } $self->_lock(); my $fh = $self->{fh}; @@ -98,7 +104,7 @@ sub log_message { # parts borrowed from Log::Dispatch::FileRotate, Thanks! $self->_unlock(); } else { $self->{rolling_fh_pid} = $$; - $self->_open_file; + $self->_rolling_open_file; $self->_lock(); my $fh = $self->{fh}; print $fh $p{message}; @@ -106,6 +112,37 @@ sub log_message { # parts borrowed from Log::Dispatch::FileRotate, Thanks! } } +sub _rolling_open_file { + my $self = shift; + + $self->_open_file; + + $self->_update_current_symlink; +} + +sub _update_current_symlink { + my $self = shift; + + return if !exists $self->{current_symlink}; + + my $current_symlink_value = readlink($self->{current_symlink}); + + if (!defined $current_symlink_value || $current_symlink_value ne $self->{filename}) { + my $temp_symlink_file = "$self->{current_symlink}.temp$$"; + unlink($temp_symlink_file); + + symlink($self->{filename}, $temp_symlink_file) + || die "unable to create symlink '$temp_symlink_file': $!"; + + if (!rename($temp_symlink_file, $self->{current_symlink})) { + unlink($temp_symlink_file); + die "unable to overwrite symlink '$self->{current_symlink}': $!"; + } + } + + $self->{current_symlink_inited} = 1; +} + sub _lock { # borrowed from Log::Dispatch::FileRotate, Thanks! my $self = shift; flock($self->{fh},LOCK_EX); @@ -207,6 +244,13 @@ needed regularly as this module also supports logfile sharing between processes, but if you've got a high load on your logfile or a system that doesn't support flock()... +=item current symlinks + +If you pass in C<current_symlink> to the constructor, it will create a +symlink at your provided filename. This symlink will always link to the +most recent log file. You can then use C<tail -F> to monitor an application's +logs with no interruptions even when the filename rolls over. + =back =head1 METHODS diff --git a/t/6currentsymlink.t b/t/6currentsymlink.t new file mode 100755 index 0000000..ce81c4e --- /dev/null +++ b/t/6currentsymlink.t @@ -0,0 +1,89 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl 6currentsymlink.t' + +######################### + +# change 'tests => 1' to 'tests => last_test_to_print'; + +use Test; +BEGIN { plan tests => 9 }; +use Log::Dispatch; +use Log::Dispatch::File::Rolling; +ok(1); # If we made it this far, we're ok. + +#########################1 + +my $dispatcher = Log::Dispatch->new; +ok($dispatcher); + +#########################2 + +my $curr_symlink_filename = 'currsym'; + +my %params = ( + name => 'file', + min_level => 'debug', + filename => 'logfile', + current_symlink => $curr_symlink_filename, +); + +my $Rolling = Log::Dispatch::File::Rolling->new(%params); +ok($Rolling); + +#########################3 + +$dispatcher->add($Rolling); + +ok(1); + +#########################4 + +my $message = 'logtest id ' . int(rand(9999)); + +$dispatcher->log( level => 'info', message => $message ); + +ok(1); + +#########################5 + +$dispatcher = $Rolling = undef; + +ok(1); + +#########################6 + +my @logfiles = glob("logfile.2*"); + +ok(scalar(@logfiles) == 1 or scalar(@logfiles) == 2); + +#########################7 + +my $content = ''; + +foreach my $file (@logfiles) { + open F, '<', $file; + local $/ = undef; + $content .= <F>; + close F; +} + +ok($content =~ /$message/); + +my $content2 = ''; + +{ + open F, '<', $curr_symlink_filename; + local $/ = undef; + $content2 .= <F>; + close F; +} + +ok($content2 =~ /$message/); + +foreach my $file (@logfiles) { + unlink $file; +} + +unlink $curr_symlink_filename; + +#########################8
Download (untitled) / with headers
text/plain 281b
On 2014-05-23 10:03:04, FRACTAL wrote: Show quoted text
> First off, thanks for this module. We've used to generate many many > gigs of logs.
FWIW, you might find Log-Dispatch-File-Stamped to be useful too - it takes a slightly different approach, and supports all the Log::Dispatch::File options.
Download (untitled) / with headers
text/plain 250b
Thanks for the pointer, I'll check it out. On Fri May 23 14:00:47 2014, ETHER wrote: Show quoted text
> FWIW, you might find Log-Dispatch-File-Stamped to be useful too - it > takes a slightly different approach, and supports all the > Log::Dispatch::File options.
Download (untitled) / with headers
text/plain 333b
On Fri May 23 13:03:04 2014, FRACTAL wrote: Show quoted text
> First off, thanks for this module. We've used to generate many many > gigs of logs.
Thank you for using it! I like the idea. I'll integrate your patch into the next version. However, I want to go through the patch before I do, so it'll take at least 2 weeks for me to have the time...
Download (untitled) / with headers
text/plain 560b
On Fri May 23 14:00:47 2014, ETHER wrote: Show quoted text
> FWIW, you might find Log-Dispatch-File-Stamped to be useful too - it > takes a slightly different approach, and supports all the > Log::Dispatch::File options.
Actually, if you look at the bottom if Log::Dispatch::File::Rolling's documentation you'll find "Based on: Log::Dispatch::File::Stamped [...]"... ;) I haven't check how Log::Dispatch::File::Stamped changed since 2003, but I implemented ::Rolling because ::Stamped missed some features we needed. I may be wrong, but I think it still is not fork()-safe.
Download (untitled) / with headers
text/plain 459b
No worries, thanks for looking at it when you get a chance. On Fri May 23 14:41:56 2014, JACOB wrote: Show quoted text
> On Fri May 23 13:03:04 2014, FRACTAL wrote:
> > First off, thanks for this module. We've used to generate many many > > gigs of logs.
> > Thank you for using it! > > I like the idea. I'll integrate your patch into the next version. > > However, I want to go through the patch before I do, so it'll take at > least 2 weeks for me to have the time...
Download (untitled) / with headers
text/plain 1.5k
I didn't really want to add yet another file logging module to CPAN so I'm sorry to say I have forked this module: https://metacpan.org/release/FRACTAL/Log-File-Rolling-0.100 My main reasons were the lack of the symlink feature I described in this ticket, the bug where an unformatted log filename (with the % characters) is created alongside your logs (which is embarrassing to explain to operations), and getting away from Log::Dispatch/Log4Perl bloat... ETHER: I checked out Log::Dispatch::File::Stamped, but I don't think it provides the symlink feature I described in this ticket. How do you handle the "I just want to tail -F this app's logs and not worry about roll-overs" issue, or does this just not come up in your workflow? I do like the filename caching in ::Stamped and I implemented similar in mine. I also like that you're using standard strftime not the zany Log4Perl format. I chose to use Time::Piece instead of POSIX for strftime since the POSIX module is pretty memory heavy. Cheers, Doug On Mon May 26 09:46:21 2014, FRACTAL wrote: Show quoted text
> No worries, thanks for looking at it when you get a chance. > > On Fri May 23 14:41:56 2014, JACOB wrote:
> > On Fri May 23 13:03:04 2014, FRACTAL wrote:
> > > First off, thanks for this module. We've used to generate many many > > > gigs of logs.
> > > > Thank you for using it! > > > > I like the idea. I'll integrate your patch into the next version. > > > > However, I want to go through the patch before I do, so it'll take at > > least 2 weeks for me to have the time...
> >


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.