我构建了一个python(2.7)脚本,用这段代码解析txt文件:
cnt = 1
logFile = open( logFilePath, 'r' )
for line in logFile:
if errorCodeGetHostName in line:
errorHostNameCnt = errorHostNameCnt + 1
errorGenericCnt = errorGenericCnt + 1
reportFile.write( "--- Error: GET HOST BY NAME @ line " + str( cnt ) + "\n\r" )
reportFile.write( line )
elif errorCodeSocke462 in line:
errorSocket462Cnt = errorSocket462Cnt + 1
errorGenericCnt = errorGenericCnt + 1
reportFile.write("--- Error: SOCKET -462 @ line " + str(cnt) + "\n\r" )
reportFile.write(line)
elif errorCodeMemory in line:
errorMemoryCnt = errorMemoryCnt + 1
errorGenericCnt = errorGenericCnt + 1
reportFile.write("--- Error: MEMORY NOT RELEASED @ line " + str(cnt) + "\n\r" )
reportFile.write(line)
cnt = cnt + 1
我想添加每个错误的行号,为此我添加了一个计数器(cnt),但其值与实际行号无关。
这是我的日志文件:
=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2017.06.13 17:05:43 =~=~=~=~=~=~=~=~=~=~=~=
UTC Time fetched from server #1: '0.pool.ntp.org'
*** Test (cycle #1) starting...
--- Test01 completed successfully!
--- Test02 completed successfully!
--- Test03 completed successfully!
--- Test04 completed successfully!
--- Test01 completed successfully!
--- Test02 completed successfully!
INF:[CONFIGURATION] Completed
--- Test03 completed successfully!
Firmware Version: 0.0.0
*** Test (cycle #1) starting...
如何获得真实的行号?
感谢您的帮助。
答案 0 :(得分:1)
除了行结尾问题之外,此代码还存在一些其他问题
如评论中所述,最好打开带有with
语句的文件
现在你有一个大循环,你可以循环遍历原始文件,解析它并立即写入ReportFile
。我认为最好将它们分开。
使一个函数循环遍历日志,返回所需的详细信息,以及循环显示这些详细信息并将其写入报告的下一个函数。这是一个更强大,更容易调试和测试出错的时候
我也会让IO尽可能多地在外面。如果您以后想要流式传输到套接字或其他东西,这可以轻松完成
代码的第6到第24行包含很多几乎相同的行,如果要添加另一个要报告的错误,则需要添加另外5行代码,几乎相同。我会使用dict
和for循环来剪切样板代码
较小的一点是,您不会使用Python提供的方便的内容,例如yield
with
- 语句,enumerate
或collections.counter
也可变命名不符合PEP-8
,但主要是审美
errors = {
error_hostname_count: {'error_msg' = '--- Error: GET HOST BY NAME @ line %i'},
error_socker_462: {'error_msg' = '--- Error: SOCKET -462 @ line %i'},
error_hostname_count: {'error_msg' = '--- Error: MEMORY NOT RELEASED @ line %i'},
}
在此定义可能发生的错误以及错误消息的外观
def get_events(log_filehandle):
for line_no, line in enumerate(log_filehandle):
for error_code, error in errors.items():
if error_code in line:
yield line_no, error_code, line
这只需要一个文件句柄(也可以是一个流或缓冲区),只是在那里查找error_codes,如果找到一个,它就会与行一起产生
def generate_report(report_filehandle, error_list):
error_counter = collections.Counter()
for line_no, error_code, error_line in error_list:
error_counter['generic'] += 1
error_counter[error_code] += 1
error_msg = format_error_msg(line_no, error_code)
report_file.write(error_msg)
report_file.write(error_line)
return error_counter
这会循环找到找到的错误。它会增加它们的计数器,格式化消息并将其写入report_file
def format_error_msg(line_no, error_code):
return errors[error_code['error_msg'] % line_no
这使用字符串格式从error_code和line_no
生成消息with open(log_filename, 'r') as log_filehandle, open(report_filename, 'w') as report_filehandle:
error_list = get_events(log_filehandle):
error_counter = print_events(report_filehandle, error_list)
这将它们联系在一起。您可以使用error_counter
向报告添加摘要,或将摘要写入另一个文件或数据库。
这种方法的优点是,如果您的错误识别发生变化,您可以独立于报告执行此操作,反之亦然
答案 1 :(得分:0)
简介:我想要解析的日志来自用C语言编写的嵌入式平台。
我在嵌入式代码中发现,某处有一个带 \ n \ r 的printf而不是 \ r \ n 。我将每个 \ n \ r 替换为与 CR LF 对应的 \ r \ n 。
通过此更改,python脚本可以正常工作!我可以通过它来确定错误。