2016-05-09 2 views
0

Я пытаюсь отобразить вывод/var/log/messages или аналогичного (../secure, например) на веб-странице, к которой я обращаюсь через веб-сервер на том же хосте.display/var/log/messages в html/php output?

Должен ли я использовать bash для tail -f >> файл сообщений в новый выходной файл и отображать этот текстовый файл на странице html или есть лучший способ сделать это?

Спасибо! idiglivemusic

ответ

0
<!DOCTYPE html> 
<html> 
<head> 
    <title>toyLogs</title> 
</head> 
<body> 
    <div><p><?php include('/var/www/html/accesslog.txt'); ?></p></div> 
</body> 
</html> 
1

Если вы используете tail -f, это означает, что вы будете непрерывно получать данные из файла, пока он растет по мере запуска команды. Вы можете использовать кошку или хвост -n. Кроме того, вы можете напрямую обращаться к файлам, создавая им символическую или жесткую ссылку (ln-файл-файл-файл, ln -s source-file link-file), но убедитесь, что на вашем веб-сервере достаточно права доступа к ним.

+0

Спасибо за быстрый ответ Сергей! Я закончил с решением, которое позволяет избежать символических ссылок. – iDigLiveMusic

0

Убедитесь, что ваш html-сервер имеет права доступа к странице и чтения страницы (с чем-то вроде cat, tail, grep). В <html> введите выходные данные между <pre> и </pre>.

0

Метод 1

В одном из базовых каталогов, создать символическую ссылку

ln -s /var/log/messages messages 

Если каталог принадлежал сказать, test.web, доступ к журналу с unmesh http://test.web/messages

Способ 2

Если вы ищете php сценарий, то сначала создайте ссылку, как указано в способе 1. Затем создайте новый файл, скажем, readlog.php в базовой директории test.web с содержимым, приведенным ниже:

<?php 
readfile(“$DOCUMENT_ROOT/messages”); 
?> 

Доступ к readlog.php нравится:

http://test.web/readlog.php 

Требование:

Read доступ должен быть включен для всех пользователей для /var/log/messages.

Примечание:

read Установка опции для /var/log/messages для всего мира НЕ хорошей идеей.

+0

Спасибо за ответ! Из-за очевидных проблем безопасности (которые вы указали) я мог бы передать это, но он технически относится к моей проблеме, хотя и использует php вместо html – iDigLiveMusic

1

Если вы ищете способ отображения фактического содержимого файла в Интернете без необходимости перезагрузки страницы, вам необходимо установить сервер WebSocket.

Вы можете создать сервер WebSocket, используя рамки, такие как phpDaemon, ReactPHP, Ratchet, icicle или реализовать свой собственный сервер с помощью PHP расширений оберточных асинхронных библиотек: eventev, или аналогичных.

Я выбрал случайную структуру из приведенного выше списка: Ratchet. Ratchet основан на ReactPHP. ReactPHP выбирает бэкенд для цикла событий из следующего списка: - libevent расширения, - libev расширения, - event расширения, - или внутренний класс на основе встроенного stream_select() функции.

Как продюсер event, я выбрал event.

Я написал «быстрый» пример, чтобы дать вам представление о том, как он может быть реализован. Скорее всего, вам придется разработать свою собственную версию, возможно, используя разные инструменты. Но код должен дать вам импульс.

SRC/MyApp/Server.php

<?php 
namespace MyApp; 
use Ratchet\MessageComponentInterface; 
use Ratchet\ConnectionInterface; 

class Server implements MessageComponentInterface { 
    protected $clients; 

    public function __construct() { 
    $this->clients = new \SplObjectStorage; 
    } 

    public function onOpen(ConnectionInterface $conn) { 
    $this->clients->attach($conn); 
    echo "New connection! ({$conn->resourceId})\n"; 
    } 

    public function onMessage(ConnectionInterface $from, $msg) { 
    $numRecv = count($this->clients) - 1; 
    printf("Connection %d sending '%s' to %d other connection%s\n", 
     $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's'); 

    foreach ($this->clients as $client) { 
     if ($from !== $client) { 
     $client->send($msg); 
     } 
    } 
    } 

