算法日志的存在核心在于搭建自检系统

        "相信每一个人执行与日志有关的任务都会遇到这样难题吧?长达几万行的日志,如果我们单纯用肉眼去一个个排查,那么恐怕所耗费的时间是以天为计量单位了。当然这是一种比较夸张的情况,根据我的项目经验,正常情况是十几个站点的人可能每天需要花费3-4个小时去排查日志或者与日志有关却能被日志替代的内容。如果我们能搭建一个智能化的系统,使得这个系统可以智能的读取日志中我们关键的信息,那么会发生什么呢?"

        有些人问,我就想用肉眼看,不行嘛?其实,"不是肉眼看不起,而是智能化日志更有性价比!"没错,如果我们搭建这样一个智能化日志自检系统,N个站n*m个团体每天都能节省n*m*k个工时去干别的事情。

NOTE:本文只是介绍一种思想,所以不会有过多的具体代码讲解,但是可以给上一个成功的案例手册,仅供参考。
———————————————————————————————————————————华丽的分割线

现场人员自检失败表计点位教程

NOTE: 如果没有meterPoint_Self-Checking_sys.py“脚本的请联系我们进行提供

👇

运行该脚本,参考运行命令如下(请确保此时您的工作目录处于meter/log)

#这是一条参考运行命令,请您根据您实际的情况修改-p和-t参数的具体内容
python3 meterPoint_Self-Checking_sys.py -p meterlog -t 30M00000036658634_task1703485183168_20231225141946
# @pararm:-p 是存放日志的路径,该日志包含您刚跑完测试的日志内容。
# @pararm:-t 是您任务的序号,如下图,Ftp图片路径下包含”task“的字符串,也就是灰色框框住的那一串正式您此次任务的序号,输入30M00000036658634_task1703485183168_20231225141946

👇

自动生成自检报表meterlog_checking.txt

里面部分关键内容如下:

👇

接下来大家请对照这张表,找到【需要现场人员自检】【错误】进行搜索排查,有多个,可以从上往下慢慢来。

👇

以【通用类】<序号7>"该点位没有录入"作为例子,打开自检文本meterlog_checking.txt

👇

👇

如果出现无需现场人员自检的错误,需要截图一下日志中有关内容,可能后续还需提供图片我们这边进行优化

一些使用样例图: 

# -*- coding: utf-8 -*-
'''
参考diamagnetic:
# 兰江
python3 meterPoint_Self-Checking_sys.py -p meterlog -t 30M00000036658634_task1703485183168_20231225141946
# 金鼎
python3 meterPoint_Self-Checking_sys.py -p meterlog -t 30M00000036658634_task1703485183168_20231225141947
'''
import re
import json
import argparse

# 创建命令行参数解析器
parser = argparse.ArgumentParser()
parser.add_argument('-p', '--log_file', help='log文件路径')
parser.add_argument('-t', '--task_id', help='任务ID')
args = parser.parse_args()

def extract_debug_segments(log_file):
    debug_segments = []
    with open(log_file, 'r') as file:
        lines = file.readlines()
        start_line = None
        end_line = None
        segment = []

        for i, line in enumerate(lines):
            if 'Debug' in line or '收到请求' in line or '数据库信息' in line:
                if start_line is None:
                    start_line = i
                segment.append(line.strip())   

            elif '结果放入队列待发送' in line:
                if start_line is not None:
                    end_line = i
                    segment.append(line)
                    debug_segments.append([segment, start_line, end_line])
                    segment = []
                    start_line = None
                    end_line = None

    return debug_segments
def process_request(request_str):
    target_index = request_str.index("{")
    # 按照":"分割字符串
    split_str = request_str[target_index:]
    # 获取分割后数组中最后一个索引所保存的信息
    json_str = split_str.strip().replace("—", "-").replace("'", "\"")

    objectList_request_str = json.loads(json_str)['objectList'][0]
    # for k in objectList_request_str:
    #     print(k)
    return objectList_request_str

def get_pointList_length(json_str):
    
    pattern = r"'Position': '(\[.*?\])'"
    matches = re.search(pattern, json_str)
    if matches is None:
        return 0
    position_list = json.loads(matches.group(1))
    # print("position_list:", position_list)
    return len(position_list)

def process_sql(json_str):

    json_str = json_str[json_str.index("MinValue"):]
    json_str = "{'" + json_str
    json_str = json_str.replace("'", "\"")
    sql_dict = json.loads(json_str)
    return sql_dict

