def _parse_step_log_from_log4j_records(records):
    result = {}

    for record in records:
        message = record['message']

        # counters
        if _is_counter_log4j_record(record):
            result['counters'] = _parse_indented_counters(
                message.splitlines())
            continue

        # output_dir
        m = _OUTPUT_DIRECTORY_RE.match(message)
        if m:
            result['output_dir'] = m.group('output_dir')
            continue

        # application_id
        m = _SUBMITTED_APPLICATION_RE.match(message)
        if m:
            result['application_id'] = m.group('application_id')
            continue

        # job_id
        m = _RUNNING_JOB_RE.match(message)
        if m:
            result['job_id'] = m.group('job_id')
            continue

        # task failure
        m = _TASK_ATTEMPT_FAILED_RE.match(message)
        if m:
            error_str = '\n'.join(message.splitlines()[1:])
            if not error_str:  # if no exception, print something
                error_str = message

            error = dict(
                attempt_id=m.group('attempt_id'),
                hadoop_error=dict(
                    message=error_str,
                    num_lines=record['num_lines'],
                    start_line=record['start_line'],
                )
            )

            result.setdefault('errors', [])
            result['errors'].append(error)

    return result
Ensure that the README is in sync with the docstring.
dataset/ETHPy150Open Yelp/mrjob/mrjob/logs/step.py/_parse_step_log_from_log4j_records--crossover with--dataset/ETHPy150Open rfk/promise/promise/tests/__init__.py/test_README