Merge lp:~smoser/cloud-init/log_time into lp:~cloud-init-dev/cloud-init/trunk

Proposed by Scott Moser
Status: Merged
Merged at revision: 854
Proposed branch: lp:~smoser/cloud-init/log_time
Merge into: lp:~cloud-init-dev/cloud-init/trunk
Diff against target: 163 lines (+55/-16)
6 files modified
ChangeLog (+3/-0)
bin/cloud-init (+3/-1)
cloudinit/config/cc_growpart.py (+2/-1)
cloudinit/config/cc_resizefs.py (+5/-6)
cloudinit/sources/DataSourceAzure.py (+7/-8)
cloudinit/util.py (+35/-0)
To merge this branch: bzr merge lp:~smoser/cloud-init/log_time
Reviewer Review Type Date Requested Status
Joshua Harlow (community) Approve
Review via email: mp+177666@code.launchpad.net

Description of the change

add util.log_time helper

The reason for this is that more and more things I was wanting to be able to
see how long they took. This puts that time logic into a single place. It
also supports from /proc/uptime as the timing mechanism.

While reading /proc/uptime is almost certainly slower than time.time(), it does
give millisecond granularity and is not affected by 'ntpdate' having run in
between the two events.

To post a comment you must log in.
Revision history for this message
Joshua Harlow (harlowja) wrote :

