`

使用 WebSocket 和 Python 编写日志查看器

阅读更多

在生产环境运维工作中,查看线上服务器日志是一项常规工作。如果这项工作可以在浏览器中进行,而无需登录服务器执行 tail -f 命令,就太方便了。我们可以使用 WebSocket 技术轻松实现这一目标。在本文中,我将带各位一起使用 Python 编写一个日志查看工具。

基于 WebSocket 的日志查看器基于 WebSocket 的日志查看器

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
 
@asyncio.coroutine
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
@asyncio.coroutine
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监听数据库

    通过查看源码,我们可以学习如何整合数据库监听和WebSocket推送的细节,例如如何配置数据库连接,如何编写WebSocket服务器代码,以及如何在前端与WebSocket服务器交互等。 总的来说,WebSocket监听数据库是一项技术...

    Python库 | samsteady_python_utils-1.0.1-py3-none-any.whl

    为了更好地了解`samsteady_python_utils`库的具体功能和用法,建议查看其官方文档或者阅读源代码,以便深入学习和使用。 总结来说,`samsteady_python_utils`是一个面向Python 3的实用工具库,以`.whl`格式提供,...

    Python库 | chariothy_common-1.2.2-py3-none-any.whl

    通过使用pip(Python的包管理器),用户可以直接安装这个.whl文件,无需编译源代码,从而节省了时间和资源。例如,你可以使用以下命令来安装这个库: ```bash pip install chariothy_common-1.2.2-py3-none-any.whl...

    Python库 | casey-1.1.0-py3-none-any.whl

    Python库的开发通常遵循一定的规范,比如使用setuptools或者distutils作为构建工具,编写`setup.py`脚本来定义库的元数据,如作者、版本、依赖等。Casey库的开发者可能已经定义好了这些信息,使得用户可以通过`setup...

    Python库 | winhye_common-0.0.2-py3-none-any.whl

    `.whl`文件通常包含Python模块的预编译版本,适用于特定的Python解释器版本和操作系统平台。 winhye_common库,版本号为0.0.2,是专为Python 3设计的,其“none-any”部分表示该库不依赖特定的系统架构或ABI(应用...

    【python爬虫】资源pyspider-v0.3.10

    - 支持WebSocket和JSONP:处理动态加载和异步加载的数据。 四、使用流程 1. **创建项目**:在WebUI中新建项目,编写爬虫脚本。 2. **定义爬虫任务**:使用`@every`装饰器设置定时任务,`@config`配置爬虫参数。 3. ...

    Python库 | alpaca_trade_api-1.3.0-py3-none-any.whl

    版本1.3.0可能包含对前一版本的改进和新功能,具体更新日志需查看官方发布文档。通常,版本更新可能涉及性能优化、错误修复、增加新的API接口或者增强已有功能的稳定性。 5. **适用场景** `alpaca_trade_api`适用...

    Python-通过Chrome开发者工具调试Django应用

    在Python开发领域,Django是一个广泛使用的Web框架,它提供了高效、可扩展的后端解决方案。而Chrome开发者工具(Chrome DevTools)是前端开发者必备的利器,它可以帮助我们调试JavaScript、CSS、网络请求等。然而,...

    更简单的方式开发移动端webapp.zip

    在IT行业中,Python爬虫是一项重要的技能,尤其...为了深入了解"lincoui-master",你需要解压文件并查看其代码结构和文档,了解项目的具体实现和使用方法。这将帮助你更好地运用Python爬虫技术于移动端Webapp的开发中。

    python_chromedev_monitor

    使用该工具,开发者可以实时查看网页的加载速度、网络请求、内存使用、CPU占用、CSS选择器性能等关键指标。这有助于发现和解决性能瓶颈,优化前端代码。 4. **网络请求分析**: "python_chromedev_monitor"可能...

    开发板程序代码

    它们通常配备有微处理器、内存、输入/输出接口等基本组件,为编写和运行应用程序提供了一个实际的平台。"开发板程序代码"指的是在特定开发板上运行的软件代码,这些代码可能包括操作系统内核、驱动程序、应用软件等...

    Tornado 最新代码

    Tornado是一款由Facebook开源的高性能Web框架,完全用Python编写,以其异步网络I/O模型而闻名。这个“Tornado最新代码”指的是Tornado的3.2.1版本,一个在发布时被认为是最新且功能强大的版本。下面我们将深入探讨...

    个人博客系统毕业设计.zip

    - 文章创建、编辑和删除:支持Markdown或富文本编辑器,方便用户编写内容。 - 分类与标签:组织文章,便于用户按主题查找。 - 文章版本控制:保存历史版本,便于恢复误删或查看修改记录。 6. **评论系统** - ...

    sanic:异步Python 3.6+ Web服务器框架| 快速建立。 快跑

    在压缩包文件`sanic-master`中,可能包含了Sanic的源码和示例项目,用户可以通过阅读源码了解其内部实现,或者查看示例来学习如何使用Sanic构建自己的Web服务。 总之,Sanic是一个强大的、异步的Python Web服务器...

    double-x-financial-tracker-源码.rar

    这涉及到网络编程技术,如HTTP请求、WebSocket连接等,以及对API的理解和使用。 数据存储模块则需要处理大量的金融数据,可能采用数据库系统,如MySQL、MongoDB或者专门针对时间序列数据的InfluxDB等。这部分涉及...

    msg.rar的源代码

    10. **测试与调试**:项目可能包含了单元测试、集成测试和自动化测试脚本,以确保代码质量,并使用调试工具(如Android Studio的调试器)进行问题定位。 以上是对"msg.rar"源代码可能涉及的知识点的详细阐述,具体...

    源代码文件(Goc Chess)

    - **编程语言的语法和特性**:根据源代码使用的编程语言(可能是C++、Python、Java或C#),可以深入学习语言的细节。 - **设计模式和架构**:源代码可能体现了单体架构、模块化设计或者面向对象的设计原则。 - **...

    小E单班同学录1.1源码.zip

    2. **编程语言**:根据源码的编写,可以推测小E单班同学录可能使用了Java、Python、C#、JavaScript等常见编程语言中的某一种。具体语言的选择可能影响到程序的性能、跨平台能力和开发效率。 3. **软件架构**:同学...

    django完整学习项目,包含集成scrapy爬虫

    4. **Scrapyd的使用**:Scrapyd是一个Scrapy的分布式爬虫调度器,它可以部署、管理、监控和调度多个Scrapy项目。在Django中集成Scrapyd,可以通过其提供的API接口来启动、停止爬虫,或者获取爬虫状态和日志。 5. **...

    Crypto-Message-Bot

    8. **错误处理和日志记录**:为了提高程序的健壮性,Python的异常处理机制(try-except-finally)会被使用,同时可能使用logging模块记录程序运行过程中的错误和事件,以便于调试和维护。 9. **版本控制**:项目名...

Global site tag (gtag.js) - Google Analytics