从日志文件里提取通信数据报文-python

背景

        工作中有需要从一个日志文件中提取打印的通信数据报文。日志打印有几十万行,而里面的报文也很长,分了几百个块发送,因此相关日志也有几百行,但是相关日志的格式是有特点的。因此我决定写个python脚本,把通信数据报文输出用于进一步分析。

        报文日志打印的格式特点是含有“multiFrame is:”和“07470136”这两个字符,第二个字符串后面有两个字符的编号,编号后就是报文内容。

[SendMultiFrame] Debug! multiFrame is:01122********************0747013601555555555555
......
[SendMultiFrame] Debug! multiFrame is:01122********************0747013602555555555555
......
[SendMultiFrame] Debug! multiFrame is:01122********************0747013603555555555555
......

代码实现

import zlib


def extract_from_log():
    f = open("log.txt", "r")  # 日志文件
    f_data = open("result.txt", "w")  # 日志文件里的通信数据
    # f_out = open("resultdata.txt", "w")  # 日志文件里通信数据每字节一行写入,是否要用看实际需要
    file_data = f.readlines()
    data = []
    print('data is:')
    for content in file_data:
        # 本用例里通信数据所在行的特征是 含有“multiFrame is”和“7470136”关键词,并且第90位开始到最后“\n”前是数据
        if 'multiFrame is' in content:
            if '7470136' in content:
                content = content.replace("\n", "")
                print(content[89:])
                f_data.writelines(content[89:])
                data.append(content[89:])

    packagedata = "".join(data)
    # 由于数据是16进制打印,所以每两个字符的长度是一个字节
    datalength = len(packagedata) // 2
    dataList = []
    for i in range(0, datalength):
        dataList.append(packagedata[2 * i] + packagedata[2 * i + 1])  # 每个字节由相邻两个16机制字符组成
    for i in range(0, datalength):
        # f_out.write(dataList[i] + "\n")  # 日志文件里通信数据每字节一行写入,是否要用看实际需要
        dataList[i] = int(dataList[i], 16)  # 计算CRC32需要int格式

    # 最后计算从日志文件中提取的通信报文数据长度和CRC32值,用于确认是否提取正确
    data_out_CRC32 = zlib.crc32(bytes(dataList))
    print('datalength is:', datalength)
    print("crc32 of printed data is:%#x" % data_out_CRC32)


#通过日志上文得知这里的数据是intel hex格式的,根据对该格式的了解,复原了原始的hex文件
    f_hex = open("result_hex.txt", "w")  # 日志文件里的通信数据
    for i in range(datalength):
        if i % 0x10 == 0 and i < 97265:
            firstpart = 0x108000 + i
            if firstpart >= 0x110000:
                firstpart = firstpart - 0x10000
            if firstpart == 0x100000:
                # print(':020000021000EC')
                f_hex.write(':020000021000EC' + "\n")
            firstpartprint = str(hex(firstpart))[2:].upper()
            datalineprint = ':'
            datalineprint = "".join((datalineprint, firstpartprint))
            datalineprint = "".join((datalineprint, '00'))
            Sum = 0
            for j in range(16):
                if (i + j) >= datalength:
                    break
                Sum = Sum + dataList[i + j]
                dataprint = str(hex(dataList[i + j]))[2:].upper()
                if len(dataprint) == 1:
                    dataprint = "".join(('0', dataprint))
                datalineprint = "".join((datalineprint, dataprint))
            a1 = (firstpart & 0xff0000) >> 8 * 2
            a2 = (firstpart & 0x00ff00) >> 8
            a3 = firstpart & 0x0000ff
            a_firstpart = a1 + a2 + a3
            #crc计算的算法是将所有的数相加,然后计算补码
            Checksum = 0x100 - (Sum + a_firstpart) & 0xff
            checksumprint = str(hex(Checksum))[2:].upper()
            if len(checksumprint) == 1:
                checksumprint = "".join(('0', checksumprint))
            datalineprint = "".join((datalineprint, checksumprint))
            # print(datalineprint)
            f_hex.write(datalineprint + "\n")
    # print(':00000001FF')
    f_hex.write(':00000001FF' + "\n")


if __name__ == '__main__':
    extract_from_log()

测试结果

测试日志打印:

data is:
55555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
......
datalength is: 94444
crc32 of printed data is:0x3108c3d5

Process finished with exit code 0

生成一个新的文件(intel hex文件):

:108000004B4F5354414CFFFF0001FBE0FFFFFFFFCC
:10801000ED108100ED118400ED148400ED17840053
......
:10FBE0004B4F434849FFFFFF0001FBF8FFFFFFFFBA
:00000001FF

测试结果分析

        经过和日志里数据长度打印和CRC32校验值比对,上述代码提取的报文数据是正确的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值