你改的都不行,我把原代码发给你,你参考一下原代码的逻辑,注意,我是要在windows上跑程序,原代码是在Linux上跑的,所以进行了修改
import os
import subprocess
import sys
import time
g_logLevel = ['INVALID', 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']
# g_logLevel 是一个列表,定义了日志的级别。g_logModule 是一个字典,将模块的十六进制编号映射到模块名称
g_logModule = {
0x00 : 'HIVIEW',
0x01 : 'SAMGR',
0x02 : 'UPDATE',
0x03 : 'ACE',
0x04 : 'APP',
0x05 : 'AAFWK',
0x06 : 'GRAPHIC',
0x07 : 'MEDIA',
0x08 : 'DMA',
0x09 : 'SEN',
0x0A : 'SCY',
0x0B : 'XTS',
0x0C : 'SOFTBUS',
0x0D : 'PWM',
0x0E : 'UIKIT',
0x0F : 'GLOBAL',
0x10 : 'DATAMGR',
0x1E : 'HISI',
0x1F : 'COMMU',
0x20 : 'NV',
0x21 : 'BSP',
0x22 : 'DM',
0x23 : 'PM',
0x24 : 'LCD',
0x25 : 'GPS',
0x26 : 'BT',
0x27 : 'NFC',
0x28 : 'SVRAUDIO',
0x29 : 'FTM',
0x2A : 'SVR',
0x2B : 'APPUI',
0x2C : 'AST',
0x2D : 'FIT',
0x2E : 'ALG',
0x2F : 'HRM',
0x30 : 'TLV',
0x31 : 'WIFI',
0x32 : 'INPUT',
0x33 : 'RFID',
0x34 : 'EARSDK',
0x35 : 'SVCOMMU',
0x36 : 'RSMC',
0x37 : 'UWB',
0x38 : 'WATCHEAR',
0x39 : 'PAIR',
0x3A : 'DRVAUDIO',
0x3B : 'BRIGHT',
0x3C : 'FITUI',
0x3D : 'DIALUI',
0x3E : 'FMKUI',
0x3F : 'HRMUI' }
class BIN_INFO():
# 该类用于存储二进制文件的相关信息,包括起始地址、结束地址、二进制内容、文件路径、内容字典和标志。
def __init__(self, flag):
self.start_address = 0
self.end_address = 0
self.bin_content = []
self.bin_path = ""
self.bin_dict = {}
self.flag = flag
class LogProcessThread():
# 该类用于处理日志文件,初始化时接收日志文件和各种二进制文件信息。
def __init__(self, log_file, gpu_info, rom_info, xip_info, itcm_info, sram_info, reverse1_info, reverse2_info):
self.log_file = log_file
self.gpu_info = gpu_info
self.rom_info = rom_info
self.xip_info = xip_info
self.itcm_info = itcm_info
self.sram_info = sram_info
self.reverse1_info = reverse1_info
self.reverse2_info = reverse2_info
def find_address_by_bin(self, logStr, key_index, num_list, bin_files_dict):
# 该方法用于在二进制文件中查找地址对应的字符串,并替换日志字符串中的 % s占位符。
s_list = []
for i in range(len(logStr)):
if logStr[i] == "%" and i != len(logStr) - 1:
s_list.append(logStr[i: i + 2])
for i in range(len(s_list)):
if s_list[i] == "%s":
for j in key_index:
if num_list[i] > j:
address = num_list[i] - j
new_s = ""
if (bin_files_dict.get(j).bin_dict.__contains__(address) == False):
new_s = str(bin_files_dict.get(j).bin_content[address:-1]).split('\\x00', 1)[0]
new_s = new_s[2: len(new_s)]
if isText(logStr):
new_s = new_s.replace('\r', '')
new_s = new_s.replace('\n', '')
new_s = new_s.replace('{public}', '')
new_s = new_s.replace('{private}', '')
new_s = new_s.replace('%ll', '%')
new_s = new_s.replace('%p', '%x')
bin_files_dict.get(j).bin_dict[address] = new_s
else:
new_s = 'NULL'
else:
new_s = bin_files_dict.get(j).bin_dict[address]
num_list[i] = new_s
break
return num_list
def return_format_str(self, logStr, logContent, logContentIndex, num):
# 该方法用于从日志内容中提取格式化字符串的参数。
num_list = []
index = logStr.find('%', 0, len(logStr))
temp_num = 0
while (index >= 0) or (temp_num < num):
startLogIndex = logContentIndex + 12 + temp_num * 4
endLogIndex = logContentIndex + 12 + (temp_num + 1) * 4
if "%d" in logStr[index:index + 2]:
logArgOne = int.from_bytes(logContent[startLogIndex:endLogIndex], "little", signed=True)
num_list.append(logArgOne)
else:
logArgOne = int.from_bytes(logContent[startLogIndex:endLogIndex], "little", signed=False)
num_list.append(logArgOne)
index = logStr.find('%', index + 1, len(logStr))
temp_num += 1
return num_list
def start_parse_v1r6(self):
# 该方法是核心的日志解析方法,从日志文件中读取内容,检查日志的头部信息、级别、模块和参数数量,提取日志字符串和参数,格式化日志信息并写入结果文件。
with open(self.log_file, 'rb') as logFile:
#logFile = open(self.log_file, 'rb')
logFileSize = os.path.getsize(self.log_file)
logFile.seek(0, 0)
logContent = logFile.read(logFileSize)
list1 = [self.gpu_info, self.rom_info, self.xip_info, self.itcm_info, self.sram_info, self.reverse1_info, self.reverse2_info]
bin_files_dict = {}
for i in list1:
if i.start_address != 4294967295 and i.start_address != 0:
bin_files_dict[i.start_address] = i
key_index = sorted(bin_files_dict.keys(), reverse=True)
logResultFile = open(logFileArg + '_offline.txt', 'w', encoding='utf8', errors='ignore')
logContentIndex = self.find_head_index(logContent, 0)
while logContentIndex <= logFileSize - 12:
if logContent[logContentIndex] == 0xED:
# check the log level is in range or not
logLevel = logContent[logContentIndex + 1]
if (logLevel & 0x7F) >= 0x06:
logContentIndex = self.find_head_index(logContent, logContentIndex + 1)
continue
# check the log module is in range or not
logModule = logContent[logContentIndex + 2]
# if g_logModule.__contains__(logModule) == False:
# logContentIndex = logContentIndex + 1
# continue
# check the log arguments is larger than 6 or not
logArgNum = logContent[logContentIndex + 3]
if logArgNum > 6:
logContentIndex = self.find_head_index(logContent, logContentIndex)
continue
logTime = int.from_bytes(logContent[logContentIndex + 4: logContentIndex + 8], "little")
logAddress = int.from_bytes(logContent[logContentIndex + 8: logContentIndex + 12], "little")
logStr = 'NULL'
if logLevel < 0x06:
for i in key_index:
if logAddress > i:
address = logAddress - i
if (bin_files_dict.get(i).bin_dict.__contains__(address) == False):
logStr = str(bin_files_dict.get(i).bin_content[address:-1]).split('\\x00', 1)[0]
logStr = logStr[2: len(logStr)]
if isText(logStr):
logStr = logStr.replace('\\r', '')
logStr = logStr.replace('\\n', '')
logStr = logStr.replace('{public}', '')
logStr = logStr.replace('{private}', '')
logStr = logStr.replace('%ll', '%')
logStr = logStr.replace('%p', '%x')
bin_files_dict.get(i).bin_dict[address] = logStr
else:
logStr = 'NULL'
else:
logStr = bin_files_dict.get(i).bin_dict[address]
break
if (logArgNum == 1) and (logStr.count('%') >= 1):
num_list = self.return_format_str(logStr, logContent, logContentIndex, logArgNum)
if logStr.find('%s') != -1:
num_list = self.find_address_by_bin(logStr, key_index, num_list, bin_files_dict)
try:
logStr = logStr % (num_list[0])
except:
logStr = "{str},{para1}".format(str=logStr,
para1=num_list[0])
elif (logArgNum == 2) and (logStr.count('%') >= 2):
num_list = self.return_format_str(logStr, logContent, logContentIndex, logArgNum)
if logStr.find('%s') != -1:
num_list = self.find_address_by_bin(logStr, key_index, num_list, bin_files_dict)
try:
logStr = logStr % (num_list[0], num_list[1])
except:
logStr = "{str},{para1},{para2}".format(str=logStr,
para1=num_list[0],
para2=num_list[1])
elif (logArgNum == 3) and (logStr.count('%') >= 3):
num_list = self.return_format_str(logStr, logContent, logContentIndex, logArgNum)
if logStr.find('%s') != -1:
num_list = self.find_address_by_bin(logStr, key_index, num_list, bin_files_dict)
try:
logStr = logStr % (num_list[0], num_list[1], num_list[2])
except:
logStr = "{str},{para1},{para2},{para3}".format(str=logStr,
para1=num_list[0],
para2=num_list[1],
para3=num_list[2])
elif (logArgNum == 4) and (logStr.count('%') >= 4):
num_list = self.return_format_str(logStr, logContent, logContentIndex, logArgNum)
if logStr.find('%s') != -1:
num_list = self.find_address_by_bin(logStr, key_index, num_list, bin_files_dict)
try:
logStr = logStr % (num_list[0], num_list[1], num_list[2], num_list[3])
except:
logStr = "{str},{para1},{para2},{para3},{para4}".format(str=logStr,
para1=num_list[0],
para2=num_list[1],
para3=num_list[2],
para4=num_list[3])
elif (logArgNum == 5) and (logStr.count('%') >= 5):
num_list = self.return_format_str(logStr, logContent, logContentIndex, logArgNum)
if logStr.find('%s') != -1:
num_list = self.find_address_by_bin(logStr, key_index, num_list, bin_files_dict)
try:
logStr = logStr % (num_list[0], num_list[1], num_list[2], num_list[3], num_list[4])
except:
logStr = "{str},{para1},{para2},{para3},{para4},{para5}".format(str=logStr,
para1=num_list[0],
para2=num_list[1],
para3=num_list[2],
para4=num_list[3],
para5=num_list[4])
elif (logArgNum == 6) and (logStr.count('%') >= 6):
num_list = self.return_format_str(logStr, logContent, logContentIndex, logArgNum)
if logStr.find('%s') != -1:
num_list = self.find_address_by_bin(logStr, key_index, num_list, bin_files_dict)
try:
logStr = logStr % (num_list[0], num_list[1], num_list[2], num_list[3], num_list[4], num_list[5])
except:
logStr = "{str},{para1},{para2},{para3},{para4},{para5},{para6}".format(str=logStr,
para1=num_list[0],
para2=num_list[1],
para3=num_list[2],
para4=num_list[3],
para5=num_list[4],
para6=num_list[5])
log = "{time},{level},{module},{str}\n".format(
time=time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(logTime)),
level=g_logLevel[logLevel & 0x7F],
module=g_logModule[logModule],
str=logStr)
logResultFile.write(log)
logContentIndex = logContentIndex + 12 + logArgNum * 4
else:
logContentIndex = self.find_head_index(logContent, logContentIndex)
logResultFile.close()
print("success")
def find_head_index(self, logContent, index):
# 该方法用于查找日志头部的起始索引。
firstFlag = logContent[index:].find(0xED) + index
if firstFlag == -1:
return -1
ipos = firstFlag
for i in range(4):
varnum = logContent[ipos + 3]
log_len = 4 * varnum + 12
if log_len < 12 or log_len > 36:
return self.find_head_index(logContent, ipos + 1)
ipos += log_len
if ipos >= len(logContent):
return firstFlag
if log_len == 12 and logContent[ipos] == 0 and logContent[ipos + 1] == 0 and logContent[ipos + 2] == 0 and logContent[ipos + 3] == 0:
ipos += 4
if logContent[ipos] != 0xED:
return self.find_head_index(logContent, ipos + 1)
return firstFlag
def isText(s):
# 该函数用于判断字符串是否为文本。
if len(s) == 0:
return False
if not s:
return False
if (s.count('\\x') >= 1):
return False
return True
def indexOfSubstr(logStr):
# 该函数用于查找日志字符串中 % u的索引。
indexList = []
index = 0
for i in range(len(logStr)):
if logStr[i:i+1] == '%':
index = index + 1
para = logStr[i:i+2]
if para == '%u':
indexList.append(index)
return indexList
def GetBinString(binFile, dict):
# 该函数用于从二进制文件中提取字符串,并存储到字典中。
getStringsInBinCmd = "strings -n8 -td '%s'" % (binFile)
stringsCmdOutPut = subprocess.check_output(getStringsInBinCmd, shell=True)
stringsCmdOutPutText = stringsCmdOutPut.decode('utf-8')
for subString in stringsCmdOutPutText.split('\n'):
if len(subString) > 0:
tempString = subString.lstrip()
stringAddress = int(tempString.split(' ', 1)[0])
logContent = tempString.split(' ', 1)[1]
logContent = logContent.replace('\r', '')
logContent = logContent.replace('\n', '')
logContent = logContent.replace('{public}', '')
logContent = logContent.replace('{private}', '')
logContent = logContent.replace('%ll', '%')
logContent = logContent.replace('%p', '%x')
dict[stringAddress] = logContent
def GetBinFiles(root):
# 该函数用于从指定目录中获取二进制文件列表。
gpu_log_str_bin = ""
mcu_log_str_bin = ""
bin_files = []
for file in os.listdir(root):
if file.__contains__("gpu_log_str.bin"):
gpu_log_str_bin = os.path.join(root, file)
bin_files.append(os.path.join(root, file))
elif file.__contains__("mcu_log_str.bin"):
mcu_log_str_bin = os.path.join(root, file)
bin_files.append(os.path.join(root, file))
elif file[-4:] == ".bin":
bin_files.append(os.path.join(root, file))
return gpu_log_str_bin, mcu_log_str_bin, bin_files
def CheckBinAddr(bin_infos, bin_files):
# 该函数用于检查二进制文件的地址信息是否正确。
for info in bin_infos:
if info.start_address != 4294967295:
flag = True
for i in bin_files:
if info.flag == "application.bin":
if info.flag in i or "OHOS_Image.bin" in i or "factory.bin" in i:
flag = False
info.bin_path = i
elif info.flag in i:
flag = False
info.bin_path = i
if flag:
if info.flag == "application.bin":
errorLog = "error info: need application.bin or OHOS_Image.bin or factory.bin"
else:
errorLog = "error info: need %s" % info.flag
print("{str}".format(str=errorLog))
sys.exit(-1)
def GetBinAddr(log_str_bin):
# 该函数用于从二进制文件中获取地址信息。
with open(log_str_bin, mode="rb") as f:
f.seek(0, 0)
binAddr = f.read(32)
strBinAddr = int.from_bytes(binAddr[4:8], "little")
romBinAddr = int.from_bytes(binAddr[8:12], "little")
xipBinAddr = int.from_bytes(binAddr[12:16], "little")
itcmBinAddr = int.from_bytes(binAddr[16:20], "little")
sramBinAddr = int.from_bytes(binAddr[20:24], "little")
reveser1Addr = int.from_bytes(binAddr[24:28], "little")
reveser2Addr = int.from_bytes(binAddr[28:32], "little")
return strBinAddr, romBinAddr, xipBinAddr, itcmBinAddr, sramBinAddr, reveser1Addr, reveser2Addr
def GetBinFilesString(bin_files):
# 该函数用于获取二进制文件的内容和字符串信息。
for file in bin_files:
if file.start_address != 4294967295:
with open(file.bin_path, 'rb') as f:
binFileSize = os.path.getsize(file.bin_path)
f.seek(0, 0)
file.bin_content = f.read(binFileSize)
file.end_address = file.start_address + binFileSize
GetBinString(file.bin_path, file.bin_dict)
if __name__ == '__main__':
logFileArg = sys.argv[1]
root = sys.argv[2]
gpu_info = BIN_INFO("gpu_log_str.bin")
mcu_info = BIN_INFO("mcu_log_str.bin")
rom_info = BIN_INFO("application.bin")
xip_info = BIN_INFO("xip_code.bin")
itcm_info = BIN_INFO("itcm_code.bin")
sram_info = BIN_INFO("sram_code.bin")
reverse1_info = BIN_INFO("reserve1.bin")
reverse2_info = BIN_INFO("reserve2.bin")
gpu_info.bin_path, mcu_info.bin_path, bin_files = GetBinFiles(root)
if logFileArg.endswith("gpu_debug.log"):
if gpu_info.bin_path == "":
errorLog = "error info: need gpu_log_str.bin"
print("{str}".format(str=errorLog))
sys.exit(-1)
else:
gpu_info.start_address, rom_info.start_address, xip_info.start_address, itcm_info.start_address, sram_info.start_address, \
reverse1_info.start_address, reverse2_info.start_address = GetBinAddr(gpu_info.bin_path)
bin_infos = [gpu_info, rom_info, xip_info, itcm_info, sram_info, reverse1_info, reverse2_info]
CheckBinAddr(bin_infos, bin_files)
GetBinFilesString(bin_infos)
logProcessThread = LogProcessThread(log_file=logFileArg,
gpu_info=gpu_info,
rom_info=rom_info,
xip_info=xip_info,
itcm_info=itcm_info,
sram_info=sram_info,
reverse1_info=reverse1_info,
reverse2_info=reverse2_info, )
logProcessThread.start_parse_v1r6()
elif logFileArg.endswith("mcu_debug.log"):
if mcu_info.bin_path == "":
errorLog = "error info: need mcu_log_str.bin"
print("{str}".format(str=errorLog))
sys.exit(-1)
else:
mcu_info.start_address, rom_info.start_address, xip_info.start_address, itcm_info.start_address, sram_info.start_address, \
reverse1_info.start_address, reverse2_info.start_address = GetBinAddr(mcu_info.bin_path)
bin_infos = [mcu_info, rom_info, xip_info, itcm_info, sram_info, reverse1_info, reverse2_info]
CheckBinAddr(bin_infos, bin_files)
GetBinFilesString(bin_infos)
logProcessThread = LogProcessThread(log_file=logFileArg,
gpu_info=mcu_info,
rom_info=rom_info,
xip_info=xip_info,
itcm_info=itcm_info,
sram_info=sram_info,
reverse1_info=reverse1_info,
reverse2_info=reverse2_info, )
logProcessThread.start_parse_v1r6()
最新发布