【问题标题】:display /var/log/messages in html/php output?在 html/php 输出中显示 /var/log/messages?
【发布时间】:2016-05-09 04:23:40
【问题描述】:

我试图在我通过同一主机上的网络服务器访问的网页中显示 /var/log/messages 或类似内容(例如../secure)的输出。

我应该使用 bash 尾 -f >> 消息文件到一个新的输出文件并在 html 页面中显示该文本文件,还是有更好的方法来做到这一点?

谢谢! idiglive音乐

【问题讨论】:

    标签: linux bash apache logging


    【解决方案1】:

    如果您正在寻找一种无需重新加载页面即可在线显示实际文件内容的方法,那么您应该设置一个WebSocket 服务器。

    您可以使用 phpDaemonReactPHPRatcheticicle 等框架构建 WebSocket 服务器,或者借助包装异步库的 PHP 扩展实现自己的服务器:event、@ 987654327@,或类似的。

    我从上面的列表中随机选择了一个框架: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>
    

    我将跳过使用Composer 设置基本测试环境所需的步骤。假设您已成功配置上述文件的测试环境,您将能够使用以下命令运行服务器:

    php server.php
    

    检查用户是否有权读取/var/log/messages。在我的系统上只有root 可以读取该文件。因此,您可能需要使用sudo(root 权限)运行上述命令。

    现在您可以在浏览器中打开test.html 并查看控制台输出。然后触发一些通常记录到消息文件中的事件。例如,您可以使用错误的密码调用sudo。服务器应在 5 秒的间隔内检测到更改,然后将其发送到 WebSocket 客户端。

    【讨论】:

    • 这看起来像是一个完整的问题解决方案:D
    • Ruslan,感谢您的回复。很彻底!您能否澄清 src/MyApp/Server.php 文件的去向?你的意思是让它进入/usr/src/MyApp/Server.php??? (!!!)
    • @iDigLiveMusic,它只是您项目目录中的PSR-0,可以在文件系统的任何位置使用。请参阅 Ratchet 的"hello world" example
    • 非常感谢所有帮助。虽然这比我所寻找的要多,但我仍然赞成,因为我相信这最终可能会帮助一些毫无戒心的读者:)
    【解决方案2】:

    如果您使用的是 tail -f,这意味着您将不断地从文件中获取数据,同时它会随着命令的运行而增长。 您可以使用 cat 或 tail -n。此外,当然,您可以通过创建符号或硬链接来直接访问文件(ln source-file link-file,ln -s source-file link-file) - 但请确保您的网络服务器有足够的访问它们的权利。

    【讨论】:

    • 感谢谢尔盖的快速响应!我最终得到了一个避免符号链接的解决方案。
    【解决方案3】:

    确保您的 html-server 有权访问该页面并阅读该页面(例如cattailgrep)。 在&lt;html&gt; 中,将输出放在&lt;pre&gt;&lt;/pre&gt; 之间。

    【讨论】:

      【解决方案4】:

      方法一

      在您的一个基本目录中,创建一个符号链接

      ln -s /var/log/messages messages
      

      如果该目录属于test.web,则使用以下命令访问日志 取消网格化 http://test.web/messages

      方法二

      如果您正在寻找php 脚本,请首先按照方法1 中所述创建链接。然后,在test.web 的基本目录中创建一个新文件,例如readlog.php,内容如下:

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

      访问readlog.php 喜欢:

      http://test.web/readlog.php
      

      要求:

      应该为/var/log/messages的所有用户启用Read访问权限。

      注意:

      为全世界的/var/log/messages 设置read 选项不是一个好主意。

      【讨论】:

      • 感谢您的回复!由于明显的安全问题(你已经指出)我可能会传递这个问题,但它在技术上解决了我的问题,尽管使用 php 而不仅仅是 html
      【解决方案5】:
      <!DOCTYPE html>
      <html>
       <head>
        <title>toyLogs</title>
       </head>
       <body>
        <div><p><?php include('/var/www/html/accesslog.txt'); ?></p></div>
       </body>
      </html>
      

      【讨论】:

        猜你喜欢
        • 2016-02-29
        • 1970-01-01
        • 1970-01-01
        • 2015-01-27
        • 1970-01-01
        • 2017-04-29
        • 1970-01-01
        • 1970-01-01
        • 2019-01-15
        相关资源
        最近更新 更多