import tornado
from tornado.web import Application
from tornado.web import RequestHandler
from tornado.websocket import WebSocketHandler
import os
import json
template = '''<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Document</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script type="text/javascript" charset="utf-8">
$(function() {
if (typeof String.prototype.startsWith != 'function') {
String.prototype.startsWith = function (prefix){
return this.slice(0, prefix.length) === prefix;
};
}
var output = $("#stdout-output").html();
function addToOutput(msg) {
/* output = $("#output").html() + '<br/>' + msg;*/
if (msg.startsWith('stderr:')) {
if (!$('a[href="#stderr"]').hasClass("alarm-report") && $('ul[role="tablist"] li.active a').attr('href') != '#stderr') {
$('a[href="#stderr"]').addClass("alarm-report")
}
output = $("#stderr-output").html() + msg.replace(/^stderr:/,'');
$("#stderr-output").html(output);
$('#stderr-output').scrollTop($('#stderr-output')[0].scrollHeight);
}else {
if (!$('a[href="#stdout"]').hasClass("alarm-report") && $('ul[role="tablist"] li.active a').attr('href') != '#stdout') {
$('a[href="#stdout"]').addClass("alarm-report")
}
output = $("#stdout-output").html() + msg.replace(/^stdout:/,'');
$("#stdout-output").html(output);
$('#stdout-output').scrollTop($('#stdout-output')[0].scrollHeight);
}
}
$('a#clear').click(function() {
var active_tab = $('ul[role="tablist"] li.active a').attr('href');
$(active_tab + '-output').html('');
})
$('a#load').click(function() {
var active_tab = $('ul[role="tablist"] li.active a').attr('href');
ws.send(JSON.stringify({room:'load',msg:active_tab.replace(/^#/,'')}));
})
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
if ($(e.target).hasClass("alarm-report")) {
$(e.target).removeClass("alarm-report")
}
})
if ("MozWebSocket" in window) {
WebSocket = MozWebSocket;
}
if (WebSocket) {
var ws = new WebSocket("ws://%s/show");
ws.onopen = function() {};
ws.onmessage = function (evt) {
addToOutput(evt.data);
};
ws.onclose = function() {};
} else {
alert("WebSocket not supported");
}
})
</script>
<style type="text/css">
.input-group {
margin-bottom: 5px;
}
.input-group-addon {
background-color:#337ab7;
color:#fff;
border-color:#337ab7;
}
li[aria-selected="true"] {
display:none;
}
li[role="presentation"] a{
border-bottom-left-radius:0;
border-bottom-right-radius:0;
}
.well {
color:#eee;
border-top:0;
border-top-left-radius:0;
border-top-right-radius:0;
}
#stdout-output,#stderr-output {
background-color:#333;
height:600px;
overflow-y:auto;
padding:10px;
}
.alarm-report {
border:2px solid #333;
border-bottom:none;
animation: flash 1s linear infinite;
}
@keyframes flash{
from {
border-color: #333;
}
to {
border-color: red;
}
}
</style>
</head>
<body>
<div class="row">
<div class="col-md-offset-2 col-md-8">
<!-- Nav tabs -->
<ul class="nav nav-pills nav-justified" role="tablist">
<li role="presentation" class="active">
<a href="#stdout" aria-controls="stdout" role="tab" data-toggle="tab">标准输出</a>
</li>
<li role="presentation">
<a href="#stderr" aria-controls="stderr" role="tab" data-toggle="tab">错误输出</a>
</li>
<li role="presentation">
<a href="javascript:void(0);" id="load">载入历史</a>
</li>
<li role="presentation">
<a href="javascript:void(0);" id="clear">清空</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="stdout">
<pre contentEditable="false" class="well" id="stdout-output"></pre>
</div>
<div role="tabpanel" class="tab-pane" id="stderr">
<pre contentEditable="false" class="well" id="stderr-output"></pre>
</div>
</div>
</div>
</div>
</body>
</html>
'''
def create_app():
handlers = [(r"/", AnsibleHandler), (r'/show', CommandHandler)]
app = Application(
handlers=handlers, debug=True, cookie_secret='asdadasdadasdasdasda')
return app
class cd(object):
def __init__(self, newPath):
self.newPath = os.path.expanduser(newPath)
def __enter__(self):
self.savedPath = os.getcwd()
os.chdir(self.newPath)
def __exit__(self, etype, value, traceback):
os.chdir(self.savedPath)
class AnsibleHandler(RequestHandler):
def get(self):
self.write(template % (self.request.host))
class CommandHandler(WebSocketHandler):
def open(self):
print("WebSocket opened")
LISTENERS.append(self)
def on_message(self, message):
message = json.loads(message)
# self.write_message(u"You said: " + message['msg'])
if message['room'] == 'load':
out_file = STDOUT_FILENAME if message[
'msg'] == 'stdout' else STDERR_FILENAME
if os.path.getsize(out_file) > 10240000:
self.write_message('file is too large!')
else:
with open(out_file, 'r') as f:
f.seek(0, os.SEEK_END)
fsize = f.tell()
f.seek(max(fsize - 1024, 0), 0)
for line in f.readlines()[-800:]:
self.write_message('{}:{}'.format(message['msg'],
line))
def on_close(self):
print("WebSocket closed")
try:
LISTENERS.remove(self)
except:
pass
def tail_file():
where = stdout_file.tell()
line = stdout_file.readline()
if not line:
stdout_file.seek(where)
else:
for element in LISTENERS:
element.write_message('stdout:{}'.format(line))
where = stderr_file.tell()
line = stderr_file.readline()
if not line:
stderr_file.seek(where)
else:
for element in LISTENERS:
element.write_message('stderr:{}'.format(line))
if __name__ == '__main__':
STDOUT_FILENAME = 'logs/tail.log'
STDERR_FILENAME = 'logs/tail_err.log'
STDOUT_FILENAME = os.path.abspath(STDOUT_FILENAME)
STDERR_FILENAME = os.path.abspath(STDERR_FILENAME)
LISTENERS = []
stdout_file = open(STDOUT_FILENAME)
stderr_file = open(STDERR_FILENAME)
stdout_file.seek(os.path.getsize(STDOUT_FILENAME))
stderr_file.seek(os.path.getsize(STDERR_FILENAME))
app = create_app()
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(8000, '0.0.0.0')
tailed_callback = tornado.ioloop.PeriodicCallback(tail_file, 5)
tailed_callback.start()
io_loop = tornado.ioloop.IOLoop.instance()
try:
io_loop.start()
except SystemExit as KeyboardInterrupt:
io_loop.stop()
stdout_file.close()
stderr_file.close()
NO CONTENTS