python和websocket构建实时日志跟踪器的步骤

前言

websocket 是一种网络传输协议。可在单个 TCP 连接上进行全双工通信。基于此,websocket 使得客户端与服务端的通信变得更加简便和高效。

什么是 websocket

websocket 是独立的、创建在 TCP 上的协议。该协议在 2008 年诞生,并在 2011 年成为国际标准。它的一个主要特点是——全双工,即一旦建立连接,服务端或客户端可以主动向对方推送消息。

在 websocket 出现之前,网站如果需要实现推送技术,都是采用轮询的方式,即浏览器每隔一段时间就向服务器发出请求。这种模式的缺点在于,浏览器需要不断向服务器发送请求,消耗很多的带宽资源。比较新的 Comet 技术虽然也可以实现双向通信,但依然需要反复发送请求,并且 Comet 中普遍采用的 HTTP 长连接也会消耗服务器资源。

基于以上的情况,HTML5 定义了 websocket 协议,能够更好的节省服务器和带宽资源。并且实现高效的实时通信。目前,所有的浏览器都支持它。

websocket 通信原理和机制

websocket 虽然是一种新的协议,但它不能够脱离 http 单独存在,当客户端构建一个 websocket 实例,并且向服务端连接时,会首先发起一个 http 报文请求。告诉服务端需要将通信协议切换至 websocket。

如果服务端支持 websocket 协议,那么它会将通信协议切换至 websocket 并且返回响应报文。此时的返回状态码是 101,表示同意协议转换请求,接下来便可以进行数据传输了。

websocket 之所以借助 HTTP 完成握手协议,是因为有良好的兼容性,默认端口是 80 和 443。握手阶段不容易被防火墙屏蔽。

websocket 的特点

  • 开销小,服务器和客户端交换数据时,协议包头部包含较少的信息
  • 实时性高,协议采用全双工,相对于 http 请求客户端发起请求,服务端才能响应的模式,延迟明显更低
  • 与 HTTP 有良好的兼容性,默认端口是 80 和 443。握手采用 HTTP 协议,不容易被防火墙屏蔽
  • 支持文本和二进制数据传输
  • 支持自定义拓展,用户可以自己实现自定义的子协议
  • 通过心跳机制保持服务端与客户端的长连接

构建实时日志跟踪的小例子

服务端开启一个监听日志脚本的服务,服务会限制允许访问的路径范围(防止黑客利用程序漏洞,扫描整个服务器);服务器通过解析客户端的请求,返回日志的消息内容给客户端;服务器定时发送心跳检测给客户端,如果没有收到客户端的响应,则断开连接

服务端核心程序代码逻辑如下

with open(file_path) as f:
      # 首次读取指定行数(NUM_LINES)的日志文件,发送给客户端
            content = ''.join(deque(f, NUM_LINES))
            content = conv.convert(content, full=False)
            await websocket.send(content)

      # 如果发现客户端有 tail 请求,则进行 tail 日志追踪
            if tail:
        # 首先创建发起这次请求的心跳时间
                last_heartbeat = time.time()
                while True:
          # 每次 tail 服务端最新的日志记录,返回给客户端
                    content = f.read()
                    if content:
                        content = conv.convert(content, full=False)
                        await websocket.send(content)
                    else:
                        await asyncio.sleep(1)

                    # 检测这次请求距上一次发起请求,是不是已经超过了最长心跳检测时长,如果是,发起心跳检测
                    if time.time() - last_heartbeat > HEARTBEAT_INTERVAL:
                        try:
                            await websocket.send('ping')
                            pong = await asyncio.wait_for(websocket.recv(), 5)
                            logger.info(f"pong:{pong}")
                            if pong != 'pong':
                                raise Exception()
                        except Exception:
                            raise Exception('Ping error')
                        else:
                            last_heartbeat = time.time()
            else:
                await websocket.close()

客户端就非常简单了,监听服务端日志的文件,发现有新的日志产生则输出日志或者直接将日志实时展示在前端页面上。相应地,如果需要长期监听,那么当服务端发送心跳检测的信号过来,也需要回应响应的心跳反馈

客户端核心代码逻辑如下

