Начиная с входных данных в виде текста:
txt = """
2019-05-05T00:05:11.507245 12090[12090] 0102b69880c4b330 [DM_FT_INDEX_T_INIT_INDEX_AGENT_MSG] info: Attempting to status Index Agent Instance host-address_9200_IndexAgent
2019-05-05T00:05:11.759829 12090[12090] 0102b69880c4b330 [DM_FT_INDEX_T_INIT_INDEX_AGENT_MSG] info : Response from HTTP_POST command: HTTP/1.1 200 OK Status: 0 , Time Taken: 0 seconds.
2019-05-05T00:05:11.759898 12090[12090] 0102b69880c4b330 [DM_FT_INDEX_T_INIT_INDEX_AGENT_MSG] info : HTTP_POST with args -command status -docbase SubWayX -user dm_fulltext_index_user -ticket ****** -instance host-address_9200_IndexAgent -details false to Index Agent host-address_9200_IndexAgent is successful.
2019-05-05T01:40:53.148751 20135[20135] 0102b69880c4e3b2 JMS DO_METHOD TRACE LAUNCH: do_method launch: successful: user: Xie Xiaoke, session id: 0102b69880c4e3b2, JMS id: 0802b69880003535, method: D2LifecycleChangeStateMethod, host:host-address.net, port:9082, path:/DmMethods/servlet/DoMethod
2019-05-05T01:40:53.148877 20135[20135] 0102b69880c4e3b2 DO_METHOD TRACE LAUNCH: method launch: successful, user: Xie Xiaoke, session id: 0102b69880c4e3b2, method: D2LifecycleChangeStateMethod
2019-05-07T05:42:21.171087 22484[22484] 0102b6988000000b [DM_WORKFLOW_E_PROCESS_AUTO_TASK]error: "Workflow Agent failed to process task 4a02b698800aad04 of workflow 4d02b6988000f709. The task is using method 'D2WFLifeCycleMethod'. Activity: 'Demote to Draft with new Version'. Check the Java Method Server log for errors."
2019-05-05T05:24:48.483966 17114[17114] 0102b69880c4fb1e JMS DO_METHOD TRACE LAUNCH: user: dmadmin, session id: 0102b69880c4fb1e, JMS id: 0802b69880003535, method: D2LifecycleChangeStateMethod, host:host-address.net, port:9082, path:/DmMethods/servlet/DoMethod, arguments:-method_verb com.emc.d2.api.methods.D2Method -class_name com.emc.d2.api.methods.D2LifecycleChangeStateMethod -__dm_docbase__ SubWayX -__dm_server_config__ host-address_SubWayX -docbase_name SubWayX -user_name dmadmin -method_return_id "0802b6988167b46e" -locale en
2019-05-05T05:24:50.362650 17114[17114] 0102b69880c4fb1e JMS DO_METHOD TRACE LAUNCH: do_method launch: successful: user: dmadmin, session id: 0102b69880c4fb1e, JMS id: 0802b69880003535, method: D2LifecycleChangeStateMethod, host:host-address.net, port:9082, path:/DmMethods/servlet/DoMethod
2019-05-05T05:24:50.362702 17114[17114] 0102b69880c4fb1e DO_METHOD TRACE LAUNCH: method launch: successful, user: dmadmin, session id: 0102b69880c4fb1e, method: D2LifecycleChangeStateMethod
2019-05-05T05:44:35.410674 12791[12791] 0102b6988000000c [DM_WORKFLOW_E_PROCESS_AUTO_TASK]error: "Workflow Agent failed to process task 4a02b698800a977c of workflow 4d02b698800107e9. The task is using method 'D2WFLifeCycleMethod'. Activity: 'validate entry conditions for Effective'. Method timed out within 60 secs."
2019-05-05T05:50:31.383668 12791[12791] 0102b6988000000c [DM_WORKFLOW_E_PROCESS_AUTO_TASK]error: "Workflow Agent failed to process task 4a02b698800a9782 of workflow 4d02b6988001081e. The task is using method 'D2WFLifeCycleMethod'. Activity: 'validate entry conditions for Effective'. Method timed out within 60 secs."
2019-05-05T05:53:49.978053 12791[12791] 0102b6988000000c [DM_WORKFLOW_E_PROCESS_AUTO_TASK]error: "Workflow Agent failed to process task 4a02b698800a9784 of workflow 4d02b6988001081c. The task is using method 'D2WFLifeCycleMethod'. Activity: 'validate entry conditions for Effective'. Method timed out within 60 secs."
"""
Мы можем выполнить некоторую предварительную обработку, сначала разбить на строки и отбросить пустые строки:
lines = [line for line in txt.split('\n') if line.strip()]
Затем извлечь фрагменты, которые мы 'нас интересует, но только грубое (и очень быстрое) разбиение данных
parts = [(line[44:60], line[64:].split(':', 1)) for line in lines]
update: , поскольку ваши новые данные не имеют фиксированной ширины, нам потребуется другой способпредварительной обработки, например:
# parts = [(line[44:60], line[64:].split(':', 1)) for line in lines]
import re
lines = [re.sub(r'\s+', ' ', line) for line in lines] # squash all multiple spaces to a single space
parts = [line.split() for line in lines] # split on whitespace
parts = [(line[2], ' '.join(line[3:]).split(':', 1)) for line in parts] # this is similar to the original line
помните, эта часть предназначена только для упрощения окончательной обработки в нижеприведенном классе InputData.
Затем мы создаем структуру данных для вводаданные, которые нас интересуют, которые могут взять предварительно обработанные данные, которые у нас есть, по частям:
class InputData(object):
def __init__(self, idtag, (msg, details)): # py3 is more awkward here (*)
self.idtag = idtag
self.error_task = None
self.error_workflow = None
msg = msg.strip()
if msg.endswith('] info'):
self.msg = msg[1:-len('] info')]
elif msg.endswith('error'):
self.msg = msg[1:-len(']error')]
self.error_task = details.split(' task ', 1)[1].split(' ', 1)[0]
self.error_workflow = details.split(' workflow ', 1)[1].split('.', 1)[0]
else:
self.msg = msg
def __repr__(self):
return repr(self.__dict__) # this is a great trick for making debugging easier
(*) для py3, который вам понадобится (не знаю, почему они это изменили ...?)
def __init__(self, idtag, tmp):
msg, details = tmp
Теперь мы можем применить этот класс к предварительно обработанному вводу:
input_data = [InputData(*part) for part in parts]
и, если мы распечатаем то, что имеем:
for d in input_data:
print d
результат:
{'error_workflow': None, 'error_task': None, 'idtag': '0102b69880c4b330', 'msg': 'DM_FT_INDEX_T_INIT_INDEX_AGENT_MSG'}
{'error_workflow': None, 'error_task': None, 'idtag': '0102b69880c4b330', 'msg': 'DM_FT_INDEX_T_INIT_INDEX_AGENT_MSG'}
{'error_workflow': None, 'error_task': None, 'idtag': '0102b69880c4b330', 'msg': 'DM_FT_INDEX_T_INIT_INDEX_AGENT_MSG'}
{'error_workflow': None, 'error_task': None, 'idtag': '0102b69880c4e3b2', 'msg': 'JMS DO_METHOD TRACE LAUNCH'}
{'error_workflow': None, 'error_task': None, 'idtag': '0102b69880c4e3b2', 'msg': 'DO_METHOD TRACE LAUNCH'}
{'error_workflow': '4d02b6988000f709', 'error_task': '4a02b698800aad04', 'idtag': '0102b6988000000b', 'msg': 'DM_WORKFLOW_E_PROCESS_AUTO_TASK'}
...
Теперь мы создаем класс, представляющий данные, которые мы хотим получить в выводе:
from collections import defaultdict
class OutputData(object):
def __init__(self): # I'm using this class in a defaultdict, so the __init__ method can't take any arguments
self.idtag = None
self.idtag_count = 0
self.messages = defaultdict(int)
self.errors = []
self.workflows = []
def add(self, indata):
"Adds indata to this object."
self.idtag = indata.idtag
self.idtag_count += 1
self.messages[indata.msg] += 1
if indata.error_task:
self.errors.append(indata.error_task)
self.workflows.append(indata.error_workflow)
ивыведите в него входные данные:
output_data = defaultdict(OutputData)
for indata in input_data:
output_data[indata.idtag].add(indata)
наконец, мы можем вывести выходные данные в нужном формате:
fmt = '%-20s %-6s %-55s %-15s %-60s %s'
print fmt % ('ID:', 'Count:', 'Message:', 'msg counts', 'taskid', 'workflowid')
for outdata in output_data.values():
print fmt % (
outdata.idtag,
outdata.idtag_count,
', '.join(outdata.messages.keys()),
', '.join(str(outdata.messages[k]) for k in outdata.messages.keys()),
', '.join(outdata.errors),
', '.join(outdata.workflows)
)
Этот тип структуры, т. е .: текст предварительной обработкиизвлекать интересные входные данные, преобразовывать входные данные в выходные данные и, наконец, сериализовывать / форматировать выходные данные;хорошо работает для всех таких проблем, и это облегчает как отладку, так и изменение в будущем.