Py小工具: 快速查询服务器日志+关键字高亮

10 篇文章 0 订阅

背景

  • 最近在单核1G的乞丐版服务器上部署了个自己的后台应用玩玩,想顺便部署个SpringBoot-admin来查查日志啥的结果一部署上去服务器资源就不够用了,那咋整?不会每次想看日志都的SSH过去然后追到日志目录然后再去tail?想想就觉得麻烦!于是花了点时间做了个简单快捷查日志的小工具,顺便加了关键字高亮,这样日志看起来漂亮多了!

效果

  • 实时查询日志, 服务器新产生的日志会立即打印到该窗口
    logV1.gif

  • 集成简单的查询和字符操作
    logV2.gif

源码

https://github.com/shuoGG1239/LogViewer

使用

  • 仅需配置下userinfo.json即可. name,host,password为服务器SSH登录三元组
  • 然后把cmd下的/home/server/admin.log换成服务器日志的路径, 然后直接跑就行了
{
  "password": "122222",
  "host": "39.108.226.222",
  "name": "root",
  "cmd": "tail -f -n 500 /home/server/admin.log"
}


分析

  • 其实看到userinfo下的字段就知道这其实只是一个超级简化版的SSH客户端了吧, 然后cmd就是自动执行的命令, 最后把执行的命令显示在输出框…确实就是这么简单! 其实本来是对cmd进行一层封装的, 不过后来觉得不自由, 还是改成在cmd填命令直接跑吧, 反正是给自己用的:P

  • 其中SSH连接模块是用了paramiko, 其实python的SSH工具包很多, 什么fabric, pexpect都用过, 但是在windows+Py3的环境下感觉不是很友好, 踩过一些坑就不多说了, 反正windows下就无脑选paramiko

  • 代码高亮部分, 我这边由于日志用的是log4j, 所以着色也是根据log4j的格式来适配, prettify_text方法是着色+过滤主体, 可以根据自己服务器日志的格式修改此方法即可

# LogViewer.py
    @pyqtSlot(str)
    def __slot_redirect(self, text):
        raw_text = text.strip()
        if raw_text != '':
            # 着色+过滤
            pretty_text = self.prettify_text(raw_text) 
            if pretty_text != '':
                self.ui.textBrowser.append(pretty_text)

    def prettify_text(self, text):
        """
        对日志进行渲染美化, 包括着色过滤等
        :param text:
        :return:
        """
        # 含有这些字段的报文都过滤掉
        ex_list = ('PushUtil', 'pushUtil', 'Jdbc', 'jdbc', 'HostServiceImpl')
        # 着色 
        pretty_text = log4j_type.colorize(text)       
        pretty_text = log4j_type.frame_pack('39.108.226.252', pretty_text)
        pretty_text = log4j_type.exclude(ex_list, pretty_text)
        return pretty_text
  • 着色和过滤的具体实现在log4j_type.py
# log4j_type.py
def colorize(frame):
    """
    对单行进行着色
    :param frame:
    :return:
    """
    frame = re.sub(r'(admin\d?\.log)', color_util.bold(color_util.colorize('\\1', 'orange')), frame)
    frame = re.sub(r'\s:\s(.+)', color_util.colorize(' : \\1', 'blue'), frame)
    frame = frame.replace('INFO', color_util.colorize('INFO', color_util.LIGHT_BLUE))
    frame = frame.replace('ERROR', color_util.colorize('ERROR', 'red'))
    frame = frame.replace('WARN', color_util.colorize('WARN', 'orange'))
    frame = re.sub(r'(\w+Exception)', color_util.colorize('\\1', 'red'), frame)
    frame = re.sub(r'(\([\w_]+\.java:\d+\))', color_util.colorize(color_util.underline('\\1'), 'red'), frame)
    return frame

  • 搜索框的实现: 直接用Qt的东西, 没啥好说的
# SearchForm.py
class SearchForm(QWidget):
    signal_key = pyqtSignal(int)

    def __init__(self):
        QWidget.__init__(self)
        self.ui = Ui_SearchForm()
        self.ui.setupUi(self)

    def on_pushButtonClose_clicked(self):
        self.hide()

    def on_pushButtonForward_clicked(self):
        pass

    def on_pushButtonBackward_clicked(self):
        pass

    def keyPressEvent(self, e):
        if (e.modifiers() == Qt.NoModifier) and (e.key() == Qt.Key_Return):
            self.signal_key.emit(Qt.Key_Return)
        elif (e.modifiers() == Qt.ShiftModifier) and (e.key() == Qt.Key_Return):
            self.signal_key.emit(Qt.Key_Return + Qt.ShiftModifier)
        elif (e.modifiers() == Qt.ControlModifier) and (e.key() == Qt.Key_F):
            self.ui.pushButtonClose.click()
        elif (e.modifiers() == Qt.NoModifier) and (e.key() == Qt.Key_Escape):
            self.ui.pushButtonClose.click()


# LogViewer.py
    # -------search From Start-------
    def __init_searchForm(self):
        self.searchForm = SearchForm()
        self.searchForm.setParent(self)
        self.searchForm.hide()
        self.searchForm.ui.pushButtonForward.clicked.connect(self.__slot_find_forward)
        self.searchForm.ui.pushButtonBackward.clicked.connect(self.__slot_find_backward)
        self.searchForm.ui.pushButtonClose.clicked.connect(self.__slot_searchForm_close)
        self.searchForm.signal_key.connect(self.__slot_searchForm_keyboard)

    @pyqtSlot(int)
    def __slot_searchForm_keyboard(self, key):
        if key == Qt.Key_Return:
            self.ui.textBrowser.find(self.searchForm.ui.lineEdit.text())
        elif key == (Qt.Key_Return + Qt.ShiftModifier):
            self.ui.textBrowser.find(self.searchForm.ui.lineEdit.text(), QTextDocument.FindBackward)

    @pyqtSlot()
    def __slot_searchForm_close(self):
        self.ui.textBrowser.setFocus()

    @pyqtSlot()
    def __slot_find_forward(self):
        self.ui.textBrowser.find(self.searchForm.ui.lineEdit.text())

    @pyqtSlot()
    def __slot_find_backward(self):
        self.ui.textBrowser.find(self.searchForm.ui.lineEdit.text(), QTextDocument.FindBackward)

    def resizeEvent(self, e):
        self.searchForm.setGeometry(e.size().width() - self.searchForm.width(), 0,
                                    self.searchForm.width(), self.searchForm.height())

    # --------search From End-------
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值