class Measure(object): __slots__ = [ "clock", "name", "_logging_context", "start", ] def __init__(self, clock, name): self.clock = clock self.name = name self._logging_context = None self.start = None def __enter__(self): if self._logging_context: raise RuntimeError("Measure() objects cannot be re-used") self.start = self.clock.time() parent_context = LoggingContext.current_context() self._logging_context = LoggingContext("Measure[%s]" % (self.name, ), parent_context) self._logging_context.__enter__() in_flight.register((self.name, ), self._update_in_flight) def __exit__(self, exc_type, exc_val, exc_tb): if not self._logging_context: raise RuntimeError("Measure() block exited without being entered") duration = self.clock.time() - self.start usage = self._logging_context.get_resource_usage() in_flight.unregister((self.name, ), self._update_in_flight) self._logging_context.__exit__(exc_type, exc_val, exc_tb) try: block_counter.labels(self.name).inc() block_timer.labels(self.name).inc(duration) block_ru_utime.labels(self.name).inc(usage.ru_utime) block_ru_stime.labels(self.name).inc(usage.ru_stime) block_db_txn_count.labels(self.name).inc(usage.db_txn_count) block_db_txn_duration.labels(self.name).inc( usage.db_txn_duration_sec) block_db_sched_duration.labels(self.name).inc( usage.db_sched_duration_sec) except ValueError: logger.warning("Failed to save metrics! Usage: %s", usage) def _update_in_flight(self, metrics): """Gets called when processing in flight metrics """ duration = self.clock.time() - self.start metrics.real_time_max = max(metrics.real_time_max, duration) metrics.real_time_sum += duration
class Measure: __slots__ = [ "clock", "name", "_logging_context", "start", ] def __init__(self, clock, name: str): """ Args: clock: A n object with a "time()" method, which returns the current time in seconds. name: The name of the metric to report. """ self.clock = clock self.name = name curr_context = current_context() if not curr_context: logger.warning( "Starting metrics collection %r from sentinel context: metrics will be lost", name, ) parent_context = None else: assert isinstance(curr_context, LoggingContext) parent_context = curr_context self._logging_context = LoggingContext(str(curr_context), parent_context) self.start = None # type: Optional[int] def __enter__(self) -> "Measure": if self.start is not None: raise RuntimeError("Measure() objects cannot be re-used") self.start = self.clock.time() self._logging_context.__enter__() in_flight.register((self.name, ), self._update_in_flight) return self def __exit__(self, exc_type, exc_val, exc_tb): if self.start is None: raise RuntimeError("Measure() block exited without being entered") duration = self.clock.time() - self.start usage = self.get_resource_usage() in_flight.unregister((self.name, ), self._update_in_flight) self._logging_context.__exit__(exc_type, exc_val, exc_tb) try: block_counter.labels(self.name).inc() block_timer.labels(self.name).inc(duration) block_ru_utime.labels(self.name).inc(usage.ru_utime) block_ru_stime.labels(self.name).inc(usage.ru_stime) block_db_txn_count.labels(self.name).inc(usage.db_txn_count) block_db_txn_duration.labels(self.name).inc( usage.db_txn_duration_sec) block_db_sched_duration.labels(self.name).inc( usage.db_sched_duration_sec) except ValueError: logger.warning("Failed to save metrics! Usage: %s", usage) def get_resource_usage(self) -> ContextResourceUsage: """Get the resources used within this Measure block If the Measure block is still active, returns the resource usage so far. """ return self._logging_context.get_resource_usage() def _update_in_flight(self, metrics): """Gets called when processing in flight metrics""" duration = self.clock.time() - self.start metrics.real_time_max = max(metrics.real_time_max, duration) metrics.real_time_sum += duration
class Measure(object): __slots__ = [ "clock", "name", "start_context", "start", "created_context", "start_usage", ] def __init__(self, clock, name): self.clock = clock self.name = name self.start_context = None self.start = None self.created_context = False def __enter__(self): self.start = self.clock.time() self.start_context = LoggingContext.current_context() if not self.start_context: self.start_context = LoggingContext("Measure") self.start_context.__enter__() self.created_context = True self.start_usage = self.start_context.get_resource_usage() in_flight.register((self.name, ), self._update_in_flight) def __exit__(self, exc_type, exc_val, exc_tb): if isinstance(exc_type, Exception) or not self.start_context: return in_flight.unregister((self.name, ), self._update_in_flight) duration = self.clock.time() - self.start block_counter.labels(self.name).inc() block_timer.labels(self.name).inc(duration) context = LoggingContext.current_context() if context != self.start_context: logger.warn( "Context has unexpectedly changed from '%s' to '%s'. (%r)", self.start_context, context, self.name, ) return if not context: logger.warn("Expected context. (%r)", self.name) return current = context.get_resource_usage() usage = current - self.start_usage try: block_ru_utime.labels(self.name).inc(usage.ru_utime) block_ru_stime.labels(self.name).inc(usage.ru_stime) block_db_txn_count.labels(self.name).inc(usage.db_txn_count) block_db_txn_duration.labels(self.name).inc( usage.db_txn_duration_sec) block_db_sched_duration.labels(self.name).inc( usage.db_sched_duration_sec) except ValueError: logger.warn("Failed to save metrics! OLD: %r, NEW: %r", self.start_usage, current) if self.created_context: self.start_context.__exit__(exc_type, exc_val, exc_tb) def _update_in_flight(self, metrics): """Gets called when processing in flight metrics """ duration = self.clock.time() - self.start metrics.real_time_max = max(metrics.real_time_max, duration) metrics.real_time_sum += duration