167 lines
5.0 KiB
Python
167 lines
5.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
#########################################################
|
|
# python
|
|
import os
|
|
import traceback
|
|
import time
|
|
import threading
|
|
|
|
# third-party
|
|
from flask import request
|
|
from flask_socketio import SocketIO, emit
|
|
|
|
# sjva 공용
|
|
from framework import app, socketio, path_data, logger
|
|
from framework.logger import get_logger
|
|
from framework.util import SingletonClass
|
|
|
|
|
|
# 패키지
|
|
|
|
# 로그
|
|
|
|
#########################################################
|
|
|
|
namespace = "log"
|
|
|
|
|
|
@socketio.on("connect", namespace="/%s" % namespace)
|
|
def socket_connect():
|
|
logger.debug("log connect")
|
|
|
|
|
|
@socketio.on("start", namespace="/%s" % namespace)
|
|
def socket_file(data):
|
|
try:
|
|
package = filename = None
|
|
if "package" in data:
|
|
package = data["package"]
|
|
else:
|
|
filename = data["filename"]
|
|
LogViewer.instance().start(package, filename, request.sid)
|
|
logger.debug(
|
|
"start package:%s filename:%s sid:%s",
|
|
package,
|
|
filename,
|
|
request.sid,
|
|
)
|
|
except Exception as exception:
|
|
logger.error("Exception:%s", exception)
|
|
logger.error(traceback.format_exc())
|
|
|
|
|
|
@socketio.on("disconnect", namespace="/%s" % namespace)
|
|
def disconnect():
|
|
try:
|
|
LogViewer.instance().disconnect(request.sid)
|
|
logger.debug("disconnect sid:%s", request.sid)
|
|
except Exception as exception:
|
|
logger.error("Exception:%s", exception)
|
|
logger.error(traceback.format_exc())
|
|
|
|
|
|
class WatchThread(threading.Thread):
|
|
def __init__(self, package, filename):
|
|
super(WatchThread, self).__init__()
|
|
self.stop_flag = False
|
|
self.package = package
|
|
self.filename = filename
|
|
self.daemon = True
|
|
|
|
def stop(self):
|
|
self.stop_flag = True
|
|
|
|
def run(self):
|
|
logger.debug("WatchThread.. Start %s", self.package)
|
|
if self.package is not None:
|
|
logfile = os.path.join(path_data, "log", "%s.log" % self.package)
|
|
key = "package"
|
|
value = self.package
|
|
else:
|
|
logfile = os.path.join(path_data, "log", self.filename)
|
|
key = "filename"
|
|
value = self.filename
|
|
if os.path.exists(logfile):
|
|
with open(logfile, "r") as f:
|
|
f.seek(0, os.SEEK_END)
|
|
while not self.stop_flag:
|
|
line = f.readline()
|
|
if not line:
|
|
time.sleep(0.1) # Sleep briefly
|
|
continue
|
|
socketio.emit(
|
|
"add",
|
|
{key: value, "data": line},
|
|
namespace="/log",
|
|
broadcast=True,
|
|
)
|
|
logger.debug("WatchThread.. End %s", value)
|
|
else:
|
|
socketio.emit(
|
|
"add",
|
|
{key: value, "data": "not exist logfile"},
|
|
namespace="/log",
|
|
broadcast=True,
|
|
)
|
|
|
|
|
|
class LogViewer(SingletonClass):
|
|
|
|
watch_list = {}
|
|
|
|
@classmethod
|
|
def start(cls, package, filename, sid):
|
|
# 2019-04-02 간만에 봤더니 헷깔려서 적는다
|
|
# 이 쓰레드는 오픈시 이전 데이타만을 보내는 쓰레드다. 실시간보는거 아님.
|
|
|
|
def thread_function():
|
|
if package is not None:
|
|
logfile = os.path.join(path_data, "log", "%s.log" % package)
|
|
else:
|
|
logfile = os.path.join(path_data, "log", filename)
|
|
if os.path.exists(logfile):
|
|
ins_file = open(logfile, "r", encoding="utf8") ## 3)
|
|
line = ins_file.read()
|
|
socketio.emit("on_start", {"data": line}, namespace="/log")
|
|
logger.debug("on_start end")
|
|
else:
|
|
socketio.emit(
|
|
"on_start", {"data": "not exist logfile"}, namespace="/log"
|
|
)
|
|
|
|
if package is not None:
|
|
key = package
|
|
else:
|
|
key = filename
|
|
thread = threading.Thread(target=thread_function, args=())
|
|
thread.daemon = True
|
|
thread.start()
|
|
|
|
if key not in cls.watch_list:
|
|
cls.watch_list[key] = {}
|
|
cls.watch_list[key]["sid"] = []
|
|
cls.watch_list[key]["thread"] = WatchThread(package, filename)
|
|
cls.watch_list[key]["thread"].start()
|
|
cls.watch_list[key]["sid"].append(sid)
|
|
|
|
@classmethod
|
|
def disconnect(cls, sid):
|
|
find = False
|
|
find_key = None
|
|
for key, value in cls.watch_list.items():
|
|
logger.debug("key:%s value:%s", key, value)
|
|
for s in value["sid"]:
|
|
if sid == s:
|
|
find = True
|
|
find_key = key
|
|
value["sid"].remove(s)
|
|
break
|
|
if find:
|
|
break
|
|
if not find:
|
|
return
|
|
if not cls.watch_list[find_key]["sid"]:
|
|
logger.debug("thread kill")
|
|
cls.watch_list[find_key]["thread"].stop()
|
|
del cls.watch_list[find_key]
|