简单分析实现运维利器---web远程ssh终端录像回放

背景
上次给大家介绍了实现基础的运维系统功能—webssh , 今日书接上回 , 继续给大家介绍一个web远程ssh终端录像回放功能 。
 
一、思路
网上查了一下资料 , 搜索了一下关于实现webssh录像回放的方案 , 大家统一都是使用asciinema!仔细看了相关技术文档之后更是二次确定!一开始以为需要视频文件 , 没想到 , asciinema用特定的格式文件就可以实现视频流 。(在写asciinemaweb技术的时候发现一个大坑 , 琢磨了将近两个小时 , 待会再详细说具体问题)
asciinema实际就是通过系统输出的信息 , 将信息写成asciinema特定的格式文件 , 包含header与data两大部分(也是待会从文章中讲解两部分的结构) , 它就能解析成视频 。所以我们在上次的功能逻辑之上:
1.连接ssh成功后 , 构造头部内容写入文件中;
2.将开头两条输出信息以特定的格式写入文件中;
3.将线程监听回来的所有输出信息以特定的格式写入文件中(其中2.3已经包含了我们webssh所有的输出信息了 , 已经足以构成录像回放);
4.创建html页面展示回访列表 。
 
二、实现
1.先说明一下asciinema文件的格式
头部:
header = {"version": 2,#(asciinema)版本"width": 160, #(asciinema)回放时的宽度"height": 48, #(asciinema)回放时的高度"timestamp": date, #(asciinema)时间戳 用于播放"env": {"SHELL": "/bin/bash",#(asciinema)使用的shell类型"TERM": "xterm-256color"}, #(asciinema)终端颜色"title": "video"#(asciinema)标题}data:
[0.00699162483215332, "o", "Last login: Thu May7 18:42:13 2020 from 192.168.254.1rrn"][0.1905069351196289, "o", "[root@leestudy ~]# "]#第一个字段为时间戳 , 第二个字段“o”为输出 , “i”为输入 , 第三个字段为“(o)输出信息/(i)输入信息” 
2.连接ssh成功后写入header
sshsession = client.get_transport().open_session()sshsession.get_pty()sshsession.invoke_shell()asciinemadir = settings.BASE_DIR + '/static/asciinemadir/' #定义一个存放文件的目录(喜欢的也可以保存在数据库)if not os.path.isdir(asciinemadir):os.makedirs(asciinemadir)starttime=time.strftime("%Y%m%d%H%M%S") #用于记录开始时间filena =ip+starttime#文件名 , 用ip+开始时间为文件名date=time.time()#开始时间戳print(date)header = {"version": 2,"width": 160,"height": 48,"timestamp": date,#开始时间戳"env": {"SHELL": "/bin/bash","TERM": "xterm-256color"},"title": "video"}writedata= https://www.isolves.com/it/wl/rj/2021-10-13/open(asciinemadir + filena, 'w') #打开文件writedata.write(json.dumps(header) + 'n')#将header写入文件 
3.将开头两条输出信息以特定的格式写入文件中
for i in range(2):messa = sshsession.recv(1024)request.websocket.send(messa)demessa = messa.decode('utf-8')iodata = https://www.isolves.com/it/wl/rj/2021-10-13/[time.time() - date, 'o', f'{demessa}'] #构造格式writedata.write(json.dumps(iodata)+'n') #写入文件 
4.将线程监听回来的所有输出信息以特定的格式写入文件中
def srecv():while True:sshmess = sshsession.recv(2048)if not len(sshmess):print('退出监听发送循环,并关闭写入文件')writedata.close()#如果不再监听通道 , 则关闭文件breakrequest.websocket.send(sshmess)print('ssh回复的信息:' + sshmess.decode('utf-8'))print(len(sshmess))desshmess = sshmess.decode('utf-8')iodata2 = [time.time() - date, 'o', f'{desshmess}']#构造格式writedata.write(json.dumps(iodata2) + 'n')#写进文件【简单分析实现运维利器---web远程ssh终端录像回放】 
5.创建html页面展示回访列表
在创建html前需要创建一个新的表用于存放录像列表的信息
models下:
class video(models.Model):hostaddress = models.CharField(max_length=255)username = models.CharField(max_length=255)filename = models.CharField(max_length=255)starttime = models.CharField(max_length=255)overtime = models.CharField(max_length=255)####(创建好列表信息后需要进行数据库记录与迁移Python manage.py makemigrations与python manage.py migrate)接着在关闭websocket时创建一条数据 , 并且在关闭websocket时也关闭文件 , 判断是否关闭只要用try异常机制即可 。


推荐阅读