浏览器动态显示服务器日志信息集成工具实践
这个任务可以完全只有一句命令行就搞定:
1 | tail -f -n 500 /smapp/servers/tomcat/apache-tomcat-7.0.72/logs/catalina. out |
然而 实际上我们的系统是一个超级分布式的系统,单是内网测试环境涉及的服务器达到20+这个量级,于是单是找某一个服务器的地址也成了一个工作负担
我们运维采用了设置一个跳板机来处理这个事儿
登录跳板机——>SSH 登录到指定服务器
中间还得再输一次账号、密码,记服务器名称,记host也是个头疼的工作,这是我制作这样一个工具的原因之一
另外一点,Xshell 还是 WinSCP 都没法对日志信息为所欲为,我在测试调度功能时日志书写很快很快,看了一上午的调度日志,眼睛也痛了。痛定思痛,思前想后还得自己写个工具。
下面言归正传,说一说整体的实现:
1.后端部分
找到想要打印日志的服务器 ,在这个服务器上运行一个websocket进程供前端请求,而这个websocket执行服务器上的一个shell脚本,这个脚本打印我想要的日志
下载一个websocketd 程序到 /usr/local/websocketd 目录,这个程序不需要编译,可以直接运行
创建一个cmd.sh 这个脚本完成打印我们想要日志的工作
#!/bin/bash while :; do tail -f -n200 /smapp/servers/tomcat/apache-tomcat-7.0.72/logs/catalina.out
done
命令行运作:
./websocketd --port=8008 --staticdir=. ./cmd.sh
这个时候输出的就是打印日志的内容,这里需要注意端口不要与其他进程冲突了
ctrl+C 退出后进程就会结束,但是实际上我们想要这个进程一直一直在运行,所有需要优化下命令行
nohup ./websocketd --port=8008 --staticdir=. ./cmd.sh &
运行后不再打印输出,我们可以退出服务器连接,这个进程将会在后台一直跑
2.前端部分
首先得有台网页服务器放我们的导航页面,我找了内网151这台机,找到 /usr/local/nginx/conf 下面的 nginx.conf
添加一个 location
location /download { autoindex on; alias /var/www/html/download/; index index.html index.htm; }
把导航页放在
/var/www/html/download/ 这个路径下
导航页简陋一点,就是一些超链接,页面如下
<!doctype html> <html> <head> <meta http-equiv="Content-Type" content="text/html"; charset="UTF-8"/> <title>日志中心</title> <style type="text/css"> .table1{ width:100%; border-bottom:1px; background:#f3f3f3 ; text-align:center; } </style> </head> <body> <div id="test"> <hr> <p style=" text-align:center;">测试环境专车日志</p> <hr> <table class="table1" cellspacing="1" cellpadding="4" border="1"> <tr> <th>乘客端</th> <th>司机端</th> <th>调度</th> <th>订单</th> <th>用户中心</th> <th>管理系统</th> </tr> <tr> <th><a href="http://192.168.3.151:9000/download/log/log_PassengerProvider.html" target="_blank">provider</a></th> <th><a href="http://192.168.3.151:9000/download/log/log_driverProvider.html" target="_blank">provider</a></th> <th><a href="http://192.168.3.151:9000/download/log/log_dispatch.html" target="_blank">provider</a></th> <th><a href="http://192.168.3.151:9000/download/log/log_orderProvider.html" target="_blank">provider</a></th> <th><a href="http://192.168.3.151:9000/download/log/log_UserCenterProvider.html" target="_blank">provider</a></th> <th></th> </tr> <tr> <th><a href="http://192.168.3.151:9000/download/log/log_gwPassenger.html" target="_blank">gw</a></th> <th><a href="http://192.168.3.151:9000/download/log/log_gwDriver.html" target="_blank">gw</a> <a href="http://192.168.3.151:9000/download/log/log_code_driver.html" target="_blank">验证码</a></th> <th><a href="http://192.168.3.151:9000/download/log/visual_dispath.html" target="_blank">调度可视化</a></th> <th></th> <th><a href="http://192.168.3.151:9000/download/log/log_code.html" target="_blank">验证码</a></th> <th></th> </tr> </table> </div> <hr> <div id = "taxi"> <p style=" text-align:center;">测试环境出租车日志</p> <hr> <table class="table1" cellspacing="1" cellpadding="4" border="1"> <tr> <th>乘客端</th> <th>司机端</th> <th>调度</th> <th>订单</th> <th>中控</th> <th>管理系统</th> </tr> <tr> <th><a href="http://192.168.3.151:9000/download/log/taxi_log_PassengerProvider.html" target="_blank">provider</a></th> <th><a href="http://192.168.3.151:9000/download/log/taxi_log_driverProvider.html" target="_blank">provider</a></th> <th><a href="http://192.168.3.151:9000/download/log/taxi_log_dispatch.html" target="_blank">provider</a></th> <th><a href="http://192.168.3.151:9000/download/log/taxi_log_orderProvider.html" target="_blank">provider</a></th> <th><a href="http://192.168.3.151:9000/download/log/taxi_log_centorcontrolprovider.html" target="_blank">provider</a></th> <th></th> </tr> <tr> <th><a href="http://192.168.3.151:9000/download/log/taxi_log_gwPassenger.html" target="_blank">gw</a></th> <th><a href="http://192.168.3.151:9000/download/log/taxi_log_gwDriver.html" target="_blank">gw</a></th> <th><a href="http://192.168.3.151:9000/download/log/visual_taxi_dispath.html" target="_blank">调度可视化</a></th> <th></th> <th><a href="http://192.168.3.151:9000/download/log/taxi_log_centorcontrolgw.html" target="_blank">gw</a></th> <th></th> </tr> </table> </div> <hr> <div id = "Pre-release"> <p style=" text-align:center;">预发布专车日志</p> <hr> <table class="table1" cellspacing="1" cellpadding="4" border="1"> <tr> <th>乘客端</th> <th>司机端</th> <th>调度</th> <th>订单</th> <th>用户中心</th> <th>管理系统</th> </tr> <tr> <th><a href="http://192.168.3.151:9000/download/log/pre-log_PassengerProvider.html" target="_blank">provider</a></th> <th><a href="http://192.168.3.151:9000/download/log/pre-log_driverProvider.html" target="_blank">provider</a></th> <th><a href="http://192.168.3.151:9000/download/log/pre-log_dispatch.html" target="_blank">provider</a></th> <th><a href="http://192.168.3.151:9000/download/log/pre-log_orderProvider.html" target="_blank">provider</a></th> <th><a href="http://192.168.3.151:9000/download/log/pre-log_UserCenterProvider.html" target="_blank">provider</a></th> <th></th> </tr> <tr> <th><a href="http://192.168.3.151:9000/download/log/pre-log_gwPassenger.html" target="_blank">gw</a></th> <th><a href="http://192.168.3.151:9000/download/log/pre-log_gwDriver.html" target="_blank">gw</a> <a href="http://192.168.3.151:9000/download/log/pre-log_code_driver.html" target="_blank">验证码</a></th> <th></th> <th></th> <th><a href="http://192.168.3.151:9000/download/log/pre-log_code.html" target="_blank">验证码</a></th> <th></th> </tr> </table> </div> <hr> <p style=" text-align:right;">技术支持请联系:老王</p> <p style=" text-align:right;">QQ:316707959</p> </body> </html>
实际页面效果
每一个超链接对应着一个html页面,这个html页面读取websocket的输出信息并且显示在网页上,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | <!DOCTYPE html> <html> <head> <title>dispatch-provider实时日志</title> <meta http-equiv= "Content-Type" content= "text/html" ; charset= "UTF-8" /> <style> body{ background-color: #0e1012;color: #ffffff; } *{ margin: 0; padding: 0; } #msg{ overflow:auto; border:2px solid #303030; color:#ffffff; background-color: #2b2b2b; font-size: 15px; position: absolute; left: 8px; right: 8px; bottom: 8px; top: 40px; word- break : break -all; } #log{ position: fixed ; top: 0; left: 0; width: 100%; height: 40px; text-align: center; margin: 4px 0 0 8px; } #log b{ font-size: 26px; } .msgBtn1{ padding: 5px 10px; border: none; background: red; float : right; margin: 0 16px 0 0; } </style> </head> <body> <div id= "log" ><span><b>测试环境dispatch-provider实时日志</b></span> <button id= "msgBtn" class = "msgBtn1" type= "button" >清空</button> <button id= "msgBtn_pause" class = "msgBtn1" type= "button" onclick= "msgBtn_pause_click()" >暂停</button> <button id= "startBtn" class = "msgBtn1" type= "button" style= "float: left" onclick= "start_click()" >启动</button> <button id= "shutdownBtn" class = "msgBtn1" type= "button" style= "float: left" onclick= "shutdown_click()" >关闭</button> <button id= "msgBtn_check_y" class = "msgBtn1" style= "background:yellow;color:red" type= "button" onclick= "msgBtn_check_y_click()" >高亮监控:黄</button> <button id= "msgBtn_check_b" class = "msgBtn1" style= "background: blue;color:white" type= "button" onclick= "msgBtn_check_b_click()" >高亮监控:蓝</button> </div> <div id= "msg" > <ul class = "list" ></ul> </div> <script src= "http://libs.baidu.com/jquery/1.9.1/jquery.min.js" ></script> <script> var sw = 0; var check_str_y = localStorage.y; var check_str_back_y = null ; var check_str_b = localStorage.b; var check_str_back_b = null ; var but_pause = document.getElementById( "msgBtn_pause" ); $(document).ready(function() { if (!window.WebSocket) { if (window.MozWebSocket) { window.WebSocket = window.MozWebSocket; } else { $( '#msg' ).append( "<p>你的浏览器不支持websocket</p>" ); } } var ws = new WebSocket( 'ws://10.28.17.190:8008/websocket/' ); ws.onopen = function(evt) { $( '.list' ).append( '<li>连接成功,开始读取日志内容</li>' ); } ws.onmessage = function(evt) { if (evt.data.indexOf( "ERROR" ) != -1 || evt.data.indexOf( "Exception" ) != -1) { $( '.list' ).append( '<li style="color: yellow;background-color:red;font-size: 18px ">' + evt.data + '</li>' ); } else { if (evt.data.indexOf( "at" ) != 1) { if (evt.data.indexOf(check_str_y) != -1||evt.data.indexOf(check_str_b) != -1) { if (evt.data.indexOf(check_str_y) != -1) { $( '.list' ).append( '<li style="color: red;background-color:yellow;font-size: 18px ">' + evt.data + '</li>' ); } if (evt.data.indexOf(check_str_b) != -1) { $( '.list' ).append( '<li style="color: white;background-color:blue;font-size: 18px ">' + evt.data + '</li>' ); } } else { $( '.list' ).append( '<li>' + evt.data + '</li>' ); } } } if (sw==0) { setTimeout(function(){ $( '#msg' ).scrollTop($( '.list' ).height()-$( '#msg' ).height()); }, 100) } } $( "#msgBtn" ).click(function(){ $( ".list" ).html( "" ); }) }); function msgBtn_pause_click(){ if (but_pause.innerText == "暂停" ) { but_pause.innerText = "继续" ; but_pause.style = "background:green" ; sw = 1; } else { but_pause.innerText = "暂停" ; but_pause.style = "background:red" ; sw = 0; } } function msgBtn_check_b_click(){ check_str_back_b =check_str_b; check_str_b = prompt( "请输入需要高亮显示的文本行关键字:" ,check_str_b); if (check_str_b == null ) { check_str_b = check_str_back_b; } localStorage.setItem( 'b' ,check_str_b); } function msgBtn_check_y_click(){ check_str_back_y =check_str_y; check_str_y = prompt( "请输入需要高亮显示的文本行关键字:" ,check_str_y); if (check_str_y == null ) { check_str_y = check_str_back_y; } localStorage.setItem( 'y' ,check_str_y); } function start_click(){ var ws2 = new WebSocket( 'ws://10.28.17.190:8019/websocket/' ); } function shutdown_click(){ var ws3 = new WebSocket( 'ws://10.28.17.190:8029/websocket/' ); } </script> </body> </html> |
实际效果如下:
在读取到websocket返回的信息后,我可以对信息进行各种各样我们想要的操作,过滤无用信息,标注重要信息,可以说是进退自如、为所欲为
这里我还加入了关键字的高亮监控,需要高亮显示的信息保存在本里缓存里,关闭、刷新浏览器也不会清除到这个内容,这个功能在日志书写较快,而关键信息稍纵即逝的场景里非常实用
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步