async def consumer_handler(websocket: WebSocketClientProtocol) -> None:
    async for message in websocket:
        log_message(message)
        if message == "ping":
            await websocket.send("pong")

async def cousume(hostname: str, port: int, log_file: str, tail:bool=True) -> None:
    websocket_resource_url = f"ws://{hostname}:{port}{log_file}"
    if tail:
        websocket_resource_url = f"{websocket_resource_url}?tail=1"
    async with websockets.connect(websocket_resource_url) as websocket:
        await consumer_handler(websocket)

def log_message(message: str) -> None:
    logger.info(f"Message: {message}")

这里模拟一个日志生产文件

代码逻辑如下

import os

from loguru import logger

class LoggerExtend(object):
    # 存放目录名称
    folder = '../logs'

    def __init__(self, filename, folder=None):

        self.folder = folder or self.folder

        if not os.path.exists(self.folder):
            os.mkdir(self.folder)

        self.file = self.folder + '/' + filename

        logger.add(self.file, rotation="100 MB")

    @property
    def get_logger(self):
        return logger

if __name__ == '__main__':
    logger = LoggerExtend(os.path.basename(__file__).replace(".py", ".log")).get_logger
    import time
    while True:

        logger.info("你好aaa")

最后依次启动日志生产程序→服务端程序→客户端程序

日志生产文件启动后,运行效果如下

服务端启动程序运行,无运行日志产生

这时候启动客户端程序,运行效果如下

完整代码请移步至 GitHub 查看

https://github.com/hacksman/l...

日志生产程序路径:

common/logger_extend.py

服务端程序路径:

websoctet_lab/log_server.py

客户端程序路径:

websoctet_lab/cousumer_log_view.py

以上就是python和websocket构建实时日志跟踪器的步骤的详细内容,更多关于python 构建实时日志跟踪器的资料请关注我们其它相关文章!

(0)

