在生产环境运维工作中,查看线上服务器日志是一项常规工作。如果这项工作可以在浏览器中进行,而无需登录服务器执行 tail -f
命令,就太方便了。我们可以使用 WebSocket 技术轻松实现这一目标。在本文中,我将带各位一起使用 Python 编写一个日志查看工具。
WebSocket 简介
WebSocket 是一个标准化协议,构建在 TCP 之上,能够在客户端和服务端之间建立一个全双工的通信渠道。这里的客户端和服务端通常是用户浏览器和 Web 服务器。在 WebSocket 诞生之前,如果我们想保持这样的一个长连接,就需要使用诸如长轮询、永久帧、Comet 等技术。而现今 WebSocket 已经得到了所有主流浏览器的支持,我们可以使用它开发出在线聊天室、游戏、实时仪表盘等软件。此外,WebSocket 可以通过 HTTP Upgrade 请求来建立连接,并使用 80 端口通信,从而降低对现有网络环境的影响,如无需穿越防火墙。
websockets
Python 类库
websockets
是第三方的 Python 类库,它能基于 Python 提供的 asyncio
包来实现 WebSocket 服务端以及客户端应用。我们可以使用 pip
来安装它,要求 Python 3.3 以上的版本。
1
2
3
|
pip install websockets
# For Python 3.3
pip install asyncio
|
下面是一段简单的 Echo 服务代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import asyncio
import websockets
def echo(websocket, path):
message = yield from websocket.recv()
print('recv', message)
yield from websocket.send(message)
start_server = websockets.serve(echo, 'localhost', 8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
|
可以看到,我们使用 Python 的协程来处理客户端请求。协程是 Python 3.3 引入的新概念,简单来说,它能通过单个线程来实现并发编程,主要适用于处理套接字 I/O 请求等场景。Python 3.5 开始又引入了 async
和 await
关键字,方便程序员使用协程。以下是使用新关键字对 Echo 服务进行改写:
1
2
3
|
async def echo(websocket, path):
message = await websocket.recv()
await websocket.send(message)
|
对于客户端应用,我们直接使用浏览器内置的 WebSocket
类。将下面的代码直接粘贴到 Chrome 浏览器的 JavaScript 控制台中就可以运行了:
1
2
3
4
5
6
7
|
let ws = new WebSocket('ws://localhost:8765')
ws.onmessage = (event) => {
console.log(event.data)
}
ws.onopen = () => {
ws.send('hello')
}
|
查看并监听日志
我们将通过以下几步来构建日志查看器:
- 首先,客户端发起一个 WebSocket 请求,并将请求的文件路径包含在 URL 中,形如
ws://localhost:8765/tmp/build.log?tail=1
; - 服务端接受到请求后,将文件路径解析出来,顺带解析出是否要持续监听日志的标志位;
- 服务端打开日志文件,开始不断向客户端发送日志文件内容。
完整的源代码可以在 GitHub 中查看,以下只截取重要的部分:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
def view_log(websocket, path):
parse_result = urllib.parse.urlparse(path)
file_path = os.path.abspath(parse_result.path)
query = urllib.parse.parse_qs(parse_result.query)
tail = query and query['tail'] and query['tail'][0] == '1'
with open(file_path) as f:
yield from websocket.send(f.read())
if tail:
while True:
content = f.read()
if content:
yield from websocket.send(content)
else:
yield from asyncio.sleep(1)
else:
yield from websocket.close()
|
其它特性
- 在实际应用中发现,浏览器有时不会正确关闭 WebSocket 连接,导致服务端资源浪费,因此我们添加一个简单的心跳机制:
1
2
3
4
5
6
|
if time.time() - last_heartbeat > HEARTBEAT_INTERVAL:
yield from websocket.send('ping')
pong = yield from asyncio.wait_for(websocket.recv(), 5)
if pong != 'pong':
raise Exception('Ping error'))
last_heartbeat = time.time()
|
- 日志文件中有时会包含 ANSI 颜色高亮(如日志级别),我们可以使用
ansi2html
包来将高亮部分转换成 HTML 代码:
1
2
3
|
from ansi2html import Ansi2HTMLConverter
conv = Ansi2HTMLConverter(inline=True)
yield from websocket.send(conv.convert(content, full=False))
|
- 最后,日志文件路径也需要进行权限检查,本例中是将客户端传递的路径转换成绝对路径后,简单判断了路径前缀,以作权限控制。
参考资料
- WebSocket - Wikipedia
- websockets - Get Started
- Tasks and coroutines
- How can I tail a log file in Python?
相关推荐
通过查看源码,我们可以学习如何整合数据库监听和WebSocket推送的细节,例如如何配置数据库连接,如何编写WebSocket服务器代码,以及如何在前端与WebSocket服务器交互等。 总的来说,WebSocket监听数据库是一项技术...
为了更好地了解`samsteady_python_utils`库的具体功能和用法,建议查看其官方文档或者阅读源代码,以便深入学习和使用。 总结来说,`samsteady_python_utils`是一个面向Python 3的实用工具库,以`.whl`格式提供,...
通过使用pip(Python的包管理器),用户可以直接安装这个.whl文件,无需编译源代码,从而节省了时间和资源。例如,你可以使用以下命令来安装这个库: ```bash pip install chariothy_common-1.2.2-py3-none-any.whl...
Python库的开发通常遵循一定的规范,比如使用setuptools或者distutils作为构建工具,编写`setup.py`脚本来定义库的元数据,如作者、版本、依赖等。Casey库的开发者可能已经定义好了这些信息,使得用户可以通过`setup...
`.whl`文件通常包含Python模块的预编译版本,适用于特定的Python解释器版本和操作系统平台。 winhye_common库,版本号为0.0.2,是专为Python 3设计的,其“none-any”部分表示该库不依赖特定的系统架构或ABI(应用...
- 支持WebSocket和JSONP:处理动态加载和异步加载的数据。 四、使用流程 1. **创建项目**:在WebUI中新建项目,编写爬虫脚本。 2. **定义爬虫任务**:使用`@every`装饰器设置定时任务,`@config`配置爬虫参数。 3. ...
版本1.3.0可能包含对前一版本的改进和新功能,具体更新日志需查看官方发布文档。通常,版本更新可能涉及性能优化、错误修复、增加新的API接口或者增强已有功能的稳定性。 5. **适用场景** `alpaca_trade_api`适用...
在Python开发领域,Django是一个广泛使用的Web框架,它提供了高效、可扩展的后端解决方案。而Chrome开发者工具(Chrome DevTools)是前端开发者必备的利器,它可以帮助我们调试JavaScript、CSS、网络请求等。然而,...
在IT行业中,Python爬虫是一项重要的技能,尤其...为了深入了解"lincoui-master",你需要解压文件并查看其代码结构和文档,了解项目的具体实现和使用方法。这将帮助你更好地运用Python爬虫技术于移动端Webapp的开发中。
使用该工具,开发者可以实时查看网页的加载速度、网络请求、内存使用、CPU占用、CSS选择器性能等关键指标。这有助于发现和解决性能瓶颈,优化前端代码。 4. **网络请求分析**: "python_chromedev_monitor"可能...
在应用管理中,可以查看和管理机器人插件,同时在日志中检查机器人的响应情况。 2. **安装酷Q HTTP插件** - 下载HTTP插件的cpk文件,将其放置在酷Q的插件目录下。首次启动时,HTTP插件会生成默认配置文件,需要...
它们通常配备有微处理器、内存、输入/输出接口等基本组件,为编写和运行应用程序提供了一个实际的平台。"开发板程序代码"指的是在特定开发板上运行的软件代码,这些代码可能包括操作系统内核、驱动程序、应用软件等...
Tornado是一款由Facebook开源的高性能Web框架,完全用Python编写,以其异步网络I/O模型而闻名。这个“Tornado最新代码”指的是Tornado的3.2.1版本,一个在发布时被认为是最新且功能强大的版本。下面我们将深入探讨...
- 文章创建、编辑和删除:支持Markdown或富文本编辑器,方便用户编写内容。 - 分类与标签:组织文章,便于用户按主题查找。 - 文章版本控制:保存历史版本,便于恢复误删或查看修改记录。 6. **评论系统** - ...
它通常用Python编写,允许ROS节点与使用其他编程语言(如JavaScript)的客户端进行交互。在本教程中,我们将重点放在JavaScript上,因为它是构建Web应用的常用语言。 1. **设置ROS环境**:确保你已经安装了ROS,并...
在压缩包文件`sanic-master`中,可能包含了Sanic的源码和示例项目,用户可以通过阅读源码了解其内部实现,或者查看示例来学习如何使用Sanic构建自己的Web服务。 总之,Sanic是一个强大的、异步的Python Web服务器...
这涉及到网络编程技术,如HTTP请求、WebSocket连接等,以及对API的理解和使用。 数据存储模块则需要处理大量的金融数据,可能采用数据库系统,如MySQL、MongoDB或者专门针对时间序列数据的InfluxDB等。这部分涉及...
10. **测试与调试**:项目可能包含了单元测试、集成测试和自动化测试脚本,以确保代码质量,并使用调试工具(如Android Studio的调试器)进行问题定位。 以上是对"msg.rar"源代码可能涉及的知识点的详细阐述,具体...
- **编程语言的语法和特性**:根据源代码使用的编程语言(可能是C++、Python、Java或C#),可以深入学习语言的细节。 - **设计模式和架构**:源代码可能体现了单体架构、模块化设计或者面向对象的设计原则。 - **...
2. **编程语言**:根据源码的编写,可以推测小E单班同学录可能使用了Java、Python、C#、JavaScript等常见编程语言中的某一种。具体语言的选择可能影响到程序的性能、跨平台能力和开发效率。 3. **软件架构**:同学...