def process_result(json_str):

    json_str = json_str[json_str.index("code"):-5]
    json_str = "{'" + json_str
    # print(json_str)
    json_str = json_str.replace("'", "\"")
    json_str = json_str.replace("None", "null")
    sql_dict = json.loads(json_str)
    return sql_dict

def contains_digit(string):
    pattern = r'\d'  # 正则表达式模式,匹配任意数字
    if re.search(pattern, string):
        return True
    else:
        return False

if __name__ == "__main__":
    # 摄像机偏移严重+模糊
    Error_withoutDetctor = []
    # 未识别出指针
    Error_withoutPointer = []
    # 读取ftp图失败
    Error_loadftp = []
    # minIO无图
    Error_withoutMinioImage = []
    # minIO错图
    Error_minioErrorImage = []
    # 点位未录入
    Error_withoutId = []
    # 表计类型录入错误
    Error_clsType = []
    # 最大最小值设置错误
    Error_minMaxSet = []
    # 最大最小值未设置
    Error_withoutMinMax = []
    # 未打刻度点位
    Error_withoutPointList = []
    # 刻度打点错误
    Error_PointList = []
    # 未识别到任何油面表!
    Error_ymb = []
    # OCR没有检测出数字
    Error_ocrRec = []
    # OCR没有检测出表盘
    Error_ocrDet = []
    # ===========================核
    # 获取命令行参数
    log_file = args.log_file
    work_id = args.task_id
    debug_segments = extract_debug_segments(log_file)
    error_num = 0
    # not_reading_num = 0
    # type_num = 0
    ymb_num, sxb_num, bj_num = 0, 0, 0
    ymb_errorNum, sxb_errorNum, bj_errorNum = 0, 0, 0
    for segment in debug_segments:
        error_flag = False
        # print('Start Line:', segment[1])
        # print('End Line:', segment[2])
        for line in segment[0]:
            # print(line)
            if "收到请求" in line:
                # print('【请求信息】: ',end='')
                objectList_request_str = process_request(line)
                extract_objectId = objectList_request_str['objectId']
                # print(objectList_request_str['imageUrlList'][0], work_id)
                if not work_id in objectList_request_str['imageUrlList'][0]:
                    break

            elif '数据库信息' in line:
                if line.split("【数据库信息】")[-1] == '{}':
                    # 数据库信息为空
                    # print('*pointList_length:0')
                    # print('{}')
                    Error_withoutId.append(extract_objectId)
                    error_flag = True
                    break
                else:
                    # 数据库有信息
                    pointList_length = get_pointList_length(line)
                    sql_schem = process_sql(line)
                    MinValue = sql_schem['MinValue']
                    MaxValue = sql_schem['MaxValue']
                    meter_type = sql_schem['AlgorithmType']
                    ImagePath = sql_schem['ImagePath']

                    if meter_type == 'meter_v5':
                        bj_num += 1
                    if meter_type == 'meter_ywj':
                        ymb_num += 1
                    if meter_type == 'paddleocr':
                        sxb_num += 1

                    if meter_type == 'meter_v5':
                        if len(MinValue)== 0 or len(MaxValue) == 0:
                            Error_withoutMinMax.append(extract_objectId)
                            MinValue = float(0)
                            MaxValue = float(100)
                            error_flag = True
                        else:
                            MinValue = float(MinValue)
                            MaxValue = float(MaxValue)

                    # 表计类型录入错误(如果打点了,但表计类型不是meter_v5)
                    if meter_type == 'meter_v5' and pointList_length == 0:
                        Error_clsType.append(extract_objectId)
                        error_flag = True
                    # 未打刻度点位
                    if meter_type == 'meter_v5' and pointList_length == 0:
                        Error_withoutPointList.append(extract_objectId)
                        error_flag = True

                    # print(sql_schem, end=',')
                    # print("*pointList_length:", pointList_length)
            
            elif '结果放入队列待发送' in line:
                result_schem = process_result(line)
                # print('【结果队列信息】:',end='')
                # print(result_schem)
                if result_schem['code'] == '2001':
                    Error_loadftp.append(extract_objectId)
                    error_flag = True
                if result_schem['desc'] == '未识别到任何油面表!':
                    error_flag = True
                    Error_ymb.append(extract_objectId)
            else:
                splitContent = line.split("【Debug】")[-1]
                if "成功检测到表盘!表盘信息是" in splitContent:
                    det_clsType = splitContent.split(":")[-1].strip().strip("").strip("[]").strip()
                    if splitContent.split(":")[-1].strip().strip("") == "[]":
                        Error_withoutDetctor.append(extract_objectId)
                        error_flag = True

                    if not 'sxb' in det_clsType and meter_type == 'paddleocr':
                        Error_ocrDet.append(extract_objectId) 
                        error_flag = True

                    if 'ywb' in det_clsType:
                        ywb_minMax = [
                            [-20, 140],
                            [0, 160]
                        ]
                        iter_minMax = [MinValue, MaxValue]
                        if not iter_minMax in ywb_minMax:
                            Error_minMaxSet.append(extract_objectId)
                            error_flag = True
                            
                    elif 'xldlb' in det_clsType:
                        xldlb_minMax = [
                            [0, 3.0],
                            [0, 10],
                            [0, 9],
                            [0, 1]
                        ]
                        iter_minMax = [MinValue, MaxValue]
                        if not iter_minMax in xldlb_minMax:
                            Error_minMaxSet.append(extract_objectId)
                            error_flag = True
                # if '动作次数' in splitContent:
                #     print(splitContent)
                # if '泄漏电流值' in splitContent:
                #     print(splitContent)
                if 'OCR没有检测出数字' in splitContent:
                    Error_ocrRec.append(extract_objectId)
                    error_flag = True

                if "没识别出指针" in splitContent:
                    Error_withoutPointer.append(extract_objectId)
                    error_flag = True

                if len(ImagePath) == 0 or "MinIo中缺失该点位基准图" in splitContent:
                    Error_withoutMinioImage.append(extract_objectId)
                    error_flag = True

                # 用于验证
                if '读数结果' in splitContent and not contains_digit(splitContent):
                    # not_reading_num +=1
                    # 验证后 无读数个数和错误个数基本一致->代表验证成功
                    # print(not_reading_num)
                    continue
        if error_flag:
            if meter_type == 'meter_v5':
                bj_errorNum += 1
            if meter_type == 'meter_ywj':
                ymb_errorNum += 1
            if meter_type == 'paddleocr':
                sxb_errorNum += 1
            error_num += 1
    print("错误总数比:【{}/{}】".format(error_num,len(debug_segments)))
    # ===========================核
    # 写入
    with open('meterlog_checking.txt', 'w') as output_file:
        output_file.write('您这次序号为[{}]的任务:\n---------------------------------\n一共测试表计数量:[{}]个, 错误点位为:[{}]个, 未打点个数为:[{}]。\n<在此之中>\n,指针类表计成功占[{}/{}]个\n,油面表成功占[{}/{}]个\n,数显表成功占[{}/{}]个。'.format(work_id,len(debug_segments),error_num,len(Error_withoutId),bj_num - bj_errorNum, bj_num,ymb_num - ymb_errorNum, ymb_num, sxb_num - sxb_errorNum, sxb_num))

        output_file.write('\n')
        output_file.write('---------------------------------\n')
        output_file.write('NOTE:接下来,请您根据所需要查询的错误名称,使用<ctrl+F>的方式进行查询。\n')
        output_file.write('---------------------------------\n')
        output_file.write("【错误】可能存在摄像机偏移严重/模糊<数量:{}>:".format(str(len(Error_withoutDetctor))) + "\n")
        output_file.write("\n".join(Error_withoutDetctor))
        output_file.write('\n')

        output_file.write("【错误】未识别出指针<数量:{}>:".format(str(len(Error_withoutPointer))) + "\n") 
        output_file.write("\n".join(Error_withoutPointer))
        output_file.write('\n')

        output_file.write("【错误】读取ftp图失败<数量:{}>:".format(str(len(Error_loadftp))) + "\n")
        output_file.write("\n".join(Error_loadftp))
        output_file.write('\n')

        output_file.write("【错误】minIO无图<数量:{}>:".format(str(len(Error_withoutMinioImage))) + "\n")
        output_file.write("\n".join(Error_withoutMinioImage))
        output_file.write('\n')
        
        output_file.write("【错误】该点位没有录入<数量:{}>:".format(str(len(Error_withoutId))) + "\n")
        output_file.write("\n".join(Error_withoutId))
        output_file.write('\n')

        output_file.write("【错误】表计类型录入错误<数量:{}>:".format(str(len(Error_clsType))) + "\n")
        output_file.write("\n".join(set(Error_clsType)))
        output_file.write('\n')

        output_file.write("【错误】最大最小值未设置<数量:{}>:".format(str(len(Error_withoutMinMax))) + "\n")
        output_file.write("\n".join(Error_withoutMinMax))
        output_file.write('\n')

        output_file.write("【错误】未打刻度点位<数量:{}>:".format(str(len(Error_withoutPointList))) + "\n")
        output_file.write("\n".join(Error_withoutPointList))
        output_file.write('\n')

        output_file.write("【错误】最大最小值设置错误<数量:{}>:".format(str(len(Error_minMaxSet))) + "\n")
        output_file.write("\n".join(Error_minMaxSet))
        output_file.write('\n')

        output_file.write("【错误】存在刻度打点错误(暂未启用)<数量:{}>:".format(str(len(Error_PointList))) + "\n")
        output_file.write("\n".join(Error_PointList))
        output_file.write('\n')

        output_file.write("【错误】未识别到任何油面表<数量:{}>:".format(str(len(Error_ymb))) + "\n")
        output_file.write("\n".join(Error_ymb))
        output_file.write('\n')

        output_file.write("【错误】OCR没有检测出数字<数量:{}>:".format(str(len(Error_ocrRec))) + "\n")
        output_file.write("\n".join(Error_ocrRec))
        output_file.write('\n')

        output_file.write("【错误】OCR没有检测出表盘<数量:{}>:".format(str(len(Error_ocrDet))) + "\n")
        output_file.write("\n".join(Error_ocrDet))
        output_file.write('\n')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/297059.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于FFmpeg的短视频编辑工具Cut

