in reply to Why can't some of my modules do log output to a file?

it should work, right?

In addition to the comments by the others, I would suggest using flock, turning on Data::Dumper's Useqq option, and adding more error checking.

use warnings; use strict; use Fcntl qw/:flock/; use Data::Dumper; sub write_log { my ($file, $obj) = @_; open my $fh, '>>', $file or die "open $file: $!"; flock($fh, LOCK_EX) or die "flock $file: $!"; print {$fh} Data::Dumper->new([$obj])->Useqq(1)->Dump or die "print $file: $!"; close $fh or die "close $file: $!"; } write_log("/tmp/log.txt", {hello=>"world"});

If that didn't work or die, personally I would assume the code really wasn't being run, or perhaps that some other process was messing with the logfile. (Note it's been a while since I've used flock on Windows, but I assume you're on *NIX based on your filename.)

There's definitely nothing wrong with the logfile

Well now that you've said that, I have to ask ;-) Are you sure? SELinux? Are all the processes spawned by the script running as the same user?

Replies are listed 'Best First'.
Re^2: Why can't some of my modules do log output to a file?
by LanX (Saint) on Oct 10, 2022 at 13:29 UTC
    I'm wondering if it's efficient to open close the file each time, the handle could be kept in the closure.

    And flock would cover problems with concurrent use.

    Although ... IIRC there are also OS dependencies to consider.

    Cheers Rolf
    (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
    Wikisyntax for the Monastery

      I'm wondering if it's efficient to open close the file each time, the handle could be kept in the closure. And flock would cover problems with concurrent use.

      Opening and closing each time is indeed less efficient. Keeping the file open would require a lock-seek-write-flush-unlock sequence, which introduces more complexity, and given that the OP is debugging "weird" behavior, I thought it best to give the simpler, albeit less efficient, method that uses only simple filesystem operations. I perhaps should have clairifed that my suggestion is one for debugging and not for high-performance logging. (Also, I seem to remember that keeping the file open does not work on Windows when multiple processes are accessing it, though I'm not yet sure whether that's the case here.)

        Instead of closing the file handle, you could just release the lock.  flock $fh, LOCK_UN or die "flock can't release lock $!";

        Note from the docs: "To avoid the possibility of miscoordination, Perl now flushes FILEHANDLE before locking or unlocking it."
        So, lock, write, unlock will cause 2 flushes. There is no need to explicitly seek or flush.

Re^2: Why can't some of my modules do log output to a file?
by eyepopslikeamosquito (Archbishop) on Oct 11, 2022 at 10:23 UTC

    I would suggest using flock, turning on Data::Dumper's Useqq option, and adding more error checking

    Excellent advice! Whenever I use logging for troubleshooting, as a matter of reflex, I tend to further turn on autoflush on the logfile.

    BTW, in addition to providing portable locking across Unix and Windows, flock enriches Perl poems, as demonstrated by pjf in this immortal line:

    join flock($other,@chickens) if split /from others/;
    from his classic Perl poem my @chickens.

Re^2: Why can't some of my modules do log output to a file?
by LittleJack (Beadle) on Oct 12, 2022 at 01:06 UTC

    Hi, thanks for your reply. I don't really understand what the Useqq option does for me in this instance? Are you assuming there might be problematic characters in the output causing this unusual behaviour?

      I don't really understand what the Useqq option does for me in this instance?

      Without Useqq, the module will output some characters literally, which may cause garbled output and could in theory even cause it to appear that certain log messages weren't being output, e.g. when showing a logfile with cat or tail.

      $ perl -MData::Dumper -e 'print Dumper("Hello,\rWorld!")' World!';'Hello, $ perl -MData::Dumper -e '$Data::Dumper::Useqq=1; print Dumper("Hello, +\rWorld!")' $VAR1 = "Hello,\rWorld!";
      Are you assuming there might be problematic characters in the output causing this unusual behaviour?

      Actually, I think those characters are the least likely explanation, but I wanted to have all bases covered. I'd be much more curious about the results of my other suggestions?

      ... what the Useqq option does for me ... Are you assuming there might be problematic characters in the output ...

      Taking the liberty of responding for haukex: I don't think problematic characters are necessarily assumed to be present, but if they're there, Useqq will help you see them. See also Data::Dump.


      Give a man a fish:  <%-{-{-{-<