def match_rules(self, log_data):
        """
        Process a log line data message with app's pattern rules.
        Return a tuple with this data:

            Element #0 (app_matched): True if a rule match, False otherwise;
            Element #1 (has_full_match): True if a rule match and is a filter or the
                app has not filters; False if a rule match but is not a filter;
                None otherwise;
            Element #2 (app_thread): Thread value if a rule match and it has a "thread"
                group, None otherwise;
            Element #3 (output_data): Mapping dictionary if a rule match and a map
                of output is requested (--anonymize/--ip/--uid options).
        """
        for rule in self.rules:
            match = rule.regexp.search(log_data.message)
            if match is not None:
                gids = rule.regexp.groupindex
                self._last_rule = rule
                if self.name_cache is not None:
                    values = self.name_cache.match_to_dict(match, rule.key_gids)
                    values['host'] = self.name_cache.map_value(log_data.host, 'host')
                    output_data = {
                        'host': values['host'],
                        'message': self.name_cache.match_to_string(match, gids, values),
                    }
                else:
                    values = {'host': log_data.host}
                    for gid in gids:
                        values[gid] = match.group(gid)
                    output_data = None

                if self._thread and 'thread' in rule.regexp.groupindex:
                    thread = match.group('thread')
                    if rule.filter_keys is not None and \
                            any([values[key] is None for key in rule.filter_keys]):
                        return False, None, None, None
                    if self._report:
                        rule.add_result(values)
                    return True, rule.full_match, thread, output_data
                else:
                    if rule.filter_keys is not None and \
                            any([values[key] is None for key in rule.filter_keys]):
                        return False, None, None, None
                    elif self._report or (rule.filter_keys is not None or not self.has_filters):
                        rule.add_result(values)
                    return True, rule.full_match, None, output_data

        # No rule match: the application log message is not parsable with enabled rules.
        self._last_rule = None
        return False, None, None, None
Process a log line data message with app's pattern rules.
        Return a tuple with this data:

            Element #0 (app_matched): True if a rule match, False otherwise;
            Element #1 (has_full_match): True if a rule match and is a filter or the
                app has not filters; False if a rule match but is not a filter;
                None otherwise;
            Element #2 (app_thread): Thread value if a rule match and it has a "thread"
                group, None otherwise;
            Element #3 (output_data): Mapping dictionary if a rule match and a map
                of output is requested (--anonymize/--ip/--uid options).