前言 最近在学习FFmpeg和音视频的相关知识&#xff0c;为了加强对FFmpeg的认识和了解&#xff0c;于是撸了一个短视频编辑软件Cut。 效果图先行&#xff1a; 技术点 启动页优化 但启动app的时候会有一个短暂的黑屏或者白屏。为什么呢&#xff1f; 是因为在App启动时&#x…

腾讯云2核2G3M服务器够用吗?腾讯云2核2G3M云服务器性能评测

阿里云轻量应用服务器2核2G3M带宽优惠价格62元一年&#xff0c;100%CPU性能&#xff0c;3M带宽下载速度384KB/秒&#xff0c;40GB SSD系统盘&#xff0c;月流量200GB&#xff0c;折合每天6.6GB流量&#xff0c;超出月流量包的流量按照0.8元每GB的价格支付流量费&#xff0c;地域…

kubesphere和k8s的使用分享

文章目录 什么是kubernetesKubernetes的部分核心概念互式可视化管理平台与kubernetes的关系市面是常见的kubernetes管理平台 什么是kubesphereKubesphere默认安装的组件Kubesphere涉及的服务组件kubesphere的安装Kubesphere相关的内容 什么是kubernetes 就在这场因“容器”而起…

Vue CLI组件通信

目录 一、组件通信简介1.什么是组件通信&#xff1f;2.组件之间如何通信3.组件关系分类4.通信解决方案5.父子通信流程6.父向子通信代码示例7.子向父通信代码示例8.总结 二、props1.Props 定义2.Props 作用3.特点4.代码演示 三、props校验1.思考2.作用3.语法4.代码演示 四、prop…

