Esempio n. 1
0
class VMBulkSampler(object):
    def __init__(self, conn, get_vms, stats_cache,
                 stats_flags=0, ttl=_TTL):
        self._conn = conn
        self._get_vms = get_vms
        self._stats_cache = stats_cache
        self._stats_flags = stats_flags
        self._skip_doms = ExpiringCache(ttl)
        self._sampling = threading.Semaphore()  # used as glorified counter
        self._log = logging.getLogger("virt.sampling.VMBulkSampler")

    def __call__(self):
        timestamp = self._stats_cache.clock()
        acquired = self._sampling.acquire(blocking=False)
        # we are deep in the hot path. bool(ExpiringCache)
        # *is* costly so we should avoid it if we can.
        fast_path = acquired and not self._skip_doms
        try:
            if fast_path:
                # This is expected to be the common case.
                # If everything's ok, we can skip all the costly checks.
                bulk_stats = self._conn.getAllDomainStats(self._stats_flags)
            else:
                # A previous call got stuck, or not every domain
                # has properly recovered. Thus we must whitelist domains.
                doms = self._get_responsive_doms()
                self._log.debug('sampling %d domains', len(doms))
                if doms:
                    bulk_stats = self._conn.domainListGetStats(
                        doms, self._stats_flags)
                else:
                    bulk_stats = []
        except Exception:
            self._log.exception("vm sampling failed")
        else:
            self._stats_cache.put(_translate(bulk_stats), timestamp)
        finally:
            if acquired:
                self._sampling.release()

    def _get_responsive_doms(self):
        vms = self._get_vms()
        doms = []
        for vm_id, vm_obj in vms.iteritems():
            to_skip = self._skip_doms.get(vm_id, False)
            if to_skip:
                continue
            elif not vm_obj.isDomainReadyForCommands():
                self._skip_doms[vm_id] = True
            else:
                # TODO: This racy check may fail if the underlying libvirt
                # domain has died just after checking isDomainReadyForCommands
                # succeeded.
                doms.append(vm_obj._dom._dom)
        return doms
Esempio n. 2
0
class VMBulkSampler(object):
    def __init__(self, conn, get_vms, stats_cache, stats_flags=0, ttl=_TTL):
        self._conn = conn
        self._get_vms = get_vms
        self._stats_cache = stats_cache
        self._stats_flags = stats_flags
        self._skip_doms = ExpiringCache(ttl)
        self._sampling = threading.Semaphore()  # used as glorified counter
        self._log = logging.getLogger("virt.sampling.VMBulkSampler")

    def __call__(self):
        timestamp = self._stats_cache.clock()
        acquired = self._sampling.acquire(blocking=False)
        # we are deep in the hot path. bool(ExpiringCache)
        # *is* costly so we should avoid it if we can.
        fast_path = acquired and not self._skip_doms
        try:
            if fast_path:
                # This is expected to be the common case.
                # If everything's ok, we can skip all the costly checks.
                bulk_stats = self._conn.getAllDomainStats(self._stats_flags)
            else:
                # A previous call got stuck, or not every domain
                # has properly recovered. Thus we must whitelist domains.
                doms = self._get_responsive_doms()
                self._log.debug('sampling %d domains', len(doms))
                if doms:
                    bulk_stats = self._conn.domainListGetStats(
                        doms, self._stats_flags)
                else:
                    bulk_stats = []
        except Exception:
            self._log.exception("vm sampling failed")
        else:
            self._stats_cache.put(_translate(bulk_stats), timestamp)
        finally:
            if acquired:
                self._sampling.release()

    def _get_responsive_doms(self):
        vms = self._get_vms()
        doms = []
        for vm_id, vm_obj in vms.iteritems():
            to_skip = self._skip_doms.get(vm_id, False)
            if to_skip:
                continue
            elif not vm_obj.isDomainReadyForCommands():
                self._skip_doms[vm_id] = True
            else:
                # TODO: This racy check may fail if the underlying libvirt
                # domain has died just after checking isDomainReadyForCommands
                # succeeded.
                doms.append(vm_obj._dom._dom)
        return doms
