• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

django+tornado实现实时查看远程日志的方法

python 搞代码 4年前 (2022-01-09) 21次浏览 已收录 0个评论

大致思路:

1.利用tornado提供的websocket功能与浏览器建立长连接,读取实时日志并输出到浏览器

2.写一个实时读取日志的脚本,利用saltstack远程执行,并把实时日志发往redis中。来源gaodai#ma#com搞@代~码$网

3.tornado读取redis中的信息,发往浏览器。

此过程用到了redis的发布和订阅功能。

先看一下tornado中是如何处理的:

import os
import sys
import tornado.websocket
import tornado.web
import tornado.ioloop
import redis
import salt.client

from tornado import gen
from tornado.escape import to_unicode

from logs.utility import get_last_lines
from logs import settings


class SubWebSocket(tornado.websocket.WebSocketHandler):
 """
 此handler处理远程日志查看
 """
 def open(self, *args, **kwargs):
  print("opened")

 @gen.coroutine
 def on_message(self, message):
  # 主机名,要查看的日志路径,运行脚本的命令这些信息从浏览器传过来
  hostname, log_path, cmd = message.split("||")
  local = salt.client.LocalClient()
  r = redis.StrictRedis(host=settings.REDIS_HOST, port=settings.REDIS_PORT,
        password=settings.REDIS_PASSWD, db=5)
  # 订阅频道,服务器和日志路径确定一个频道
  key = settings.LOG_KEY.format(server=hostname.strip(), log_path=log_path.strip())
  channel = r.pubsub()
  channel.subscribe(key)
  # 异步方式执行命令,远程运行脚本
  local.cmd_async(hostname, "cmd.run", [cmd])
  try:
   while True:
    data = channel.get_message()
    if not data:
     # 如果读取不到消息,间隔一定时间,避免无谓的CPU消耗
     yield gen.sleep(0.05)
     continue
    if data["type"] == "message":
     line = format_line(data["data"])
     self.write_message(line)
  except tornado.websocket.WebSocketClosedError:
   self.close()

 def on_close(self):
  global FLAG
  FLAG = False
  print("closed")


def format_line(line):
 line = to_unicode(line)
 if "INFO" in line:
  color = "#46A3FF"
 elif "WARN" in line:
  color = "#FFFF37"
 elif "ERROR" in line:
  color = "red"
 elif "CRITICAL" in line:
  color = "red"
 else:
  color = "#FFFFFF"

 return "<span style='color:{}'>{}</span>".format(color, line)


class EchoWebSocket(tornado.websocket.WebSocketHandler):
 def open(self):
  print("WebSocket opened")

 @gen.coroutine
 def on_message(self, message):
  log = message
  print "log file: ", log

  try:
   with open(log, 'r') as f:
    for line in get_last_lines(f):
     line1 = format_line(line)
     self.write_message(line1)
    while True:
     line = f.readline()
     if not line:
      yield gen.sleep(0.05)
      continue
     self.write_message(format_line(line.strip()))
  except tornado.websocket.WebSocketClosedError as e:
   print e
   self.close()

 # def check_origin(self, origin):
 #  print origin, self.request.headers.get("Host")
 #  # super(EchoWebSocket, self).check_origin()
 #  return True

 def on_close(self):
  print("WebSocket closed")


class Application(tornado.web.Application):
 def __init__(self):
  handlers = [
   (r'/log/', MainHandler), # 提供浏览页面,页面中的JS与服务器建立连接
   (r'/log/local', EchoWebSocket), # 处理本地日志实时查看,比较简单
   (r'/log/remote', SubWebSocket), # 处理远程日志实时查看,稍微复杂
  ]
  settings = {
   "debug": True,
   "template_path": os.path.join(os.path.dirname(__file__), "templates"),
   "static_path": os.path.join(os.path.dirname(__file__), "static"),
  }
  super(Application, self).__init__(handlers, **settings)


class MainHandler(tornado.web.RequestHandler):
 def get(self):
  # 要查看的日志路径
  log = self.get_argument("log", None)
  # hostname实际上是saltstack中这台机器对应的minion id
  hostname = self.get_argument("hostname", None)
  # 本地日志还是远程日志
  type = self.get_argument("type", "local")
  # 运行读取实时日志的脚本,参数比较多,后面会有
  cmd = self.get_argument("cmd", "")
  context = {
   "log": log,
   "hostname": hostname,
   "type": type,
   "cmd": cmd,
  }
  self.render("index.html", **context)

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:django+tornado实现实时查看远程日志的方法
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址