科锐16位汇编学习笔记 03 汇编指令

指令种类 数据传送指令算数运算类指令位操作类指令串操作类指令控制转移类指令处理器控制类指令 数据传送类指令 传送类指令不影响标志位&#xff0c;**除了标志位传送指令外。** 传送指令MOV&#xff08;move&#xff09; 说明 ​ 把一个字节或字的操作数从源地址传送至…

swift ——多行文字前面内容省略

首先来说一说ios中的 lineBreakModelineBreakMode : 设置文字过长时的显示截断样式 可选值如下 byWordWrapping &#xff1a; 以单词为单位换行&#xff0c;以单词为单位截断。byCharWrapping &#xff1a;以字符为单位换行&#xff0c;以字符为单位截断。byClipping &#x…

Linux进程管理、ps命令、kill命令

每一个程序在运行的时候都会被操作系统注册为系统中的一个进程 补充一下操作系统的内容&#xff1a; 进程实体&#xff08;又称进程映像&#xff09;&#xff1a;程序段、相关数据段、PCB三部分构成 进程是进程实体的运行过程&#xff0c;是系统进行资源分配的一个独立单位 …

关于时间格式yyyy-M-d或yyyy-MM-d到yyyy-MM-dd的转换

工作时遇到前端传的时间格式是"2023-12-3 17:41:52"&#xff0c;和"2023-1-1 17:41:52"但是我想要的是"2023-12-03 17:41:52"和"2023-01-01 17:41:52"。下面给大家分享几个解决方法 方法一&#xff1a; 找前端&#xff01;让他改&…

关于《码农翻身》一书的读后感以及自己的一些拙见汇总

