human
Complete this python program:
def _parse_hadoop_log4j_records(lines, pre_filter=None):
assistant
#Here is the Python code you requested.

    """Parse lines from a hadoop log into log4j records.
    Yield dictionaries with the following keys:
    caller_location -- e.g. \YarnClientImpl.java:submitApplication(251)\
    level -- e.g. \INFO\
    logger -- e.g. \amazon.emr.metrics.MetricsSaver\
    message -- the actual message. If this is a multi-line message (e.g.
    for counters), the lines will be joined by \
    num_lines -- how many lines made up the message
    start_line -- which line the message started on (0-indexed)
    thread -- e.g. \main\. Defaults to \\
    timestamp -- unparsed timestamp, e.g. \15/12/07 20:49:28\,
    \2015-08-22 00:46:18,411\
    Trailing  and
    will be stripped from lines.
    If set, *pre_filter* will be applied to stripped lines. If it
    returns true, we\ll return a fake record with message set to the line,
    num_lines and start_line set as normal, and everything else set to \\.
    Also yields fake records for leading non-log4j lines (trailing non-log4j
    lines are assumed to be part of a multiline message if not pre-filtered).
    """
    last_record = None
    for (line_num, line) in enumerate(lines):
        line = line.rstrip('\r\n')
        def fake_record():
            return dict(caller_location='', level='', logger='', message=line, num_lines=1, start_line=line_num, thread='', timestamp='')
        if pre_filter:
            if pre_filter(line):
                if last_record:
                    last_record['num_lines'] = (line_num - last_record['start_line'])
                    (yield last_record)
                (yield fake_record())
                last_record = None
                continue
        m = (_HADOOP_LOG4J_LINE_RE.match(line) or _HADOOP_LOG4J_LINE_ALTERNATE_RE.match(line))
        if m:
            if last_record:
                last_record['num_lines'] = (line_num - last_record['start_line'])
                (yield last_record)
            last_record = m.groupdict()
            last_record.setdefault('caller_location', '')
            last_record['thread'] = (last_record['thread'] or '')
            last_record['start_line'] = line_num
        elif last_record:
            last_record['message'] += ('\n' + line)
        else:
            (yield fake_record())
    if last_record:
        last_record['num_lines'] = ((line_num + 1) - last_record['start_line'])
        (yield last_record)