在服务器运维或应用开发中,我们经常需要查看实时生成的日志文件。传统的 tail -f 命令虽然强大,但必须登录到服务器才能使用,不够直观和便捷。如果我们能通过一个网页来优雅地、自动更新地查看日志,那将极大提升我们的工作效率。

本教程将带你一步步,使用 Python 的轻量级 Web 框架 Flask,结合现代化的前端技术,搭建一个稳定、美观、实用的网页版实时日志查看器。

最终成果预览:

技术栈:

  • 后端: Python 3, Flask
  • 前端: HTML, CSS (Flexbox), JavaScript (Fetch API, Polling)
  • 部署: Linux (Debian/Ubuntu), systemd 服务

第一步:服务器环境准备

一个干净的系统是成功的一半。我们将以一个全新的 Debian/Ubuntu 服务器为例。

1.更新软件包列表 首先,更新系统的包管理器,确保能获取到最新的软件信息。

sudo apt update

2.安装 Python 虚拟环境支持 现代 Debian/Ubuntu 系统为了保持精简,可能没有预装 Python 的虚拟环境 (venv) 工具。我们需要手动安装它。

# 对于 Debian 11 / Ubuntu 20.04 (Python 3.9), 使用:
# sudo apt install python3.9-venv -y

# 一个更通用的命令是:
sudo apt install python3-venv -y

3.(推荐) 修复主机名解析警告 如果你在运行 sudo 命令时看到 unable to resolve host ... 的警告,可以通过编辑 /etc/hosts 文件来修复。

sudo nano /etc/hosts

在文件中加入类似 127.0.1.1 你的主机名 的一行即可。这不是必须的,但可以消除烦人的警告。

第二步:项目设置与依赖安装

现在,我们来创建项目并配置一个隔离的 Python 环境。

1.创建项目目录

mkdir -p ~/logdata
cd ~/logdata

2.创建并激活虚拟环境 使用 venv 为我们的项目创建一个名为 venv 的独立 Python 环境。

python3 -m venv venv

然后,激活这个环境。这是非常关键的一步!

source venv/bin/activate

3.安装 Flask

在激活的虚拟环境中,使用 pip 安装 Flask。

pip install Flask

第三步:编写后端代码 (app.py)

我们的后端将提供两个服务:一个用于展示网页,另一个是 API 接口,用于提供最新的日志数据。

~/logdata 目录下,创建 app.py 文件:

nano app.py

将以下代码完整复制进去:

import json
from flask import Flask, render_template, Response

# --- 配置区 ---
# 日志文件的绝对路径请根据你的实际情况修改
LOG_FILE_PATH = '/root/rbot/log_r_client.log' 
# 每次请求返回的日志行数
LOG_LINES_TO_RETURN = 11

app = Flask(__name__)

@app.route('/')
def home():
    """渲染前端主页"""
    return render_template('index.html')

@app.route('/get-logs')
def get_logs():
    """API 接口,读取并返回日志文件的最后N行"""
    try:
        with open(LOG_FILE_PATH, 'r', encoding='utf-8') as f:
            all_lines = f.readlines()
            # 获取列表的最后N个元素
            last_lines = all_lines[-LOG_LINES_TO_RETURN:]
            # 清理每行末尾的换行符
            last_lines = [line.strip() for line in last_lines]
            #  Python 列表转换为 JSON 字符串作为响应返回
            return Response(json.dumps(last_lines), mimetype='application/json')
    except FileNotFoundError:
        error_msg = [f"错误: 日志文件未找到 {LOG_FILE_PATH}"]
        return Response(json.dumps(error_msg), status=404, mimetype='application/json')
    except Exception as e:
        error_msg = [f"发生未知错误: {str(e)}"]
        return Response(json.dumps(error_msg), status=500, mimetype='application/json')

if __name__ == '__main__':
    # 生产环境中 debug 模式应为 False
    app.run(host='0.0.0.0', port=2096, debug=False)

第四步:编写前端界面 (templates/index.html)

前端负责以美观的方式展示数据,并定时从后端获取更新。

首先,创建 templates 文件夹:

mkdir templates

创建 index.html 文件:

nano templates/index.html