书籍名称 《码农翻身》 | 刘欣&#xff08;码农翻身&#xff09; 著 | 文章将以问答的形式进行叙述 1.是从什么渠道接触到《码农翻身》的 一个工作日的下午&#xff0c;手上的任务基本结束&#xff0c;翻了翻桌上的书和笔记之类的&#xff0c;同事见我在看书&#xff0c;于是向…

用opencv的DNN模块做Yolov5目标检测(纯干货,源码已上传Github)

最近在微信公众号里看到多篇讲解yolov5在openvino部署做目标检测文章&#xff0c;但是没看到过用opencv的dnn模块做yolov5目标检测的。于是&#xff0c;我就想着编写一套用opencv的dnn模块做yolov5目标检测的程序。在编写这套程序时&#xff0c;遇到的bug和解决办法&#xff0c…

Mac启动时候出现禁止符号

Mac启动时候出现禁止符号 启动时候出现禁止符号,意味着 选定的启动磁盘 包含 Mac 操作系统&#xff0c;但它不是 您的 Mac 可以使用的 macOS 。您应该在这个磁盘上 重新安装 macOS 。 可以尝试以下苹果提供的方法&#xff1a; Mac启动时候出现禁止符号 不要轻易抹除磁盘&am…

2023 最火的是什么? 超维计算 + 神经网络

从chatgpt开始&#xff0c;人工智能进步的步伐似乎势不可挡&#xff0c;但支撑这些程序的人工神经网络遇到了一些重大限制&#xff0c;其他的很难推理但是人类的大脑能够通过类比进行推理&#xff0c;当我们看到新事物时&#xff0c;我们不必生长新的神经元&#xff0c;我们可以…

【python】Python 3.11不支持Tix库

Tix库主要用于扩展Tkinter&#xff0c;但是Python 3.11 Tkinter已经不再支持Tix库。Tix模块提供了一些额外的部件和功能&#xff0c;但现在这些功能已经整合到了Tkinter库中。 一、如果在Python 3.11中想要使用Tix库&#xff0c;但发现它不再被内置支持&#xff0c;可以尝试以…

QCharView使用

QChart是 QGraphicsWidget的子类。 QCharView是QGraphicsView的子类 QCharView概念:title、系列、图标Chart、视图 说明: 需要添加Qt组件charts 在使用QChart或者QChartView之前需要添加宏定义QT_CHARTS_USE_NAMESPACE &#xff08;其实是使用了命名空间&#xff09;&#xff…

KVM虚拟化技术

在当今的云计算时代&#xff0c;虚拟化技术已经成为了企业和个人用户的首选。而在众多虚拟化技术中&#xff0c;KVM&#xff08;Kernel-based Virtual Machine&#xff09;虚拟化技术因其高性能、低成本和灵活性而备受青睐。本文将介绍KVM虚拟化技术的原理、特点以及应用场景。…

CDMP考试解析:从报名到成功不走弯路

❤️CDMP数据管理专业认证是由DAMA国际于2004推出&#xff0c;是一项涵盖学历教育、工作经验和专业知识考试在内的综合资格认证&#xff0c;也是目前全球wei一数据管理方面权威性认证。 &#x1f4b0;考试费用&#xff1a;CDMP的考试费用约为每科2500元。 其他可能的费用&#…

【web】Springboot3 集成 Swagger3

文章目录 Maven 依赖配置类&#xff08;可选&#xff09;访问示例 Maven 依赖 <!--swagger3--> <dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.0.2</v…

什么是谐波减速机?日本Harmonic哈默纳科谐波减速机有哪些优点?

一、什么是谐波减速机&#xff1f; 谐波减速装置最早期被叫做“strain wave gearing”&#xff0c;直译过来为“应变波齿轮”。其后被HarmonicDrive Systems 公司大规模商业实用化后&#xff0c;经过二次翻译后&#xff0c;中文名称才将其称为“谐波齿轮传动”。 谐波减速机是…

Ubuntu18 安装chatglm2-6b

记了下Ubuntu18 上安装chatglm2-6遇到的问题。 环境&#xff1a;Ubuntu18.04 V100(显卡) nvcc 11.6 显卡驱动cudacudnnaniconda chatglm6b 的安装 网上有很多&#xff0c; 不记录 了。 chatglm2-6b 我从别的地方拷贝的&#xff0c; 模型也包含了。 遇到的问题&#xf…

C++补充内容--语法篇

这里写目录标题 语法其他语法函数的存储类函数参数默认值格式默认参数位置重载函数的默认参数 指针名与正常指针的自增自减以及解引用与的优先级问题指针的赋值、加减数字、加减指针二维数组中的一些指针辨析输出调用字符指针时 会将该指针以及之后的元素全部输出二维数组未完全…
最新文章