    public function onClose(ConnectionInterface $conn) { 
    $this->clients->detach($conn); 
    echo "Connection {$conn->resourceId} has disconnected\n"; 
    } 

    public function onError(ConnectionInterface $conn, \Exception $e) { 
    echo "An error has occurred: {$e->getMessage()}\n"; 
    $conn->close(); 
    } 

    public function broadcast($msg) { 
    foreach ($this->clients as $client) { 
     $client->send($msg); 
    } 
    } 
} 

server.php

<?php 
use Ratchet\Server\IoServer; 
use Ratchet\Http\HttpServer; 
use Ratchet\WebSocket\WsServer; 
use MyApp\Server; 

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

$server = IoServer::factory(
    new HttpServer(
    new WsServer(
     $my_app_server = new Server() 
    ) 
), 
    9989 
); 

$loop = $server->loop; 
$filename = '/var/log/messages'; 

$loop->addPeriodicTimer(5, function() 
    use ($filename, $my_app_server) 
    { 
    static $stat_info; 

    if ($stat_info == null) { 
     clearstatcache(true, $filename); 
     $stat_info = stat($filename); 
    } 

    clearstatcache(true, $filename); 
    $st = stat($filename); 

    $size_diff = $st['size'] - $stat_info['size']; 
    echo "Diff = $size_diff bytes\n"; 

    if ($size_diff > 0) { 
     $offset = $stat_info['size']; 
     $bytes = $size_diff; 
    } elseif ($size_diff < 0) { 
     // The file is likely truncated by `logrotate` or similar utility 
     $offset = 0; 
     $bytes = $st['size']; 
    } else { 
     $bytes = 0; 
    } 

    $stat_info = $st; 

    if ($bytes) { 
     if (! $fp = fopen($filename, 'r')) { 
     fprintf(STDERR, "Failed to open file $filename\n"); 
     return; 
     } 
     if ($offset > 0) { 
     fseek($fp, $offset); 
     } 
     if ($msg = fread($fp, $bytes)) { 
     $my_app_server->broadcast($msg); 
     } 
     fclose($fp); 
    } 
    } 
); 

$server->run(); 

test.html

<html> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8"> 
    <title>Test</title> 
</head> 
<body> 
    <script> 
    var conn = new WebSocket('ws://localhost:9989'); 
    conn.onopen = function(e) { 
    console.log("Connection established!"); 
    }; 
    conn.onmessage = function(e) { 
    console.log("Msg from server", e.data); 
    }; 
    </script> 
</body> 
</html> 

Я опущу шаги р equired для установки базовой тестовой среды с использованием Composer. Предполагая, что вы успешно настроили тестовую среду для файлов выше, вы будете иметь возможность запускать сервер с помощью следующей команды:

php server.php 

Проверьте, если пользователь имеет право на чтение /var/log/messages. В моей системе только root может прочитать файл. Таким образом, вам может потребоваться выполнить указанную выше команду с помощью sudo (корневые разрешения).

Теперь вы можете открыть test.html в браузере и посмотреть на вывод консоли. Затем активируйте событие, которое обычно регистрируется в файле сообщений. Например, вы можете вызывать sudo с неправильным паролем. Сервер должен обнаружить изменения в течение 5 секунд, а затем отправить их клиентам WebSocket.

+0

. Это похоже на полное решение проблемы: D – sjsam

+0

Ruslan, Спасибо за ваш ответ. Очень тщательно! Не могли бы вы объяснить, где находится файл src/MyApp/Server.php? Вы хотите, чтобы он зашел в /usr/src/MyApp/Server.php ??? (!!!) – iDigLiveMusic

+0

@iDigLiveMusic, это всего лишь [PSR-0] (http://www.php-fig.org/psr/psr-0/) в вашем каталоге проектов, который может быть где угодно в файловой системе. См. Пример Ratchet [«привет мир»] (http://socketo.me/docs/hello-world) –