LGTM!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ChangeLog'
--- ChangeLog 2013-07-29 16:33:42 +0000
+++ ChangeLog 2013-07-30 18:35:32 +0000
@@ -11,6 +11,9 @@
11 - always finalize handlers even if processing failed (LP: #1203368)11 - always finalize handlers even if processing failed (LP: #1203368)
12 - support merging into cloud-config via jsonp. (LP: #1200476)12 - support merging into cloud-config via jsonp. (LP: #1200476)
13 - add datasource 'SmartOS' for Joyent Cloud. Adds a dependency on serial.13 - add datasource 'SmartOS' for Joyent Cloud. Adds a dependency on serial.
14 - add 'log_time' helper to util for timing how long things take
15 which also reads from uptime. uptime is useful as clock may change during
16 boot due to ntp.
140.7.2:170.7.2:
15 - add a debian watch file18 - add a debian watch file
16 - add 'sudo' entry to ubuntu's default user (LP: #1080717)19 - add 'sudo' entry to ubuntu's default user (LP: #1080717)
1720
=== modified file 'bin/cloud-init'
--- bin/cloud-init 2012-09-20 01:19:43 +0000
+++ bin/cloud-init 2013-07-30 18:35:32 +0000
@@ -502,7 +502,9 @@
502 signal_handler.attach_handlers()502 signal_handler.attach_handlers()
503503
504 (name, functor) = args.action504 (name, functor) = args.action
505 return functor(name, args)505
506 return util.log_time(logfunc=LOG.debug, msg="cloud-init mode '%s'" % name,
507 get_uptime=True, func=functor, args=(name, args))
506508
507509
508if __name__ == '__main__':510if __name__ == '__main__':
509511
=== modified file 'cloudinit/config/cc_growpart.py'
--- cloudinit/config/cc_growpart.py 2013-06-19 06:44:00 +0000
+++ cloudinit/config/cc_growpart.py 2013-07-30 18:35:32 +0000
@@ -264,7 +264,8 @@
264 raise e264 raise e
265 return265 return
266266
267 resized = resize_devices(resizer, devices)267 resized = util.log_time(logfunc=log.debug, msg="resize_devices",
268 func=resize_devices, args=(resizer, devices))
268 for (entry, action, msg) in resized:269 for (entry, action, msg) in resized:
269 if action == RESIZE.CHANGED:270 if action == RESIZE.CHANGED:
270 log.info("'%s' resized: %s" % (entry, msg))271 log.info("'%s' resized: %s" % (entry, msg))
271272
=== modified file 'cloudinit/config/cc_resizefs.py'
--- cloudinit/config/cc_resizefs.py 2013-03-26 19:50:25 +0000
+++ cloudinit/config/cc_resizefs.py 2013-07-30 18:35:32 +0000
@@ -21,7 +21,6 @@
21import errno21import errno
22import os22import os
23import stat23import stat
24import time
2524
26from cloudinit.settings import PER_ALWAYS25from cloudinit.settings import PER_ALWAYS
27from cloudinit import util26from cloudinit import util
@@ -120,9 +119,12 @@
120 if resize_root == NOBLOCK:119 if resize_root == NOBLOCK:
121 # Fork to a child that will run120 # Fork to a child that will run
122 # the resize command121 # the resize command
123 util.fork_cb(do_resize, resize_cmd, log)122 util.fork_cb(
123 util.log_time(logfunc=log.debug, msg="backgrounded Resizing",
124 func=do_resize, args=(resize_cmd, log)))
124 else:125 else:
125 do_resize(resize_cmd, log)126 util.log_time(logfunc=log.debug, msg="Resizing",
127 func=do_resize, args=(resize_cmd, log))
126128
127 action = 'Resized'129 action = 'Resized'
128 if resize_root == NOBLOCK:130 if resize_root == NOBLOCK:
@@ -132,13 +134,10 @@
132134
133135
134def do_resize(resize_cmd, log):136def do_resize(resize_cmd, log):
135 start = time.time()
136 try:137 try:
137 util.subp(resize_cmd)138 util.subp(resize_cmd)
138 except util.ProcessExecutionError:139 except util.ProcessExecutionError:
139 util.logexc(log, "Failed to resize filesystem (cmd=%s)", resize_cmd)140 util.logexc(log, "Failed to resize filesystem (cmd=%s)", resize_cmd)
140 raise141 raise
141 tot_time = time.time() - start
142 log.debug("Resizing took %.3f seconds", tot_time)
143 # TODO(harlowja): Should we add a fsck check after this to make142 # TODO(harlowja): Should we add a fsck check after this to make
144 # sure we didn't corrupt anything?143 # sure we didn't corrupt anything?
145144
=== modified file 'cloudinit/sources/DataSourceAzure.py'
--- cloudinit/sources/DataSourceAzure.py 2013-07-29 16:02:03 +0000
+++ cloudinit/sources/DataSourceAzure.py 2013-07-30 18:35:32 +0000
@@ -138,13 +138,11 @@
138 bname = pk['fingerprint'] + ".crt"138 bname = pk['fingerprint'] + ".crt"
139 fp_files += [os.path.join(mycfg['data_dir'], bname)]139 fp_files += [os.path.join(mycfg['data_dir'], bname)]
140140
141 start = time.time()141 missing = util.log_time(logfunc=LOG.debug, msg="waiting for files",
142 missing = wait_for_files(wait_for + fp_files)142 func=wait_for_files,
143 args=(wait_for + fp_files,))
143 if len(missing):144 if len(missing):
144 LOG.warn("Did not find files, but going on: %s", missing)145 LOG.warn("Did not find files, but going on: %s", missing)
145 else:
146 LOG.debug("waited %.3f seconds for %d files to appear",
147 time.time() - start, len(wait_for))
148146
149 if shcfgxml in missing:147 if shcfgxml in missing:
150 LOG.warn("SharedConfig.xml missing, using static instance-id")148 LOG.warn("SharedConfig.xml missing, using static instance-id")
@@ -206,11 +204,12 @@
206 command = BOUNCE_COMMAND204 command = BOUNCE_COMMAND
207205
208 LOG.debug("pubhname: publishing hostname [%s]", msg)206 LOG.debug("pubhname: publishing hostname [%s]", msg)
209 start = time.time()
210 shell = not isinstance(command, (list, tuple))207 shell = not isinstance(command, (list, tuple))
211 # capture=False, see comments in bug 1202758 and bug 1206164.208 # capture=False, see comments in bug 1202758 and bug 1206164.
212 (output, err) = util.subp(command, shell=shell, capture=False, env=env)209 util.log_time(logfunc=LOG.debug, msg="publishing hostname",
213 LOG.debug("publishing hostname took %.3f seconds", time.time() - start)210 get_uptime=True, func=util.subp,
211 kwargs={'command': command, 'shell': shell, 'capture': False,
212 'env': env})
214213
215214
216def crtfile_to_pubkey(fname):215def crtfile_to_pubkey(fname):
217216
=== modified file 'cloudinit/util.py'
--- cloudinit/util.py 2013-07-24 14:37:36 +0000
+++ cloudinit/util.py 2013-07-30 18:35:32 +0000
@@ -1770,3 +1770,38 @@
1770 return exe_file1770 return exe_file
17711771
1772 return None1772 return None
1773
1774
1775def log_time(logfunc, msg, func, args=None, kwargs=None, get_uptime=False):
1776 if args is None:
1777 args = []
1778 if kwargs is None:
1779 kwargs = {}
1780
1781 start = time.time()
1782
1783 ustart = None
1784 if get_uptime:
1785 try:
1786 ustart = float(uptime())
1787 except ValueError:
1788 pass
1789
1790 try:
1791 ret = func(*args, **kwargs)
1792 finally:
1793 delta = time.time() - start
1794 if ustart is not None:
1795 try:
1796 udelta = float(uptime()) - ustart
1797 except ValueError:
1798 udelta = "N/A"
1799
1800 tmsg = " took %0.3f seconds" % delta
1801 if get_uptime:
1802 tmsg += "(%0.2f)" % udelta
1803 try:
1804 logfunc(msg + tmsg)
1805 except:
1806 pass
1807 return ret