运维开发:python websocket网页实时显示远程服务器日志信息
功能:用websocket技术,在运维工具的浏览器上实时显示远程服务器上的日志信息
一般我们在运维工具部署环境的时候,需要实时展现部署过程中的信息,或者在浏览器中实时显示程序日志给开发人员看。你还在用ajax每隔段时间去获取服务器日志?out了,试试用websocket方式吧
我用bottle框架,写了个websocket服务端,浏览器连接到websocket server,再用python subprocess获取远程服务器的日志信息,subprocess,就是用Popen调用shell的shell命令而已,这样可以获取到实时的日志了,然后再send到websocket server中,那连接到websocket server的浏览器,就会实时展现出来了
用二台服务器来实现这个场景,A服务器是websocket服务端,B服务器是日志端
A服务器是我浏览器本机,websocket服务端也是这台机,IP是:192.168.1.221
B服务器是要远程查看日志的服务器,我这里用:192.168.1.10
以下是A服务器的websocket servet的python代码:
- #!/usr/bin/env python
- #coding=utf-8
- # __author__ = '戴儒锋'
- # http://www.linuxyw.com
- """
- 执行代码前需要安装
- pip install bottle
- pip install websocket-client
- pip install bottle-websocket
- """
- from bottle import get, run
- from bottle.ext.websocket import GeventWebSocketServer
- from bottle.ext.websocket import websocket
- users = set() # 连接进来的websocket客户端集合
- @get('/websocket/', apply=[websocket])
- def chat(ws):
- users.add(ws)
- while True:
- msg = ws.receive() # 接客户端的消息
- if msg:
- for u in users:
- u.send(msg) # 发送信息给所有的客户端
- else:
- break
- # 如果有客户端断开连接,则踢出users集合
- users.remove(ws)
- run(host='0.0.0.0', port=8000, server=GeventWebSocketServer)
记得安装bottle、websocket-client 、bottle-websocket 模块,服务端允许所有的IP访问其8000端口
websocket服务端除了用以上的方法外,还可以用这下面的方法实现:
在电脑桌面,写一个简单的HTML5 javascripts页面,随便命名了,如web_socket.html,这个页面使用了websocket连接到websocket服务端:
- <!DOCTYPE html>
- <html>
- <head>
- </head>
- <style>
- #msg{
- width:400px; height:400px; overflow:auto; border:2px solid #000000;color:#ffffff;
- }
- </style>
- </head>
- <body>
- <p>实时日志</p>
- <div id="msg"></div>
- <script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
- <script>
- $(document).ready(function() {
- /* !window.WebSocket、window.MozWebSocket检测浏览器对websocket的支持*/
- if (!window.WebSocket) {
- if (window.MozWebSocket) {
- window.WebSocket = window.MozWebSocket;
- } else {
- $('#msg').prepend("<p>你的浏览器不支持websocket</p>");
- }
- }
- /* ws = new WebSocket 创建WebSocket的实例 注意设置对以下的websocket的地址哦*/
- ws = new WebSocket('ws://192.168.1.221:8000/websocket/');
- /*
- ws.onopen 握手完成并创建TCP/IP通道,当浏览器和WebSocketServer连接成功后,会触发onopen消息
- ws.onmessage 接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据;
- */
- ws.onopen = function(evt) {
- $('#msg').append('<li>websocket连接成功</li>');
- }
- ws.onmessage = function(evt) {
- $('#msg').prepend('<li>' + evt.data + '</li>');
- }
- });
- </script>
- </body>
- </html>
注意:WebSocket('ws://192.168.1.221:8000/websocket/'); 这里的192.168.1.221一定要改成你的websocket服务端IP,切记!!!
到这里,就搞定浏览器连接到websocket服务端的场景了,现在要A服务器里写一段代码,去采集B服务器的实时信息了,其实采集原理很简单,就是使用shell中的tailf命令,实时显示最新的信息而已,我们在这段脚本中,使用subprocess.Popen()来远程查看日志信息:
python代码如下:
- #!/usr/bin/python
- # encoding=utf-8
- import subprocess
- import time
- from websocket import create_connection
- # 配置远程服务器的IP,帐号,密码,端口等,因我做了双机密钥信任,所以不需要密码
- r_user = "root"
- r_ip = "192.168.1.10"
- r_port = 22
- r_log = "/tmp/web_socket.log" # 远程服务器要被采集的日志路径
- # websocket服务端地址
- ws_server = "ws://192.168.1.221:8000/websocket/"
- # 执行的shell命令(使用ssh远程执行)
- cmd = "/usr/bin/ssh -p {port} {user}@{ip} /usr/bin/tailf {log_path}".format(user=r_user,ip=r_ip,port=r_port,log_path=r_log)
- def tailfLog():
- """获取远程服务器实时日志,并发送到websocket服务端"""
- popen = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
- print('连接成功')
- ws = create_connection(ws_server) # 创建websocket连接
- while True:
- line = popen.stdout.readline().strip() #获取内容
- if line:
- ws.send(line) #把内容发送到websocket服务端
- print time.time()
- if __name__ == '__main__':
- tailfLog()
文章最后再解析subprocess.Popen的原理和功能
执行websocket服务端脚本和上面这个websocket客户端采集脚本,再打开用浏览器打开上面的html5页面后,环境就基本部署好了,双websocket客户端连接到websocket服务端中
上面脚本指定的r_log = "/tmp/web_socket.log"日志路径,我们需要生成这个日志文件,并不停地往里面写入日志,这样才能在浏览器中实时显示效果(真实场景中,可以指定服务器某日志,如apache,nginx日志等)
我们在B服务器写一段python代码,然后每隔一秒就往r_log = "/tmp/web_socket.log"日志中写入内容:
python代码如下:
- #!/usr/bin/env python
- #coding=utf-8
- import time
- import random
- log_path = '/tmp/web_socket.log'
- while 1:
- with open(log_path,'a') as f:
- f.write('[%s] %s \n' % (time.ctime(),random.random()))
- time.sleep(1)
脚本写入的内容大概是:
[Tue Jul 26 18:30:41 2016] 0.527242649654
[Tue Jul 26 18:30:42 2016] 0.21080845298
[Tue Jul 26 18:30:43 2016] 0.23128691356
[Tue Jul 26 18:30:44 2016] 0.689547600796
执行这段脚本,然后看浏览器效果:

这只是我临时写的,如果要在真实的运维工具中使用,还需要根据具体情况,修改不少内容,但原理就是这样,大家可根据自己的情况修改,完善使用。
刚才提到subprocess.Popen的原理和功能,请看以下资料:
http://www.cnblogs.com/fengbeihong/articles/3374132.html
bottle websocket参考资料:
http://rfyiamcool.blog.51cto.com/1030776/1269232/
运维开发:python websocket网页实时显示远程服务器日志信息的更多相关文章
- python websocket网页实时显示远程服务器日志信息
功能:用websocket技术,在运维工具的浏览器上实时显示远程服务器上的日志信息 一般我们在运维工具部署环境的时候,需要实时展现部署过程中的信息,或者在浏览器中实时显示程序日志给开发人员看.你还在用 ...
- python实现websocket服务器,可以在web实时显示远程服务器日志
一.开始的话 使用python简单的实现websocket服务器,可以在浏览器上实时显示远程服务器的日志信息. 之前做了一个web版的发布系统,但没实现在线看日志,每次发布版本后,都需要登录到服务器上 ...
- python2.7实现websocket服务器,可以在web实时显示远程服务器日志
一.开始的话 使用python实现websocket服务器,可以在浏览器上实时显示远程服务器的日志. 之前写了一个发布系统,每次发布版本后,为了了解发布情况(进度.是否有错误)都会登录到服务器上查看日 ...
- Python 开发个人微信号在运维开发中的使用
一.主题:Python 开发个人微信号在运维开发中的使用 二.内容: 企业公众号 介绍开发微信公众号的后台逻辑,包括服务器验证逻辑.用户认证逻辑 个人微信号 面对企业微信的种种限制,可以使用 Itch ...
- Python运维开发基础09-函数基础【转】
上节作业回顾 #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 实现简单的shell命令sed的替换功能 import ...
- Python运维开发基础08-文件基础【转】
一,文件的其他打开模式 "+"表示可以同时读写某个文件: r+,可读写文件(可读:可写:可追加) w+,写读(不常用) a+,同a(不常用 "U"表示在读取时, ...
- Python运维开发基础07-文件基础【转】
一,文件的基础操作 对文件操作的流程 [x] :打开文件,得到文件句柄并赋值给一个变量 [x] :通过句柄对文件进行操作 [x] :关闭文件 创建初始操作模板文件 [root@localhost sc ...
- Python运维开发基础05-语法基础【转】
上节作业回顾(讲解+温习90分钟) #!/usr/bin/env python # -*- coding:utf-8 -*- # author:Mr.chen import os,time Tag = ...
- Python运维开发基础03-语法基础 【转】
上节作业回顾(讲解+温习60分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen #只用变量和字符串+循环实现“用户登陆 ...
随机推荐
- 【bzoj2190】[SDOI2008]仪仗队 欧拉函数
题目描述 作为体育委员,C君负责这次运动会仪仗队的训练.仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图 ...
- Python 开篇及第一个Python程序
本节内容 python 简单介绍 python 2.x 或者python 3.x python 安装 第一个python程序 一.python简单介绍 python的创始人为吉多.范罗苏姆(Guido ...
- 三节点搭建openstack-Mitaka版本
前言: 现在的云计算平台已经非常火,也非常的稳定了.像阿里云平台,百度云平台等等,今天咱们基于openstack来搭建一个云平台 注意: 本次平台搭建为三节点搭建(没有外部存储节点,所有存储为本地存储 ...
- CF#508 1038E Maximum Matching
---题面--- 题解: 感觉还是比较妙的,复杂度看上去很高(其实也很高),但是因为n只有100,所以还是可以过的. 考虑一个很暴力的状态f[i][j][x][y]表示考虑取区间i ~ j的方格,左右 ...
- [JSOI2010]缓存交换 贪心 & 堆
~~~题面~~~ 题解: 首先我们要使得Miss的次数尽量少,也就是要尽量保证每个点在被访问的时候,这个点已经存在于Cache中. 那么我们可以得到一个结论: 如果Cache已满,那么我们就从Cach ...
- [SCOI2008]天平 差分约束
---题面--- 题解: 差分约束学得实在是太烂了,,,,QAQ 这里先记下: a - b >= x ---> a >= b + x ----> b - ...
- 【单调队列】【P1776】宝物筛选
传送门 Description 终于,破解了千年的难题.小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物--这下小FF可发财了,嘎嘎.但是这里的宝物实在是太多了,小FF的采集车似乎装不下那么多宝 ...
- ContextLoaderListener和Spring MVC中的DispatcherServlet加载内容的区别【转】
原文地址:https://blog.csdn.net/py_xin/article/details/52052627 ContextLoaderListener和DispatcherServlet都会 ...
- c++11新特性之nullptr
在c++11中,nullptr可完全代替NULL. 然而NULL和nullptr还是稍有不同,NULL可被转化为int类型,而nullptr不能.因此nullptr对NULL在进行模板推导或者函数重 ...
- ACM1004 Let the balloons fly
These code is for the problem "Let the balloons Fly" in ACM 1004 which need deal with stri ...