Esempio n. 3
0
class VMBulkstatsMonitor(object):
    def __init__(self,
                 conn,
                 get_vms,
                 stats_cache,
                 stats_types=BULK_STATS_TYPES,
                 ttl=_TTL):
        self._conn = conn
        self._get_vms = get_vms
        self._stats_cache = stats_cache
        self._stats_types = stats_types
        self._skip_doms = ExpiringCache(ttl)
        self._sampling = threading.Semaphore()  # used as glorified counter
        self._log = logging.getLogger("virt.sampling.VMBulkstatsMonitor")

    def __call__(self):
        log_status = True
        timestamp = self._stats_cache.clock()
        acquired = self._sampling.acquire(blocking=False)
        # we are deep in the hot path. bool(ExpiringCache)
        # *is* costly so we should avoid it if we can.
        fast_path = acquired and not self._skip_doms
        doms = []  # whitelist, meaningful only in the slow path
        flags = libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING
        if _NOWAIT_ENABLED:
            flags |= libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_NOWAIT
        try:
            if fast_path:
                # This is expected to be the common case.
                # If everything's ok, we can skip all the costly checks.
                bulk_stats = self._conn.getAllDomainStats(
                    stats=self._stats_types, flags=flags)
            else:
                # A previous call got stuck, or not every domain
                # has properly recovered. Thus we must whitelist domains.
                doms = self._get_responsive_doms()
                if doms:
                    bulk_stats = self._conn.domainListGetStats(
                        doms, stats=self._stats_types, flags=flags)
                else:
                    bulk_stats = []
        except Exception:
            self._log.exception("vm sampling failed")
            log_status = False
        else:
            self._stats_cache.put(_translate(bulk_stats), timestamp)
        finally:
            if acquired:
                self._sampling.release()
        if log_status:
            self._log.debug(
                'sampled timestamp %r elapsed %.3f acquired %r domains %s',
                timestamp,
                self._stats_cache.clock() - timestamp, acquired,
                'all' if fast_path else len(doms))

    def _get_responsive_doms(self):
        vms = self._get_vms()
        doms = []
        for vm_id, vm_obj in six.iteritems(vms):
            to_skip = self._skip_doms.get(vm_id, False)
            if to_skip:
                continue
            elif not vm_obj.isDomainReadyForCommands():
                self._skip_doms[vm_id] = True
            else:
                # TODO: This racy check may fail if the underlying libvirt
                # domain has died just after checking isDomainReadyForCommands
                # succeeded.
                doms.append(vm_obj._dom._dom)
        return doms
Esempio n. 4
0
class VMBulkSampler(object):
    def __init__(self, conn, get_vms, stats_cache,
                 stats_flags=0, ttl=_TTL):
        self._conn = conn
        self._get_vms = get_vms
        self._stats_cache = stats_cache
        self._stats_flags = stats_flags
        self._skip_doms = ExpiringCache(ttl)
        self._sampling = threading.Semaphore()  # used as glorified counter
        self._log = logging.getLogger("virt.sampling.VMBulkSampler")

    def __call__(self):
        log_status = True
        timestamp = self._stats_cache.clock()
        acquired = self._sampling.acquire(blocking=False)
        # we are deep in the hot path. bool(ExpiringCache)
        # *is* costly so we should avoid it if we can.
        fast_path = acquired and not self._skip_doms
        doms = []  # whitelist, meaningful only in the slow path
        try:
            if fast_path:
                # This is expected to be the common case.
                # If everything's ok, we can skip all the costly checks.
                bulk_stats = self._conn.getAllDomainStats(self._stats_flags)
            else:
                # A previous call got stuck, or not every domain
                # has properly recovered. Thus we must whitelist domains.
                doms = self._get_responsive_doms()
                if doms:
                    bulk_stats = self._conn.domainListGetStats(
                        doms, self._stats_flags)
                else:
                    bulk_stats = []
        except Exception:
            self._log.exception("vm sampling failed")
            log_status = False
        else:
            self._stats_cache.put(_translate(bulk_stats), timestamp)
        finally:
            if acquired:
                self._sampling.release()
        if log_status:
            self._log.debug(
                'sampled timestamp %r elapsed %.3f acquired %r domains %s',
                timestamp,  self._stats_cache.clock() - timestamp, acquired,
                'all' if fast_path else len(doms))
        if _METRICS_ENABLED:
            self._send_metrics()

    def _send_metrics(self):
        vms = self._get_vms()
        vm_samples = self._stats_cache.get_batch()
        if vm_samples is None:
            return
        stats = {}
        for vm_id, vm_sample in six.iteritems(vm_samples):
            vm_obj = vms[vm_id]
            vm_data = vmstats.produce(vm_obj,
                                      vm_sample.first_value,
                                      vm_sample.last_value,
                                      vm_sample.interval)
            vm_data["vmName"] = vm_obj.name
            stats[vm_id] = vm_data
        vmstats.send_metrics(stats)

    def _get_responsive_doms(self):
        vms = self._get_vms()
        doms = []
        for vm_id, vm_obj in six.iteritems(vms):
            to_skip = self._skip_doms.get(vm_id, False)
            if to_skip:
                continue
            elif not vm_obj.isDomainReadyForCommands():
                self._skip_doms[vm_id] = True
            else:
                # TODO: This racy check may fail if the underlying libvirt
                # domain has died just after checking isDomainReadyForCommands
                # succeeded.
                doms.append(vm_obj._dom._dom)
        return doms