将以下代码完整复制进去。这是我们最终迭代出的、包含所有美化效果的版本。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Oracle 抢机实时日志</title>
    <style>
        html { height: 100%; }
        body {
            margin: 0;
            background-color: #1e1e1e;
            color: #d4d4d4;
            font-family: 'Monaco', 'Menlo', 'Consolas', 'Courier New', monospace;
            display: flex; /* 启用 Flexbox 布局,用于垂直撑满 */
            flex-direction: column;
            height: 100vh;
        }
        #header {
            background-color: #333;
            padding: 12px 25px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.5);
            text-align: center;
            flex-shrink: 0; /* 防止Header被压缩 */
        }
        #header h1 { margin: 0; font-size: 1.4em; }
        #table-container {
            flex-grow: 1; /* 关键:让此容器占据所有剩余垂直空间 */
            display: flex;
            padding: 20px;
            box-sizing: border-box;
            overflow: hidden;
        }
        table {
            width: 90%; 
            max-width: 980px; /* 控制表格最大宽度,实现居中效果 */
            margin: 0 auto; /* 水平居中 */
            border-collapse: separate;
            border-spacing: 0;
            height: 100%;
        }
        #log-body {
            display: flex;
            flex-direction: column;
            height: 100%;
            gap: 8px; /* 行间距 */
        }
        tr {
            flex-grow: 1; /* 关键:让每行平分可用高度 */
            display: flex;
            align-items: center; /* 垂直居中行内文字 */
            border-radius: 6px; /* 卡片圆角 */
        }
        tr:nth-child(odd) { background-color: #3c3c3c; } /* 奇数行颜色 */
        tr:nth-child(even) { background-color: #2a2d2e; } /* 偶数行颜色 */
        td { padding: 15px 25px; line-height: 1.6; width: 100%; }
        tr:hover { background-color: #555; }
    </style>
</head>
<body>
    <div id="header">
        <h1>Oracle 抢机实时日志</h1>
    </div>
    <div id="table-container">
        <table>
            <tbody id="log-body">
                </tbody>
        </table>
    </div>
    <script>
        const logBody = document.getElementById('log-body');

        // 定义一个函数来获取并更新日志
        async function fetchLogs() {
            try {
                // 使用 fetch API 去请求 /get-logs 接口
                const response = await fetch('/get-logs');
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                const lines = await response.json();

                logBody.innerHTML = ''; // 先清空当前的表格内容

                // 遍历获取到的新数据,并创建表格行
                lines.forEach(line => {
                    if (!line) return;
                    const tr = document.createElement('tr');
                    tr.innerHTML = `<td>${line}</td>`;
                    logBody.appendChild(tr);
                });
            } catch (error) {
                console.error("Failed to fetch logs:", error);
                logBody.innerHTML = `<tr><td>获取日志失败,请检查网络或后台服务...</td></tr>`;
            }
        }

        // 1. 页面加载后立即执行一次
        fetchLogs();

        // 2. 设置定时器,每 2 分钟(120000毫秒)执行一次
        setInterval(fetchLogs, 120000);
    </script>
</body>
</html>

第五步:创建 systemd 系统服务

为了让我们的应用能在后台稳定运行,并且开机自启,我们需要为它创建一个 systemd 服务。

1.创建服务文件

sudo nano /etc/systemd/system/logviewer.service

2.写入配置 将以下内容完整复制进去。

[Unit]
Description=Oracle Log Viewer Service
After=network.target

[Service]
User=root
Group=root
WorkingDirectory=/root/logdata
ExecStart=/root/logdata/venv/bin/python /root/logdata/app.py
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

⚠️ 重要安全提示

在此配置中,我们使用了 User=root。在真实的生产环境中,强烈不建议使用 root 用户来运行网络服务。我们在这里使用 root 只是为了匹配你当前的目录结构和文件权限。

第六步:管理与验证服务

现在,让我们来启动并管理我们的新服务。

1.重新加载 systemd 配置

sudo systemctl daemon-reload

2.启用并启动服务

sudo systemctl enable logviewer.service
sudo systemctl start logviewer.service

3.检查服务状态

sudo systemctl status logviewer.service

如果一切顺利,你应该能看到绿色的 active (running) 字样。

4.查看服务日志 如果需要排查问题,可以用这个命令查看程序的实时输出:

sudo journalctl -u logviewer.service -f

第七步:查看最终成果

万事俱备!现在,打开你的浏览器,访问:

http://<你的服务器IP地址>:2096

你应该能看到一个设计精美、自动更新的日志查看器界面了。它会立即显示最新的11条日志,然后每2分钟刷新一次,为你提供稳定、清晰的日志监控体验。