Beispiel #1
0
    def create_config_matcher(self, conf):
        """ Create a function that will return a log configuration when passed in data that matches that config.
        Intended to be overwritten by users of LogConfigManager to match their own use case.
        If passed an empty dictionary in `conf` this should create a catchall matcher with default configuration.

        @param conf: Logger configuration in the form of a dictionary or JsonObject, that a matcher should be created for.
        @return: Logger configuration in the form of a dictionary or JsonObject if this matcher matches the passed
        in data, None otherwise
        """
        config = copy.deepcopy(conf)
        if "journald_unit" not in config:
            config["journald_unit"] = ".*"
        file_template = Template("journald_${ID}.log")
        regex = re.compile(config["journald_unit"])
        match_hash = six.text_type(hash(config["journald_unit"]))
        if config["journald_unit"] == ".*":
            match_hash = "monitor"
        full_path = os.path.join(
            self._global_config.agent_log_path,
            file_template.safe_substitute({"ID": match_hash}),
        )
        matched_config = JsonObject({"parser": "journald", "path": full_path})
        matched_config.update(config)

        def config_matcher(unit):
            if regex.match(unit) is not None:
                return matched_config
            return None

        return config_matcher
    def create_config_matcher(self, conf):
        """Create a function that will return a log configuration when passed in data that matches that config.
        Intended to be overwritten by users of LogConfigManager to match their own use case.
        If passed an empty dictionary in `conf` this should create a catchall matcher with default configuration.

        @param conf: Logger configuration in the form of a dictionary or JsonObject, that a matcher should be created for.
        @return: Logger configuration in the form of a dictionary or JsonObject if this matcher matches the passed
        in data, None otherwise
        """
        config = copy.deepcopy(conf)

        journald_unit = config.get("journald_unit", None, none_if_missing=True)
        journald_globs = config.get("journald_globs",
                                    None,
                                    none_if_missing=True)

        # User shouldn't be able to specify both `journald_unit` and
        # `journald_globs`
        if journald_unit is not None and journald_globs is not None:
            raise BadConfiguration(
                "Cannot specify both journald_unit and journald_globs",
                "journald_unit",
                "invalidConfigError",
            )

        # If neither is specified, default to journald_unit matching
        # everything
        if journald_unit is None and journald_globs is None:
            journald_unit = ".*"
            config["journald_unit"] = journald_unit

        match_hash = "monitor"
        regex = None
        if journald_unit is not None:
            match_hash = six.text_type(hash(journald_unit))
            if journald_unit == ".*":
                match_hash = "monitor"
            regex = re.compile(journald_unit)
        elif journald_globs is not None:
            items = sorted(six.iteritems(journald_globs),
                           key=operator.itemgetter(0))
            match_hash = six.text_type(hash("%s" % items))

        file_template = Template("journald_${ID}.log")
        full_path = os.path.join(
            self._global_config.agent_log_path,
            file_template.safe_substitute({"ID": match_hash}),
        )
        matched_config = JsonObject({"parser": "journald", "path": full_path})
        matched_config.update(config)

        def regex_matcher(fields):
            if regex is None:
                return None

            # Special case where we bail out early if regex is .* aka match all
            if journald_unit == ".*":
                return matched_config

            unit = None
            if isinstance(fields, six.string_types):
                unit = fields
            else:
                # regex only matches on unit
                unit = fields.get("unit", "")

            if unit is not None:
                if regex.match(unit) is not None:
                    return matched_config

            return None

        def glob_matcher(fields):
            if journald_globs is None:
                return None

            # journald_globs requires all fields
            # to match
            for key, glob in six.iteritems(journald_globs):
                if key not in fields:
                    return None

                if not fnmatch.fnmatch(fields[key], glob):
                    return None

            return matched_config

        if journald_globs is not None:
            return glob_matcher

        return regex_matcher