相关推荐

  • python粘包问题及socket套接字编程详解

    粘包问题 TCP协议在传输过程中会出现数据粘包问题 讲一下TCP和UDP的区别,都是传数据的协议,没有好坏之说,只是不同的应用需求可能会更好选择哪一个协议 TCP:适合传输数量大 ,需要建立连接,会出现粘包问题,粘包问题可以解决,确定传入的长度,接收同样长度就可以保证一次性传输完 UDP: 适合传输数据量小,没有粘包,不需要连接,一次性传输,下一次就是新的数据,弊端就是数据丢失,不安全 QQ是用什么协议呢?按理应该可以用UDP协议,但是实际用的是TCP协议,这是历史遗留问题,可还记得我们输入QQ

  • 用Python进行websocket接口测试

    我们在做接口测试时,除了常见的http接口,还有一种比较多见,就是socket接口,今天讲解下怎么用Python进行websocket接口测试. 现在大多数用的都是websocket,那我们就先来安装一下websocket的安装包. pip install websocket-client 安装完之后,我们就开始我们的websocket之旅了. 我们先来看个炒鸡简单的栗子: import websocket ws = websocket.WebSocket() ws.connect("ws://

  • python基础之Socket套接字详解

    前言 Python语言提供了Socket套接字来实现网络通信. Python的应用程序通常通过Socket"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. 服务器和客户端的源代码 服务器端 #coding=utf-8 #创建TCP服务器 import socket import time from time import ctime HOST = '127.0.0.1' PORT = 8080 BUFSIZE=1024 sock = socket.s

  • python socket网络编程步骤详解(socket套接字使用)

    一.套接字套接字是为特定网络协议(例如TCP/IP,ICMP/IP,UDP/IP等)套件对上的网络应用程序提供者提供当前可移植标准的对象.它们允许程序接受并进行连接,如发送和接受数据.为了建立通信通道,网络通信的每个端点拥有一个套接字对象极为重要.套接字为BSD UNIX系统核心的一部分,而且他们也被许多其他类似UNIX的操作系统包括Linux所采纳.许多非BSD UNIX系统(如ms-dos,windows,os/2,mac os及大部分主机环境)都以库形式提供对套接字的支持.三种最流行的套接

  • 详解python3中socket套接字的编码问题解决

    一.TCP 1.tcp服务器创建 #创建服务器 from socket import * from time import ctime #导入ctime HOST = '' #任意主机 PORT = 21567 #随机提供个端口号 BUFSIZ = 1024 # 缓冲区大小设置为1KB,可以根据网络性能和程序需要改变这个容量 ADDR = (HOST, PORT) tcpSerSock = socket(AF_INET, SOCK_STREAM) #分配了 TCP 服务器套接字 tcpSerSo

  • python实现socket简单通信的示例代码

    首先先来简单介绍下socket: (具体更详细介绍的可以在网上找找,都讲得非常详细),这里主要是我自己的一些理解. socket是在应用层与传输层之间的一个抽象层,它的本质是编程接口,通过socket,才能实现TCP/IP协议. 它就是一个底层套件,用来处理最底层消息的接受和发送. socket翻译为套接字,可以把TCP/IP复杂的操作抽象为简单的几个接口来供应用层调用来实现进程在网络中的通信.socket起源于Unix,而Unix的基本要素之一就是"一切都为文件",即可以通过打开--

  • Python基础之Socket通信原理

    上图是socket网络编程的流程图 至于数据在网络中是怎么走的,咱先不说,那个太底层了,咱今天见就说如何将数据从咱的屏幕上放到网络流中去. 这可不是键盘敲敲,回车一按的事情,在这背后,那也是百转千回. 打开一个网络接口:套接字 Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. Python 中,我们用 socket()函数来创建套接字,语法格式如下: import socket # 居然

  • Python socket 套接字实现通信详解

    首先:我们介绍一下socket什么是socket: 1. socket 在操作系统中它是处于应用层与传输层的抽象层,它是一组操作起来非常简单的接口(接收数据的),此接口接受数据之后交个操作系统 那么为什么?直接给操作系统不是更方便吗?那么你就想错了 因为操作系统的接口远比我们想象的要丑陋复杂,使用操作系统交换数据,非诚繁琐,,开发者们只能想办法让一个中间人和他们打交道,来简单的实现数据交换,那么就是socket套接字.它的作用就是:与操作系统之间数据交换将这些繁琐的操作,进行高度化封装,和简化,

  • python和websocket构建实时日志跟踪器的步骤

    前言 websocket 是一种网络传输协议.可在单个 TCP 连接上进行全双工通信.基于此,websocket 使得客户端与服务端的通信变得更加简便和高效. 什么是 websocket websocket 是独立的.创建在 TCP 上的协议.该协议在 2008 年诞生,并在 2011 年成为国际标准.它的一个主要特点是--全双工,即一旦建立连接,服务端或客户端可以主动向对方推送消息. 在 websocket 出现之前,网站如果需要实现推送技术,都是采用轮询的方式,即浏览器每隔一段时间就向服务器

  • 基于Python编写简单实用的日志装饰器

    目录 1.简陋版装饰器 2.普通版装饰器 3.优化版装饰器 在写代码的时候,往往会漏掉日志这个关键因素,导致功能在使用的时候出错却无法溯源. 其实,只需要写一个非常简单的日志装饰器,我们就能大大提升排查问题的效率. 1.简陋版装饰器 写一个装饰器非常简单,因为本质上装饰器就是一个返回函数的“高阶”函数而已: 1) 函数作为参数传递进装饰器. 2) 装饰器内定义一个函数,处理作为参数传递进来的函数. 3) 返回这个装饰器内定义的函数 import datetime def log(func): "

  • .Net core Blazor+自定义日志提供器实现实时日志查看器的原理解析

    目录 场景 实现原理 如何使用? 1.启用blazor server(若你本来是,直接跳过) 2.安装咱的日志包:BXJG.BlazorServerLogger3.配置 自定义配置和样式 非微软的日志框架的集成 资源 基于blazor server的实时日志显示组件 场景 我们经常远程连接服务器去查看日志,比较麻烦,如果直接访问项目的某个页面就能实时查看日志就比较奈斯了,花了1天研究了下.net core 日志的原理,结合blazor实现了基本效果. 实现原理 自定义日志提供器,将日志记录到内存

  • Python使用Tkinter实现转盘抽奖器的步骤详解

    我使用 Python 中的 Tkinter 模块实现了一个简单的滚动抽奖器,接下来继续写一个简单的转盘抽奖器. Tkinter 实现滚动抽奖器参考:https://www.jb51.net/article/177913.htm 滚动抽奖器与点名的场景相似,是从一群人中抽出中奖的人,奖品是提前确定了的,抽奖只是确定中奖的人是谁.这种场景比较适合年会抽奖,奖品的种类和数量已经确定了,通过抽奖来抽出中奖人员,一个奖品对应一次抽奖,直到奖品抽完为止. 还有一种场景是只固定了奖品种类,数量不受限制,有参与

  • python实现定时提取实时日志程序

    本文实例为大家分享了python定时提取实时日志的具体代码,供大家参考,具体内容如下 这是一个定时读取 实时日志文件的程序.目标文件是target_file. 它是应用程序实时写入的. 我要做的是,每个5秒钟,提取一次该日志文件中的内容,然后生成另一个文件,最后把这些文件都汇总. #!/usr/local/bin/python # coding:utf-8 import fileinput import time import os target_file = 'user.log' init_f

  • python利用proxybroker构建爬虫免费IP代理池的实现

    前言 写爬虫的小伙伴可能遇到过这种情况: 正当悠闲地喝着咖啡,满意地看着屏幕上的那一行行如流水般被爬下来的数据时,突然一个Error弹出,提示抓不到数据了... 然后你反复检查,确信自己代码莫得问题之后,发现居然连浏览器也无法正常访问网页了... 难道是网站被我爬瘫痪了? 然后你用手机浏览所爬网站,惊奇地发现居然能访问! 才原来我的IP被网站给封了,拒绝了我的访问 这时只能用IP代理来应对禁IP反爬策略了,但是网上高速稳定的代理IP大多都收费,看了看皱皱的钱包后,一个大胆的想法冒出 我要白嫖!

  • Python接口自动化浅析logging日志原理及模块操作流程

    目录 一.日志介绍 01 为什么需要日志? 02 什么是日志? 03 日志的用途是什么? 04 日志的级别分为哪些? 05 日志功能的实现 二.Logging模块 01 logging模块介绍 02 logging模块优势 03 logging日志框架的组成 04 logging函数中的具体参数 05 简单的日志小例子 06 自定义logger日志 在上一篇Python接口自动化测试系列文章:Python接口自动化浅析pymysql数据库操作流程,主要介绍pymysql安装.操作流程.语法基础及

  • python+pytest接口自动化之日志管理模块loguru简介

    目录 安装 简单示例 add()常用参数说明 使用 python自带日志管理模块logging,使用时可进行模块化配置,详细可参考博文Python日志采集(详细). 但logging配置起来比较繁琐,且在多进行多线程等场景下使用时,如果不经过特殊处理,则容易出现日志丢失或记录错乱的情况. python中有一个用起来非常简便的第三方日志管理模块--loguru,不仅可以避免logging的繁琐配置,而且可以很简单地避免在logging中多进程多线程记录日志时出现的问题,甚至还可以自定义控制台输出的

  • SAE实时日志接口SDK用法示例

    本文实例讲述了SAE实时日志接口SDK用法.分享给大家供大家参考,具体如下: 新浪SAE是新浪研发中心开发的国内首个公有云平台,从2009年开始到现在也是也来越成熟,开放了很多接口以及服务供开发者使用.这次为了方便开发者调试分析,SAE新增实时日志查询接口.今后您可以通过API对日志信息进行筛选,并下载所需的实时日志.但是新浪SAE官方只给出的Python的实现,这里给出PHP版本的接口调用SDK class SaeApiHandler{ /** * 定义accessKey */ private

  • python自动化测试之异常及日志操作实例分析

    本文实例讲述了python自动化测试之异常及日志操作.分享给大家供大家参考,具体如下: 为了保持自动化测试用例的健壮性,异常的捕获及处理,日志的记录对掌握自动化测试执行情况尤为重要,这里便详细的介绍下在自动化测试中使用到的异常及日志,并介绍其详细的用法. 一.日志 打印日志是很多程序的重要需求,良好的日志输出可以帮我们更方便的检测程序运行状态.Python标准库提供了logging模块,切记Logger从来不直接实例化,其好处不言而喻,接下来慢慢讲解Logging模块提供了两种记录日志的方式.

随机推荐