在服务器运维或应用开发中,我们经常需要查看实时生成的日志文件。传统的 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分钟刷新一次,为你提供稳定、清晰的日志监控体验。

发表回复