2

I have an API which write logs for every requests. There is also another background task that is running always and uses same logger for logging errors etc. As this process is always running and have a reference to the file, the API actually never gets the permission to write there.

I am using monolog for as logger with 'StreamHandler' handler.

My goal is to use this same log file from both process. How can I achieve it? Is there any easy way with monolog to release access lock on the file after writing something and gain it again just before writing? Thanks.

Rana
  • 5,912
  • 12
  • 58
  • 91
  • You don't really want two separate processes writing to the same file. Either they continually open/lock/write/release/close, or have some external coordination method, they will stomp on each other's toes. – Marc B May 14 '14 at 18:11
  • 1
    Well, so what kind of solution you think will be best? Both side make logs of similar staffs, that's why I wanted to use same log file. – Rana May 14 '14 at 18:16

2 Answers2

1

I've been wondering about this myself; it's surprising how little explicit documentation there is out there given how frequently php is run in a multi-process environment like mod_php.

The most obvious solution is to not leverage the StreamHandler directly and instead rely on syslog or the sort for this. PHP doesn't really handle threading/multi-process support itself, but syslog (and its multiple variants) listen on a socket, have relatively advanced routing capabilities, and are thread-safe.

Since you mentioned you have a background task running and uses the same logger, perhaps you could extend this background process to listen on a socket and be responsible for logging messages from your other processes (or, better, have some other background task(s) for this; SRP exists for a reason).

drobert
  • 1,230
  • 8
  • 21
0

Not 100% accurate, but take a look at this SO answer.

I was curious myself so I wrote the following simple script:

test.php

require_once __DIR__ . '/vendor/autoload.php';

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$log = new Logger( 'Test' . `tasklist | grep php | wc -l` );
$log->pushHandler(new StreamHandler(__DIR__ . '/file.log', Logger::DEBUG));

while ( true ) {
    $log->debug( "This is a single log line" );
}

I ran 8 scripts in parallel on a Win 8.1 Quad-Core machine.

On the first run I got rare hiccups where the newline char would be misplaced, such that you get two log dumps on the same line, and a blank line later one (the newline char).

On the second run I didn't get any hiccup at all.

(*) Note that a single script writes 10000 lines on my machine, so to get a rare hiccup on a 80000 lines per second average (and getting none on the second run) is... pretty not bad.

Cheers.

Community
  • 1
  • 1
AVIDeveloper
  • 2,954
  • 1
  • 25
  • 32