Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

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

Report information
The Basics
Id: 108899
Status: resolved
Priority: 0/
Queue: Log-Dispatch

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

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



Subject: How to get atomic writes with Log::Dispatch::File
It seems that writes done from multiple processes to a shared file are only atomic if the file was opened with O_APPEND, at least on Linux and for reasonable string lengths. The attached script seems to confirm this statement --- with '>>' I get always 1000 lines of output, with '>' it's always less than 1000. It would be nice if this could be mentioned in the Log::Dispatch::File documentation. Some pointers about atomic writes: * http://stackoverflow.com/questions/1154446/is-file-append-atomic-in-unix/ * http://article.gmane.org/gmane.linux.kernel/43445 * http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/
Subject: parallel_log_dispatch.pl
#!/usr/bin/perl use strict; use warnings; use autodie; use Parallel::ForkManager; use Log::Dispatch; my $pm = Parallel::ForkManager->new(24); truncate '/tmp/test.out', 0; my $log = Log::Dispatch->new( outputs => [ [ 'File', min_level => 'info', filename => '/tmp/test.out', mode => '>', # try '>' and '>>' newline => 1 ] ], ); for (1..1000) { $pm->start and next; $log->emerg("no " . sprintf("%04d", $_) . ("x"x1024)); $pm->finish; } $pm->wait_all_children; __END__ =pod Check with wc /tmp/test.out Output should be 1000 2000 1032000 /tmp/test.out =cut
On Fri Nov 13 08:42:10 2015, SREZIC wrote: Show quoted text
> It seems that writes done from multiple processes to a shared file are > only atomic if the file was opened with O_APPEND, at least on Linux > and for reasonable string lengths. The attached script seems to > confirm this statement --- with '>>' I get always 1000 lines of > output, with '>' it's always less than 1000. > > It would be nice if this could be mentioned in the Log::Dispatch::File > documentation.
There is another output, Log::Dispatch::File::Locked (https://metacpan.org/pod/Log::Dispatch::File::Locked) that is designed to share a file across processes. I could add a pointer in the File docs to File::Locked.
On 2015-11-13 18:16:28, DROLSKY wrote: Show quoted text
> On Fri Nov 13 08:42:10 2015, SREZIC wrote:
> > It seems that writes done from multiple processes to a shared file > > are > > only atomic if the file was opened with O_APPEND, at least on Linux > > and for reasonable string lengths. The attached script seems to > > confirm this statement --- with '>>' I get always 1000 lines of > > output, with '>' it's always less than 1000. > > > > It would be nice if this could be mentioned in the > > Log::Dispatch::File > > documentation.
> > There is another output, Log::Dispatch::File::Locked > (https://metacpan.org/pod/Log::Dispatch::File::Locked) that is > designed to share a file across processes. > > I could add a pointer in the File docs to File::Locked.
Locking is another possibility. But I think that file locks are less efficient than normal writes in O_APPEND mode (more syscalls involved, more switching between kernel and user space). Probably both approaches should be mentioned.
On Mon Nov 16 09:18:26 2015, SREZIC wrote: Show quoted text
> On 2015-11-13 18:16:28, DROLSKY wrote:
> > On Fri Nov 13 08:42:10 2015, SREZIC wrote:
> > > It seems that writes done from multiple processes to a shared file > > > are > > > only atomic if the file was opened with O_APPEND, at least on Linux > > > and for reasonable string lengths. The attached script seems to > > > confirm this statement --- with '>>' I get always 1000 lines of > > > output, with '>' it's always less than 1000. > > > > > > It would be nice if this could be mentioned in the > > > Log::Dispatch::File > > > documentation.
> > > > There is another output, Log::Dispatch::File::Locked > > (https://metacpan.org/pod/Log::Dispatch::File::Locked) that is > > designed to share a file across processes. > > > > I could add a pointer in the File docs to File::Locked.
> > Locking is another possibility. But I think that file locks are less > efficient than normal writes in O_APPEND mode (more syscalls involved, > more switching between kernel and user space). Probably both > approaches should be mentioned.
Using O_APPEND and making sure that all your writes are under a certain size seems _very_ fragile. I agree that using locks is going to be slower, but it's also not likely to just blow up entirely ;) That said, I think any sane production app should probably be using syslog.