def _extract_metrics(self, wmi_sampler, tag_by, tag_queries, constant_tags):
        """
        Extract and tag metrics from the WMISampler.

        Raise when multiple WMIObject were returned by the sampler with no `tag_by` specified.

        Returns: List of WMIMetric
        ```
        [
            WMIMetric("freemegabytes", 19742, ["name:_total"]),
            WMIMetric("avgdiskbytesperwrite", 1536, ["name:c:"]),
        ]
        ```
        """
        if len(wmi_sampler) > 1 and not tag_by:
            raise MissingTagBy(
                u"WMI query returned multiple rows but no `tag_by` value was given."
                " class={wmi_class} - properties={wmi_properties} - filters={filters}".format(
                    wmi_class=wmi_sampler.class_name,
                    wmi_properties=wmi_sampler.property_names,
                    filters=wmi_sampler.filters,
                )
            )

        metrics = []
        tag_by = tag_by.lower()

        for wmi_obj in wmi_sampler:
            tags = list(constant_tags) if constant_tags else []

            # Tag with `tag_queries` parameter
            for query in tag_queries:
                try:
                    tags.append(self._get_tag_query_tag(wmi_sampler, wmi_obj, query))
                except TagQueryUniquenessFailure:
                    continue

            for wmi_property, wmi_value in iteritems(wmi_obj):
                # skips any property not in arguments since SWbemServices.ExecQuery will return key prop properties
                # https://msdn.microsoft.com/en-us/library/aa393866(v=vs.85).aspx
                if wmi_property.lower() not in (s.lower() for s in wmi_sampler.property_names):
                    continue
                # Tag with `tag_by` parameter
                if wmi_property == tag_by:
                    tag_value = str(wmi_value).lower()
                    if tag_queries and tag_value.find("#") > 0:
                        tag_value = tag_value[: tag_value.find("#")]

                    tags.append("{name}:{value}".format(name=tag_by, value=tag_value))
                    continue

                # No metric extraction on 'Name' property
                if wmi_property == 'name':
                    continue

                try:
                    metrics.append(WMIMetric(wmi_property, float(wmi_value), tags))
                except ValueError:
                    self.log.warning(
                        u"When extracting metrics with WMI, found a non digit value"
                        " for property '{0}'.".format(wmi_property)
                    )
                    continue
                except TypeError:
                    self.log.warning(
                        u"When extracting metrics with WMI, found a missing property" " '{0}'".format(wmi_property)
                    )
                    continue
        return metrics