在E:\nova\nova\compute\manager.py 中有如下语句:
from oslo_utils import timeutils
在manager.py中使用timeutils的例子如下:
with timeutils.StopWatch() as timer:
self.network_api.deallocate_for_instance(
context, instance, requested_networks=requested_networks)
# nova-network does an rpc call so we're OK tracking time spent here
LOG.info('Took %0.2f seconds to deallocate network for instance.',
timer.elapsed(), instance=instance)
这里就可以通过timer.elapsed() 来显示从timeutils.StopWatch() 到LOG.info 之间也就是deallocate_for_instance 执行的时间.
在oslo_utils 中StopWatch 的实现如下;
https://github.com/openstack/oslo.utils/blob/master/oslo_utils/timeutils.py
class StopWatch(object):
#可以看到StopWatch 有两种状态,分别表示start和stop
_STARTED = 'STARTED'
_STOPPED = 'STOPPED'
#init函数就是基本的赋值,本例中的duration 用的是默认值None
def __init__(self, duration=None):
if duration is not None and duration < 0:
raise ValueError("Duration must be greater or equal to"
" zero and not %s" % duration)
self._duration = duration
self._started_at = None
self._stopped_at = None
self._state = None
self._splits = ()
#开始计数
def start(self):
"""Starts the watch (if not already started).
NOTE(harlowja): resets any splits previously captured (if any).
"""
#如果当前的状态已经是start了,则返回。
if self._state == self._STARTED:
return self
#记录当前的时间
self._started_at = now()
self._stopped_at = None
#设置当前的状态为_STARTED
self._state = self._STARTED
self._splits = ()
return self
@staticmethod
def _delta_seconds(earlier, later):
# Uses max to avoid the delta/time going backwards (and thus negative).
return max(0.0, later - earlier)
#显示调用elapsed显示从with 调用StopWatch 开始到现在的时间
def elapsed(self, maximum=None):
"""Returns how many seconds have elapsed."""
if self._state not in (self._STARTED, self._STOPPED):
raise RuntimeError("Can not get the elapsed time of a stopwatch"
" if it has not been started/stopped")
if self._state == self._STOPPED:
elapsed = self._delta_seconds(self._started_at, self._stopped_at)
else:
elapsed = self._delta_seconds(self._started_at, now())
if maximum is not None and elapsed > maximum:
elapsed = max(0.0, maximum)
return elapsed
#通过with 调用StopWatch的时候,会自动调用__enter__,在__enter__ 中有会调用start 来开始计数
def __enter__(self):
"""Starts the watch."""
self.start()
return self
StopWatch 这个class 有实现__enter__,因此当在with 中调用StopWatch 是会自动调用__enter__,在__enter__ 中有会调用自身的start函数
来记录下当前的时间,当前时间是通过now函数获得,并把时间记录到内部变量_started_at中这样当用户下次在主动调用elapsed的时候就会主动
通过now函数得到当前的时间减去之前记录在_started_at的时间.