<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run(self):
 """Run each line through log2code and group by matched pattern."""

        if ProfileCollection and isinstance(self.mloginfo.logfile,
                                            ProfileCollection):
            print("\n    not available for system.profile collections\n")
            return

        codelines = defaultdict(lambda: 0)
        non_matches = 0

        # get log file information
        logfile = self.mloginfo.logfile
        if logfile.start and logfile.end and not self.mloginfo.args['verbose']:
            progress_start = self.mloginfo._datetime_to_epoch(logfile.start)
            progress_total = (self.mloginfo._datetime_to_epoch(logfile.end) -
                              progress_start)
        else:
            self.mloginfo.progress_bar_enabled = False

        for i, logevent in enumerate(self.mloginfo.logfile):
            cl, _ = self.log2code(logevent.line_str)

            # update progress bar every 1000 lines
            if self.mloginfo.progress_bar_enabled and (i % 1000 == 0):
                if logevent.datetime:
                    progress_curr = self.mloginfo._datetime_to_epoch(logevent
                                                                     .datetime)
                    (self.mloginfo
                     .update_progress(float(progress_curr - progress_start) /
                                      progress_total))

            if cl:
                codelines[cl.pattern] += 1
            else:
                if logevent.operation:
                    # skip operations (command, insert, update, delete,
                    # query, getmore)
                    continue
                if not logevent.thread:
                    # skip the lines that don't have a thread name
                    # (usually map/reduce or assertions)
                    continue
                if len(logevent.split_tokens) - logevent.datetime_nextpos <= 1:
                    # skip empty log messages (after thread name)
                    continue
                if ("warning: log line attempted" in logevent.line_str and
                        "over max size" in logevent.line_str):
                    # skip lines that are too long
                    continue

                # everything else is a real non-match
                non_matches += 1
                if self.mloginfo.args['verbose']:
                    print("couldn't match:" + logevent)

        # clear progress bar again
        if self.mloginfo.progress_bar_enabled:
            self.mloginfo.update_progress(1.0)

        if self.mloginfo.args['verbose']:
            print('')

        for cl in sorted(codelines, key=lambda x: codelines[x], reverse=True):
            print("%8i  %s" % (codelines[cl], " ... ".join(cl)))

        print('')
        if non_matches > 0:
            print("distinct couldn't match %i lines" % non_matches)
            if not self.mloginfo.args['verbose']:
                print("to show non-matched lines, run with --verbose.")