Esempio n. 5
0
class VMBulkstatsMonitor(object):
    def __init__(self, conn, get_vms, stats_cache,
                 stats_types=BULK_STATS_TYPES, ttl=_TTL):
        self._conn = conn
        self._get_vms = get_vms
        self._stats_cache = stats_cache
        self._stats_types = stats_types
        self._skip_doms = ExpiringCache(ttl)
        self._sampling = threading.Semaphore()  # used as glorified counter
        self._log = logging.getLogger("virt.sampling.VMBulkstatsMonitor")

    def __call__(self):
        log_status = True
        timestamp = self._stats_cache.clock()
        acquired = self._sampling.acquire(blocking=False)
        # we are deep in the hot path. bool(ExpiringCache)
        # *is* costly so we should avoid it if we can.
        fast_path = acquired and not self._skip_doms
        doms = []  # whitelist, meaningful only in the slow path
        flags = libvirt.VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING  # shortcut
        try:
            if fast_path:
                # This is expected to be the common case.
                # If everything's ok, we can skip all the costly checks.
                bulk_stats = self._conn.getAllDomainStats(
                    stats=self._stats_types, flags=flags)
            else:
                # A previous call got stuck, or not every domain
                # has properly recovered. Thus we must whitelist domains.
                doms = self._get_responsive_doms()
                if doms:
                    bulk_stats = self._conn.domainListGetStats(
                        doms, stats=self._stats_types, flags=flags)
                else:
                    bulk_stats = []
        except Exception:
            self._log.exception("vm sampling failed")
            log_status = False
        else:
            self._stats_cache.put(_translate(bulk_stats), timestamp)
        finally:
            if acquired:
                self._sampling.release()
        if log_status:
            self._log.debug(
                'sampled timestamp %r elapsed %.3f acquired %r domains %s',
                timestamp, self._stats_cache.clock() - timestamp, acquired,
                'all' if fast_path else len(doms))

    def _get_responsive_doms(self):
        vms = self._get_vms()
        doms = []
        for vm_id, vm_obj in six.iteritems(vms):
            to_skip = self._skip_doms.get(vm_id, False)
            if to_skip:
                continue
            elif not vm_obj.isDomainReadyForCommands():
                self._skip_doms[vm_id] = True
            else:
                # TODO: This racy check may fail if the underlying libvirt
                # domain has died just after checking isDomainReadyForCommands
                # succeeded.
                doms.append(vm_obj._dom._dom)
        return doms
Esempio n. 6
0
class VMBulkSampler(object):
    def __init__(self, conn, get_vms, stats_cache,
                 stats_flags=0, ttl=_TTL):
        self._conn = conn
        self._get_vms = get_vms
        self._stats_cache = stats_cache
        self._stats_flags = stats_flags
        self._skip_doms = ExpiringCache(ttl)
        self._sampling = threading.Semaphore()  # used as glorified counter
        self._log = logging.getLogger("virt.sampling.VMBulkSampler")

    def __call__(self):
        log_status = True
        timestamp = self._stats_cache.clock()
        acquired = self._sampling.acquire(blocking=False)
        # we are deep in the hot path. bool(ExpiringCache)
        # *is* costly so we should avoid it if we can.
        fast_path = acquired and not self._skip_doms
        doms = []  # whitelist, meaningful only in the slow path
        try:
            if fast_path:
                # This is expected to be the common case.
                # If everything's ok, we can skip all the costly checks.
                bulk_stats = self._conn.getAllDomainStats(self._stats_flags)
            else:
                # A previous call got stuck, or not every domain
                # has properly recovered. Thus we must whitelist domains.
                doms = self._get_responsive_doms()
                if doms:
                    bulk_stats = self._conn.domainListGetStats(
                        doms, self._stats_flags)
                else:
                    bulk_stats = []
        except Exception:
            self._log.exception("vm sampling failed")
            log_status = False
        else:
            self._stats_cache.put(_translate(bulk_stats), timestamp)
        finally:
            if acquired:
                self._sampling.release()
        if log_status:
            self._log.debug(
                'sampled timestamp %r elapsed %.3f acquired %r domains %s',
                timestamp, self._stats_cache.clock() - timestamp, acquired,
                'all' if fast_path else len(doms))
        if _METRICS_ENABLED:
            self._send_metrics()

    def _send_metrics(self):
        vms = self._get_vms()
        vm_samples = self._stats_cache.get_batch()
        if vm_samples is None:
            return
        stats = {}
        for vm_id, vm_sample in six.iteritems(vm_samples):
            vm_obj = vms[vm_id]
            vm_data = vmstats.produce(vm_obj,
                                      vm_sample.first_value,
                                      vm_sample.last_value,
                                      vm_sample.interval)
            vm_data["vmName"] = vm_obj.name
            stats[vm_id] = vm_data
        vmstats.send_metrics(stats)

    def _get_responsive_doms(self):
        vms = self._get_vms()
        doms = []
        for vm_id, vm_obj in six.iteritems(vms):
            to_skip = self._skip_doms.get(vm_id, False)
            if to_skip:
                continue
            elif not vm_obj.isDomainReadyForCommands():
                self._skip_doms[vm_id] = True
            else:
                # TODO: This racy check may fail if the underlying libvirt
                # domain has died just after checking isDomainReadyForCommands
                # succeeded.
                doms.append(vm_obj._dom._dom)
        return doms