更新、2013 年 9 月 12 日:
私はもう少し深く掘り下げました.systemd
そしてjournal
、私はこれに出くわしました.それは次のように述べています:
systemd-journald
受信したすべてのログ メッセージをAF_UNIX SOCK_DGRAM
ソケット/run/systemd/journal/syslog
(存在する場合) に転送します。これは、データをさらに処理するために Unix syslog デーモンによって使用される可能性があります。
マンページに従って、下にsyslogも配置するように環境をセットアップしました。それに応じてコードを調整しました。
define('NL', "\n\r");
$log = function ()
{
if (func_num_args() >= 1)
{
$message = call_user_func_array('sprintf', func_get_args());
echo '[' . date('r') . '] ' . $message . NL;
}
};
$syslog = '/var/run/systemd/journal/syslog';
$sock = socket_create(AF_UNIX, SOCK_DGRAM, 0);
$connection = socket_connect($sock, $syslog);
if (!$connection)
{
$log('Couldn\'t connect to ' . $syslog);
}
else
{
$log('Connected to ' . $syslog);
$readables = array($sock);
socket_set_nonblock($sock);
while (true)
{
$read = $readables;
$write = $readables;
$except = $readables;
$select = socket_select($read, $write, $except, 0);
$log('Changes: %d.', $select);
$log('-------');
$log('Read: %d.', count($read));
$log('Write: %d.', count($write));
$log('Except: %d.', count($except));
if ($select > 0)
{
if ($read)
{
foreach ($read as $readable)
{
$data = socket_read($readable, 4096, PHP_BINARY_READ);
if ($data === false)
{
$log(socket_last_error() . ': ' . socket_strerror(socket_last_error()));
}
else if (!empty($data))
{
$log($data);
}
else
{
$log('Read empty.');
}
}
}
if ($write)
{
foreach ($write as $writable)
{
$data = socket_read($writable, 4096, PHP_BINARY_READ);
if ($data === false)
{
$log(socket_last_error() . ': ' . socket_strerror(socket_last_error()));
}
else if (!empty($data))
{
$log($data);
}
else
{
$log('Write empty.');
}
}
}
}
}
}
write
これは明らかに、ソケットの変更のみを表示 (選択) します。まあ、ここで何かが間違っているかもしれないので、私はそれらから読み込もうとしましたが、運がありません(また、あるべきではありません):
[Thu, 12 Sep 2013 14:45:15 +0300] Changes: 1.
[Thu, 12 Sep 2013 14:45:15 +0300] -------
[Thu, 12 Sep 2013 14:45:15 +0300] Read: 0.
[Thu, 12 Sep 2013 14:45:15 +0300] Write: 1.
[Thu, 12 Sep 2013 14:45:15 +0300] Except: 0.
[Thu, 12 Sep 2013 14:45:15 +0300] 11: Resource temporarily unavailable
さて、これは私を少し狂わせます。syslog
ドキュメントには、これが可能であると書かれています。コードの何が問題になっていますか?
オリジナル:
単純に、次の方法でプロトタイプを作成しました。
while(true)
{
exec('journalctl -r -n 1 | more', $result, $exit);
// do stuff
}
しかし、これは間違っていると感じ、システム リソースを大量に消費します。その後、journald にソケットがあることがわかりました。
私は接続して読み込もうとしました:
AF_UNIX, SOCK_DGRAM : /var/run/systemd/journal/socket
AF_UNIX, SOCK_STREAM : /var/run/systemd/journal/stdout
指定されたソケット。
では/var/run/systemd/journal/socket
、socket_select
0 の変更が表示されます。I always (すべてのループ)では/var/run/systemd/journal/stdout
、0 バイトのデータで 1 つの変更を取得します。
これは私の「読者」です:
<?php
define('NL', "\n\r");
$journal = '/var/run/systemd/journal/socket';
$jSTDOUT = '/var/run/systemd/journal/stdout';
$journal = $jSTDOUT;
$sock = socket_create(AF_UNIX, SOCK_STREAM, 0);
$connection = @socket_connect($sock, $journal);
$log = function ($message)
{
echo '[' . date('r') . '] ' . $message . NL;
};
if (!$connection)
{
$log('Couldn\'t connect to ' . $journal);
}
else
{
$log('Connected to ' . $journal);
$readables = array($sock);
while (true)
{
$read = $readables;
if (socket_select($read, $write = NULL, $except = NULL, 0) < 1)
{
continue;
}
foreach ($read as $read_socket)
{
$data = @socket_read($read_socket, 1024, PHP_BINARY_READ);
if ($data === false)
{
$log('Couldn\'t read.');
socket_shutdown($read_socket, 2);
socket_close($read_socket);
$log('Server terminated.');
break 2;
}
$data = trim($data);
if (!empty($data))
{
$log($data);
}
}
}
$log('Exiting.');
}
読み取りソケットにデータがないため、何か間違ったことをしていると思います。
質問、アイデア:
私の目標は、メッセージを読み取り、それらのいくつかに対してcallbackを実行することです。
ジャーナルメッセージをプログラムで読む方法の正しい方向を教えてもらえますか?