這個任務可以完全只有一句命令行就搞定:
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的輸出信息並且顯示在網頁上,代碼如下
<!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返回的信息后,我可以對信息進行各種各樣我們想要的操作,過濾無用信息,標注重要信息,可以說是進退自如、為所欲為
這里我還加入了關鍵字的高亮監控,需要高亮顯示的信息保存在本里緩存里,關閉、刷新瀏覽器也不會清除到這個內容,這個功能在日志書寫較快,而關鍵信息稍縱即逝的場景里非常實用
