mirror of https://github.com/jumpserver/jumpserver
for log monitor
parent
ebe8ce7109
commit
50d21fcdca
|
@ -5,8 +5,9 @@ from jlog.views import *
|
|||
urlpatterns = patterns('',
|
||||
url(r'^$', log_list),
|
||||
url(r'^log_list/(\w+)/$', log_list),
|
||||
# url(r'^log_kill/', log_kill),
|
||||
url(r'^history/$', log_history),
|
||||
# url(r'^log_kill/', log_kill),
|
||||
url(r'^record/$', log_record),
|
||||
url(r'^search/$', log_search),
|
||||
url(r'^monitor/$', log_monitor),
|
||||
)
|
|
@ -110,6 +110,11 @@ def log_search(request):
|
|||
print request.GET
|
||||
return render_to_response('jlog/log_filter.html', locals())
|
||||
|
||||
|
||||
def log_monitor(request):
|
||||
return my_render('jlog/log_monitor.html', locals(), request)
|
||||
|
||||
|
||||
# def log_search(request):
|
||||
# """ 日志搜索 """
|
||||
# offset = request.GET.get('env', '')
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
import time
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import os.path
|
||||
|
||||
import tornado.ioloop
|
||||
|
@ -11,10 +13,52 @@ import tornado.websocket
|
|||
import tornado.httpserver
|
||||
|
||||
from tornado.options import define, options
|
||||
from pyinotify import WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE, IN_MODIFY
|
||||
|
||||
define("port", default=8080, help="run on the given port", type=int)
|
||||
|
||||
|
||||
class EventHandler(ProcessEvent):
|
||||
def __init__(self, client=None):
|
||||
self.client = client
|
||||
|
||||
def process_IN_CREATE(self, event):
|
||||
print "Create file:%s." % os.path.join(event.path, event.name)
|
||||
|
||||
def process_IN_DELETE(self, event):
|
||||
print "Delete file:%s." % os.path.join(event.path, event.name)
|
||||
|
||||
def process_IN_MODIFY(self, event):
|
||||
print "Modify file:%s." % os.path.join(event.path, event.name)
|
||||
self.client.write_message(f.read())
|
||||
|
||||
|
||||
def file_monitor(path='.', client=None):
|
||||
wm = WatchManager()
|
||||
mask = IN_DELETE | IN_CREATE | IN_MODIFY
|
||||
notifier = Notifier(wm, EventHandler(client))
|
||||
wm.add_watch(path, mask, auto_add=True, rec=True)
|
||||
if not os.path.isfile(path):
|
||||
print "You should monitor a file"
|
||||
sys.exit(3)
|
||||
else:
|
||||
print "now starting monitor %s." %path
|
||||
global f
|
||||
f = open(path, 'r')
|
||||
st_size = os.stat(path)[6]
|
||||
f.seek(st_size)
|
||||
|
||||
while True:
|
||||
try:
|
||||
notifier.process_events()
|
||||
if notifier.check_events():
|
||||
notifier.read_events()
|
||||
except KeyboardInterrupt:
|
||||
print "keyboard Interrupt."
|
||||
notifier.stop()
|
||||
break
|
||||
|
||||
|
||||
class Application(tornado.web.Application):
|
||||
def __init__(self):
|
||||
handlers = [
|
||||
|
@ -34,21 +78,25 @@ class Application(tornado.web.Application):
|
|||
class SendHandler(tornado.websocket.WebSocketHandler):
|
||||
clients = set()
|
||||
|
||||
def check_origin(self, origin):
|
||||
return True
|
||||
|
||||
def open(self):
|
||||
SendHandler.clients.add(self)
|
||||
self.write_message(json.dumps({'input': 'connected...'}))
|
||||
self.stream.set_nodelay(True)
|
||||
|
||||
def on_message(self, message):
|
||||
message = json.loads(message)
|
||||
self.write_message(json.dumps({'input': 'response...'}))
|
||||
while True:
|
||||
self.write_message(json.dumps(message))
|
||||
time.sleep(1)
|
||||
self.write_message(message)
|
||||
# while True:
|
||||
# self.write_message(json.dumps(message))
|
||||
# time.sleep(1)
|
||||
# # 服务器主动关闭
|
||||
# self.close()
|
||||
# SendHandler.clients.remove(self)
|
||||
|
||||
file_monitor('/opt/jumpserver/logs/tty/20151102/a_b_191034.log', client=self)
|
||||
self.write_message('monitor /tmp/test1234')
|
||||
|
||||
def on_close(self):
|
||||
# 客户端主动关闭
|
||||
SendHandler.clients.remove(self)
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Jumpserver | 开源跳板机系统</title>
|
||||
|
||||
<link rel="shortcut icon" href="/static/img/facio.ico" type="image/x-icon">
|
||||
{% include 'link_css.html' %}
|
||||
{% include 'head_script.html' %}
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div class="col-lg-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<h5> 实时监控 </h5>
|
||||
</div>
|
||||
|
||||
<div class="ibox-content blank-panel" id="content" style="background-color: #0b0b0b; color: #006621; height: 500px; padding: 20px;">
|
||||
你好<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
{% block self_footer_js %}
|
||||
<script>
|
||||
function monitor(){
|
||||
var wsUri = 'ws://j:8080/send';
|
||||
var ws = new WebSocket(wsUri);
|
||||
ws.onopen = function(evt){
|
||||
$('#content').append('Connect websocket success' + '<br />');
|
||||
ws.send('Start')
|
||||
};
|
||||
|
||||
ws.onmessage = function(evt){
|
||||
console.log(evt.data);
|
||||
$('#content').append(evt.data.replace('\r\n', '<br />').replace('[\r\n]', '<br />'));
|
||||
};
|
||||
|
||||
ws.onclose = function(evt){
|
||||
$('#content').append('Disconnect with websocket')
|
||||
}
|
||||
}
|
||||
|
||||
monitor();
|
||||
</script>
|
||||
{% endblock %}
|
||||
</html>
|
|
@ -97,84 +97,14 @@
|
|||
</div>
|
||||
|
||||
|
||||
<script src="http://{{ web_socket_host }}/socket.io/socket.io.js"></script>
|
||||
{#<script src="http://{{ web_socket_host }}/socket.io/socket.io.js"></script>#}
|
||||
<script>
|
||||
$.fn.webSocket = function(opt){
|
||||
var st = {};
|
||||
st = $.extend(st,opt);
|
||||
var message = {};
|
||||
var $this = $(this);
|
||||
var genUid = function(){
|
||||
return new Date().getTime()+""+Math.floor(Math.random()*899+100);
|
||||
};
|
||||
var init = function(e){
|
||||
var socket = io.connect('ws://'+globalConfig.SOCKET_HOST);
|
||||
var node = $(e.target);
|
||||
message.id = genUid();
|
||||
message.filename = node.attr('filename');
|
||||
var username = $('#username')[0].innerText;
|
||||
var ip = $('#ip')[0].innerText;
|
||||
BootstrapDialog.show({message:function(){
|
||||
var option, exsit_message;
|
||||
var escapeString = function (html){
|
||||
var elem = document.createElement('div');
|
||||
var txt = document.createTextNode(html);
|
||||
elem.appendChild(txt);
|
||||
return elem.innerHTML;
|
||||
};
|
||||
var tag = $('<div id="log" style="height: 500px;overflow: auto;background-color: rgba(0, 0, 0, 0);"></div>');
|
||||
|
||||
var username = "";
|
||||
var seed = "";
|
||||
document.cookie.split('; ').forEach(function(obj){
|
||||
var info = obj.split('=');
|
||||
if(info.length == 2 ){
|
||||
if(info[0] == 'username'){
|
||||
username = info[1];
|
||||
}else if(info[0] == 'seed'){
|
||||
seed = info[1];
|
||||
}
|
||||
}
|
||||
$(document).ready(function(){
|
||||
$('.monitor').click(function(){
|
||||
window.open('/jlog/monitor/', '监控', 'height=500, width=910, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no');
|
||||
})
|
||||
});
|
||||
|
||||
//告诉服务器端有用户登录
|
||||
socket.emit('login', {userid:message.id, filename:message.filename,username:username,seed:seed});
|
||||
socket.on('message',function(obj){
|
||||
option = obj.option;
|
||||
console.log(option+'so')
|
||||
exsit_message = obj.content;
|
||||
console.log(obj.content)
|
||||
//去除log中的颜色控制字符
|
||||
var regx = /\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]/g;
|
||||
// tag.append('<p>'+escapeString(obj.content.replace(regx,''))+'</p>');
|
||||
if (option == 'new') {
|
||||
// tag.append('<p style="margin: 2px">' + escapeString(obj.content) + '</p>');
|
||||
tag.append('<p style="margin: 2px">'+escapeString(obj.content.replace(regx,' '))+'</p>');
|
||||
} else if (option == 'exist') {
|
||||
tag.append('<pre>' + exsit_message + '</pre>');
|
||||
}
|
||||
tag.animate({ scrollTop: tag[0].scrollHeight}, 1);
|
||||
});
|
||||
tag[0].style.color = "#00FF00";
|
||||
return tag[0];
|
||||
} ,
|
||||
title:'Jumpserver实时监控 '+' 登录用户名: '+'<span class="text-info">'+username+'</span>'+' 登录主机: '+'<span class="text-info">'+ip,
|
||||
onhide:function(){
|
||||
socket.emit('disconnect');
|
||||
}});
|
||||
};
|
||||
$this.on("click",function(e){
|
||||
init(e);
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
globalConfig = {
|
||||
SOCKET_HOST: "{{ web_socket_host }}"
|
||||
};
|
||||
$(".monitor").webSocket();
|
||||
|
||||
function log_search(){
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
|
@ -210,6 +140,8 @@
|
|||
log_search()
|
||||
}
|
||||
});
|
||||
|
||||
$('')
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -69,36 +69,70 @@
|
|||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="test">
|
||||
<form class="form-horizontal" role="form">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h5 class="panel-title">>>输入</h5>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<div class="col-md-8">
|
||||
<input type="text" class="form-control" id="input_data" value="">
|
||||
{# <div id="test">#}
|
||||
{# <form class="form-horizontal" role="form">#}
|
||||
{# <div class="panel panel-default">#}
|
||||
{# <div class="panel-heading">#}
|
||||
{# <h5 class="panel-title">>>输入</h5>#}
|
||||
{# </div>#}
|
||||
{# <div class="panel-body">#}
|
||||
{# <div class="form-group">#}
|
||||
{# <div class="col-md-8">#}
|
||||
{# <input type="text" class="form-control" id="input_data" value="">#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# <div class="form-group">#}
|
||||
{# <div class="col-md-8">#}
|
||||
{# <input type="button" class="btn btn-success" id="input_1_btn" onclick="connect();" value="连接" />#}
|
||||
{# <input type="button" class="btn btn-success" id="input_btn" onclick="send();" value="查看" />#}
|
||||
{# <input type="button" class="btn btn-success" id="input_2_btn" onclick="close();" value="关闭" />#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </form>#}
|
||||
{# <div class="panel panel-default">#}
|
||||
{# <div class="panel-heading">#}
|
||||
{# <h5 class="panel-title">>> 输出</h5>#}
|
||||
{# </div>#}
|
||||
{# <div class="panel-body">#}
|
||||
{# <div id="message"></div>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
<div class="col-lg-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title" style="border: solid">
|
||||
<h5> 实时监控 </h5>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapise-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
</a>
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-md-8">
|
||||
<input type="button" class="btn btn-success" id="input_1_btn" onclick="connect();" value="连接" />
|
||||
<input type="button" class="btn btn-success" id="input_btn" onclick="send();" value="发送" />
|
||||
<input type="button" class="btn btn-success" id="input_2_btn" onclick="close();" value="关闭" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h5 class="panel-title">>> 输出</h5>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div id="message"></div>
|
||||
|
||||
<div class="ibox-content blank-panel" style="background-color: #0b0b0b; color: #006621; height: 500px; padding: 20px;">
|
||||
你好<br>
|
||||
你好<br>
|
||||
你好<br>
|
||||
你好你好你好<br>
|
||||
你好<br>
|
||||
你好<br>
|
||||
你好<br>
|
||||
你好<br>
|
||||
你好<br>
|
||||
你好<br>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
|
@ -1,74 +0,0 @@
|
|||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf8'>
|
||||
<script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
.blue
|
||||
{
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
{#<script>#}
|
||||
{#$('html').ajaxSend(function(event, xhr, settings) {#}
|
||||
{# function getCookie(name) {#}
|
||||
{# var cookieValue = null;#}
|
||||
{# if (document.cookie && document.cookie != '') {#}
|
||||
{# var cookies = document.cookie.split(';');#}
|
||||
{# for (var i = 0; i < cookies.length; i++) {#}
|
||||
{# var cookie = jQuery.trim(cookies[i]);#}
|
||||
{# // Does this cookie string begin with the name we want?#}
|
||||
{# if (cookie.substring(0, name.length + 1) == (name + '=')) {#}
|
||||
{# cookieValue = decodeURIComponent(cookie.substring(name.length + 1));#}
|
||||
{# break;#}
|
||||
{# }#}
|
||||
{# }#}
|
||||
{# }#}
|
||||
{# return cookieValue;#}
|
||||
{# }#}
|
||||
{# if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {#}
|
||||
{# // Only send the token to relative URLs i.e. locally.#}
|
||||
{# xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));#}
|
||||
{# }#}
|
||||
{#});#}
|
||||
{#</script>#}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$("#btn1").click(function(){
|
||||
$("#test").text(function(i,origText){
|
||||
return "Old text: " + origText + "New text: Hllo" + i
|
||||
})
|
||||
});
|
||||
|
||||
$("#btn2").click(function(){
|
||||
$.post('/test_ajax/',
|
||||
{'name': 'join', 'age': 10},
|
||||
function(data, status){
|
||||
$('#btn1').text(data)
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
$("#btn3").click(function(){
|
||||
$("p").toggleClass('blue')
|
||||
// $("p").addClass('blue')
|
||||
// $("p").before("Some thine")
|
||||
});
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p id="test" class="blue">
|
||||
这是段落中的<b>粗体</b>文本。
|
||||
<p><span>hello</span></p>
|
||||
|
||||
</p>
|
||||
<!-- <input type="text" id="test2" name="nameaaaaaaaaaa" value="米老鼠"> -->
|
||||
<button id="btn1">显示文本</button>
|
||||
<button id="btn2">显示 HTML</button>
|
||||
<button id="btn3">显示 value</button>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>Poem Maker Pro</title></head>
|
||||
<body>
|
||||
<h1>Your poem</h1>
|
||||
<p>Two {{roads}} diverged in a {{wood}}, and I—<br>
|
||||
I took the one less travelled by,<br>
|
||||
And that has {{made}} all the {{difference}}.</p>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue