TG-PlatformPlus/logForm.py

225 lines
8.9 KiB
Python

import json
import os
import re
import time
from datetime import datetime
import queue
from PyQt6 import *
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from ui.Ui_logForm import Ui_logForm
from logModel.logManager import logManager
from projectModel.projectManager import projectManager
from common import common
from config import config
from logs import log
import copy
class LogThread(QThread):
def __init__(self, parent=None):
super().__init__(parent)
self.levels = {"DEBUG":["0"], "INFO":["0","1"], "WARNING":["0","1", "2"], "ERROR":["0", "1", "2", "3"]}
self.logQueue = queue.Queue()
self.maxCount = 500
self.msgDataMap = {}
def run(self):
while True:
if not self.logQueue.empty():
msgData = self.logQueue.get()
labs = self.levels[msgData["level"]]
for lab in labs:
try:
all = lab
id = lab + msgData["tag"]
msgStr = f"<span style='color:{msgData['color']};'>{msgData['msg']}</span><br>"
if id in self.msgDataMap:
self.msgDataMap[id].append(msgStr)
if len(self.msgDataMap[id]) > self.maxCount:
self.msgDataMap[id].pop(0)
else:
self.msgDataMap[id] = []
self.msgDataMap[id].append(msgStr)
if all in self.msgDataMap:
self.msgDataMap[all].append(msgStr)
if len(self.msgDataMap[all]) > self.maxCount:
self.msgDataMap[all].pop(0)
else:
self.msgDataMap[all] = []
self.msgDataMap[all].append(msgStr)
except Exception as e:
print(e)
QThread.usleep(1)
class LogForm(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_logForm()
self.ui.setupUi(self)
self.endStr = "---END"
self.timer = QTimer()
self.isScrollBottom = True
self.currentProId = ""
self.refreshCount = "refreshCount" in config.data["log"] and config.data["log"]["refreshCount"] or 100
self.logThread = LogThread()
self.levels = {"DEBUG":["0"], "INFO":["0","1"], "WARNING":["0","1", "2"], "ERROR":["0", "1", "2", "3"]}
self.levelIndex = 0
self.refreshTime = "refreshTime" in config.data["log"] and config.data["log"]["refreshTime"] or 100
self.tagText = ""
self.lastHtmlText = ""
self.logArray = []
self.timer.timeout.connect(self.setLogPlainText)
logManager.logMsgData.connect(self.addLogMsgData, type=Qt.ConnectionType.UniqueConnection)
self.ui.pbOpen.clicked.connect(self.openLogPath)
self.ui.pbClear.clicked.connect(self.clearLog)
self.ui.cbLevel.currentIndexChanged.connect(self.comboxChange)
self.ui.cbTag.currentIndexChanged.connect(self.comboxChange)
self.ui.pbLock.clicked.connect(self.changeIsScrollBottom)
self.ui.plainTextEdit.verticalScrollBar().valueChanged.connect(self.scrollbarValueChanged)
projectManager.sig_projectChanged.connect(self.loadLog)
self.timer.start(self.refreshTime)
self.logThread.start()
def clearLog(self):
self.ui.plainTextEdit.clear()
self.logThread.msgDataMap = {}
def changeIsScrollBottom(self):
self.isScrollBottom = not self.isScrollBottom
if self.isScrollBottom:
self.scrollToBottom()
self.ui.pbLock.setIcon(QIcon(":/resource/lock.svg"))
else:
self.ui.pbLock.setIcon(QIcon(":/resource/unlock.svg"))
# 获取当前时间字符串
def nowStr(self):
now = datetime.now()
ret = now.strftime('%H:%M:%S.') + f"{now.microsecond // 1000:03d}"
return ret
def searchType(self):
self.timer.stop()
self.lastHtmlText = ""
self.ui.plainTextEdit.clear()
id = ""
self.levelIndex = self.ui.cbLevel.currentIndex()
self.tagText = str(self.ui.cbTag.currentText())
if self.ui.cbTag.currentText() == "ALL":
self.tagText = ""
id = str(self.ui.cbLevel.currentIndex())
else:
id = str(self.ui.cbLevel.currentIndex()) + str(self.ui.cbTag.currentText())
if id in self.logThread.msgDataMap:
self.logArray = self.logThread.msgDataMap[id]
self.timer.start(self.refreshTime)
def appendColoredText(self, text, font_color):
fmt = QTextCharFormat()
# 设置字体颜色
fmt.setForeground(QBrush(font_color))
# 将格式应用到文本编辑器的当前字符格式上
self.ui.plainTextEdit.mergeCurrentCharFormat(fmt)
# 在文本编辑器中追加文本
self.ui.plainTextEdit.appendPlainText(text)
def setLogPlainText(self):
try:
self.timer.stop()
self.levelIndex = self.ui.cbLevel.currentIndex()
self.tagText = str(self.ui.cbTag.currentText())
if self.ui.cbTag.currentText() == "ALL":
self.tagText = ""
id = str(self.ui.cbLevel.currentIndex())
else:
id = str(self.ui.cbLevel.currentIndex()) + str(self.ui.cbTag.currentText())
if id in self.logThread.msgDataMap:
htmlText = "".join(self.logThread.msgDataMap[id][:len(self.logThread.msgDataMap[id])])
if self.lastHtmlText != htmlText:
self.lastHtmlText = htmlText
self.setUpdatesEnabled(False)
self.ui.plainTextEdit.clear()
self.ui.plainTextEdit.appendHtml(htmlText)
self.setUpdatesEnabled(True)
except Exception as e:
log.error(f"addLogMsg exception: {e}")
finally:
self.timer.start(self.refreshTime)
def comboxChange(self, index):
self.searchType()
def openLogPath(self):
os.startfile(projectManager.getLogPath())
def scrollToBottom(self):
if self.isScrollBottom:
self.ui.plainTextEdit.verticalScrollBar().setValue(self.ui.plainTextEdit.verticalScrollBar().maximum())
def scrollbarValueChanged(self, value):
scrollbar = self.ui.plainTextEdit.verticalScrollBar()
max_value = scrollbar.maximum()
current_value = scrollbar.value()
if current_value == max_value:
self.isScrollBottom = True
self.ui.pbLock.setIcon(QIcon(":/resource/lock.svg"))
else:
self.isScrollBottom = False
self.ui.pbLock.setIcon(QIcon(":/resource/unlock.svg"))
def loadLog(self, proId):
self.clearLog()
logFilePath = logManager.loadProLog(proId)
try:
if os.path.exists(logFilePath):
with open(logFilePath, "r", encoding="utf-8") as f:
file_content = f.read()
log_entries = file_content.strip().split(f'{self.endStr}')
endCount = self.refreshCount
if self.refreshCount > len(log_entries):
endCount = 0
for entry in log_entries[-endCount:]:
if entry:
msgData = {}
msgData["time"] = ""
msgData["level"] = "DEBUG"
msgData["msg"] = ""
msgData["color"] = "blue"
msgData["tag"] = ""
try:
log_entry = json.loads(entry)
msgData["time"] = log_entry["time"]
msgData["level"] = log_entry["level"]
msgData["color"] = log_entry["color"]
msgData["msg"] = log_entry["msg"]
msgData["tag"] = log_entry["tag"]
msgData["searchText"] = common.level2Search(msgData["level"])
except:
print("invalid log line:", entry)
self.addLogMsg(msgData)
self.loadFinish()
except Exception as e:
log.error(f"log exception: {e}")
def loadFinish(self):
self.scrollToBottom()
def addLogMsgData(self, msgData):
tag = ""
if msgData["tag"] is not None:
tag = str(msgData["tag"])
msgData["tag"] = tag
if self.ui.cbTag.findText(tag) == -1:
self.ui.cbTag.addItem(tag)
labs = self.levels[msgData["level"]]
self.logThread.logQueue.put(msgData)