Browse Source

Use logging instead of print

- log module supports oslo.config

- orchestrator executable code is split into bin/

Change-Id: Ia1bc509c09c6bd4cc4734d950ee077ae2be30a5b
Changbin Liu 5 years ago
parent
commit
3d62045d44

+ 57
- 0
bin/orchestrator View File

@@ -0,0 +1,57 @@
1
+#!/usr/bin/env python
2
+
3
+import logging
4
+import sys
5
+
6
+import IPython
7
+from oslo.config import cfg
8
+
9
+from inception import __version__
10
+from inception.orchestrator import Orchestrator
11
+from inception.utils import log
12
+
13
+LOGGER = logging.getLogger(__name__)
14
+
15
+CONF = cfg.CONF
16
+
17
+
18
+def main():
19
+    # processes args
20
+    try:
21
+        CONF(args=sys.argv[1:], version="Inception: version %s" % __version__)
22
+    except Exception as e:
23
+        LOGGER.error(e)
24
+        sys.exit(1)
25
+    # start orchestator
26
+    log.setup('inception')
27
+    orchestrator = Orchestrator(CONF.prefix,
28
+                                CONF.num_workers,
29
+                                CONF.atomic,
30
+                                CONF.parallel,
31
+                                CONF.chef_repo,
32
+                                CONF.chef_repo_branch,
33
+                                CONF.ssh_keyfile,
34
+                                CONF.pool,
35
+                                CONF.user,
36
+                                CONF.image,
37
+                                CONF.flavor,
38
+                                CONF.gateway_flavor,
39
+                                CONF.key_name,
40
+                                CONF.security_groups,
41
+                                CONF.src_dir,
42
+                                CONF.dst_dir,
43
+                                CONF.userdata,
44
+                                CONF.timeout,
45
+                                CONF.poll_interval)
46
+    if CONF.shell:
47
+        # give me a ipython shell
48
+        IPython.embed()
49
+        return
50
+    if CONF.cleanup:
51
+        orchestrator.cleanup()
52
+    else:
53
+        orchestrator.start()
54
+
55
+##############################################
56
+if __name__ == "__main__":
57
+    main()

+ 4
- 0
etc/inception/inception.conf.sample View File

@@ -23,3 +23,7 @@ timeout = 999999
23 23
 poll_interval = 5
24 24
 
25 25
 pool = research
26
+
27
+log_dir=/var/log/inception/
28
+
29
+log_file=inception.log

+ 29
- 70
inception/orchestrator.py View File

@@ -1,4 +1,3 @@
1
-#!/usr/bin/env python
2 1
 """
3 2
 #TODO(changbl)
4 3
 Networks:
@@ -22,21 +21,20 @@ WebUI: Horizon-based
22 21
 
23 22
 from collections import OrderedDict
24 23
 import functools
24
+import logging
25 25
 import os
26 26
 import Queue
27 27
 import subprocess
28
-import sys
29 28
 import time
30
-import traceback
31 29
 
32
-import IPython
33 30
 from novaclient.v1_1.client import Client
34 31
 from oslo.config import cfg
35 32
 
36
-from inception import __version__
37 33
 from inception.utils import cmd
38 34
 from inception.utils import wrapper
39 35
 
36
+LOGGER = logging.getLogger(__name__)
37
+
40 38
 orchestrator_opts = [
41 39
     cfg.StrOpt('prefix',
42 40
                default=None,
@@ -235,14 +233,19 @@ class Orchestrator(object):
235 233
             self._deploy_dnsmasq()
236 234
             self._setup_controller()
237 235
             self._setup_workers()
238
-            print "Your inception cloud '%s' is ready!!!" % self.prefix
239
-            print "Gateway IP is %s" % self._gateway_floating_ip.ip
240
-            print "Chef server WebUI is http://%s:4040" % self._chefserver_ip
241
-            print "OpenStack dashboard is https://%s" % self._controller_ip
236
+            LOGGER.info("Your inception cloud '%s' is ready!!!", self.prefix)
237
+            LOGGER.info("Gateway IP is %s", self._gateway_floating_ip.ip)
238
+            LOGGER.info("Chef server WebUI is http://%s:4040",
239
+                        self._chefserver_ip)
240
+            LOGGER.info("OpenStack dashboard is https://%s",
241
+                        self._controller_ip)
242 242
         except Exception:
243
-            print traceback.format_exc()
243
+            LOGGER.exception("Error in launching inception cloud")
244 244
             if self.atomic:
245 245
                 self.cleanup()
246
+                LOGGER.info("Although there was error in creating your "
247
+                            "inception cloud '%s', resources have been "
248
+                            "successfully cleaned up", self.prefix)
246 249
 
247 250
     def _check_existence(self):
248 251
         """
@@ -267,7 +270,7 @@ class Orchestrator(object):
267 270
             security_groups=self.security_groups,
268 271
             userdata=self.userdata)
269 272
         self._gateway_id = gateway.id
270
-        print "Creating %s" % gateway
273
+        LOGGER.info("Creating %s", gateway)
271 274
 
272 275
         # launch chefserver
273 276
         chefserver = self.client.servers.create(
@@ -279,7 +282,7 @@ class Orchestrator(object):
279 282
             userdata=self.userdata,
280 283
             files=self.chefserver_files)
281 284
         self._chefserver_id = chefserver.id
282
-        print "Creating %s" % chefserver
285
+        LOGGER.info("Creating %s", chefserver)
283 286
 
284 287
         # launch controller
285 288
         controller = self.client.servers.create(
@@ -290,7 +293,7 @@ class Orchestrator(object):
290 293
             security_groups=self.security_groups,
291 294
             userdata=self.userdata)
292 295
         self._controller_id = controller.id
293
-        print "Creating %s" % controller
296
+        LOGGER.info("Creating %s", controller)
294 297
 
295 298
         # launch workers
296 299
         for i in xrange(self.num_workers):
@@ -302,10 +305,10 @@ class Orchestrator(object):
302 305
                 security_groups=self.security_groups,
303 306
                 userdata=self.userdata)
304 307
             self._worker_ids.append(worker.id)
305
-            print "Creating %s" % worker
308
+            LOGGER.info("Creating %s", worker)
306 309
 
307
-        print ('wait at most %s seconds for servers to be ready (ssh-able + '
308
-               'userdata done)' % self.timeout)
310
+        LOGGER.info('wait at most %s seconds for servers to be ready'
311
+                    ' (ssh-able + userdata done)', self.timeout)
309 312
         servers_ready = False
310 313
         begin_time = time.time()
311 314
         while time.time() - begin_time <= self.timeout:
@@ -335,8 +338,8 @@ class Orchestrator(object):
335 338
                 servers_ready = True
336 339
                 break
337 340
             except (UnboundLocalError, subprocess.CalledProcessError) as error:
338
-                print ('servers are not all ready, error=%s, sleep %s seconds'
339
-                       % (error, self.poll_interval))
341
+                LOGGER.info('servers are not all ready, error=%s,'
342
+                            ' sleep %s seconds', error, self.poll_interval)
340 343
                 time.sleep(self.poll_interval)
341 344
                 continue
342 345
         if not servers_ready:
@@ -346,7 +349,7 @@ class Orchestrator(object):
346 349
         floating_ip = self.client.floating_ips.create(pool=self.pool)
347 350
         self.client.servers.add_floating_ip(self._gateway_id, floating_ip)
348 351
         self._gateway_floating_ip = floating_ip
349
-        print "Creating and associating %s" % floating_ip
352
+        LOGGER.info("Creating and associating %s", floating_ip)
350 353
 
351 354
     def _get_server_info(self, _id):
352 355
         """
@@ -478,7 +481,7 @@ class Orchestrator(object):
478 481
             got_exception = not exception_queue.empty()
479 482
             while not exception_queue.empty():
480 483
                 thread_name, func_info, exc = exception_queue.get()
481
-                print thread_name, func_info, exc
484
+                LOGGER.error('%s %s %s', thread_name, func_info, exc)
482 485
             if got_exception:
483 486
                 raise RuntimeError("One or more subthreads got exception")
484 487
 
@@ -503,7 +506,7 @@ class Orchestrator(object):
503 506
         """
504 507
         Clean up the whole inception cloud, based on self.prefix
505 508
         """
506
-        print "Let's clean up inception cloud '%s'..." % self.prefix
509
+        LOGGER.info("Let's clean up inception cloud '%s'...", self.prefix)
507 510
         ## find out servers info
508 511
         servers = []
509 512
         gateway = None
@@ -522,62 +525,18 @@ class Orchestrator(object):
522 525
         try:
523 526
             for floating_ip in self.client.floating_ips.list():
524 527
                 if floating_ip.ip == gateway_ip:
525
-                    print ("Disassociating and releasing %s" % floating_ip)
528
+                    LOGGER.info("Disassociating and releasing %s", floating_ip)
526 529
                     self.client.servers.remove_floating_ip(gateway,
527 530
                                                            floating_ip)
528 531
                     self.client.floating_ips.delete(floating_ip)
529 532
         except Exception:
530
-            print traceback.format_exc()
533
+            LOGGER.exception("Error in disassociating/releasing floating IP")
531 534
         ## try deleting each server
532 535
         for server in servers:
533 536
             try:
534
-                print 'Deleting %s' % server
537
+                LOGGER.info('Deleting %s', server)
535 538
                 server.delete()
536 539
             except Exception:
537
-                print traceback.format_exc()
540
+                LOGGER.exception("Error in deleting server %s", server)
538 541
                 continue
539
-        print "Inception cloud '%s' has been cleaned up." % self.prefix
540
-
541
-
542
-def main():
543
-    """
544
-    program starting point
545
-    """
546
-    # processes args
547
-    try:
548
-        CONF(args=sys.argv[1:], version="Inception: version %s" % __version__)
549
-    except Exception as e:
550
-        print e
551
-        sys.exit(1)
552
-    # start orchestator
553
-    orchestrator = Orchestrator(CONF.prefix,
554
-                                CONF.num_workers,
555
-                                CONF.atomic,
556
-                                CONF.parallel,
557
-                                CONF.chef_repo,
558
-                                CONF.chef_repo_branch,
559
-                                CONF.ssh_keyfile,
560
-                                CONF.pool,
561
-                                CONF.user,
562
-                                CONF.image,
563
-                                CONF.flavor,
564
-                                CONF.gateway_flavor,
565
-                                CONF.key_name,
566
-                                CONF.security_groups,
567
-                                CONF.src_dir,
568
-                                CONF.dst_dir,
569
-                                CONF.userdata,
570
-                                CONF.timeout,
571
-                                CONF.poll_interval)
572
-    if CONF.shell:
573
-        # give me a ipython shell
574
-        IPython.embed()
575
-        return
576
-    if CONF.cleanup:
577
-        orchestrator.cleanup()
578
-    else:
579
-        orchestrator.start()
580
-
581
-##############################################
582
-if __name__ == "__main__":
583
-    main()
542
+        LOGGER.info("Inception cloud '%s' has been cleaned up.", self.prefix)

+ 5
- 2
inception/utils/cmd.py View File

@@ -1,8 +1,11 @@
1 1
 """Command execution utils
2 2
 """
3 3
 
4
+import logging
4 5
 import subprocess
5 6
 
7
+LOGGER = logging.getLogger(__name__)
8
+
6 9
 
7 10
 def local(cmd, screen_output=False):
8 11
     """
@@ -14,7 +17,7 @@ def local(cmd, screen_output=False):
14 17
     @return: (output, error)
15 18
       if screen_output is True, return ("", "")
16 19
     """
17
-    print 'executing command=', cmd
20
+    LOGGER.info('executing command=%s', cmd)
18 21
     stdout, stderr = ((None, None) if screen_output
19 22
                       else (subprocess.PIPE, subprocess.PIPE))
20 23
     proc = subprocess.Popen(cmd,
@@ -62,7 +65,7 @@ def ssh(uri, cmd, screen_output=False, silent=True, agent_forwarding=False):
62 65
     if agent_forwarding:
63 66
         flags.append('-A')
64 67
     cmd = 'ssh -p %s %s %s %s' % (port, ' '.join(flags), uri, cmd)
65
-    print 'executing command=', cmd
68
+    LOGGER.info('executing command=%s', cmd)
66 69
     stdout, stderr = ((None, None) if screen_output
67 70
                       else (subprocess.PIPE, subprocess.PIPE))
68 71
     proc = subprocess.Popen(cmd,

+ 56
- 0
inception/utils/log.py View File

@@ -0,0 +1,56 @@
1
+"""logging handler, it allows setting of formatting information through conf
2
+"""
3
+
4
+import logging
5
+import os
6
+
7
+from oslo.config import cfg
8
+
9
+log_opts = [
10
+    cfg.StrOpt('log_formatter',
11
+               default=logging.Formatter('%(asctime)s - %(name)s - '
12
+                                         '%(levelname)s - %(threadName)s - '
13
+                                         '%(message)s'),
14
+               help='log formatter'),
15
+    cfg.StrOpt('log_dir',
16
+               default=None,
17
+               help='path of log file'),
18
+    cfg.StrOpt('log_file',
19
+               default=None,
20
+               help='name of log file'),
21
+    cfg.StrOpt('log_level',
22
+               default='info',
23
+               help='default logging level'),
24
+]
25
+
26
+CONF = cfg.CONF
27
+CONF.register_cli_opts(log_opts)
28
+
29
+LOG_LEVELS = {
30
+    'debug': logging.DEBUG,
31
+    'info': logging.INFO,
32
+    'warning': logging.WARNING,
33
+    'error': logging.ERROR,
34
+    'critical': logging.CRITICAL,
35
+}
36
+
37
+
38
+def setup(product_name):
39
+    """setup logger and its handlers"""
40
+    LOGGER = logging.getLogger(product_name)
41
+    log_level = LOG_LEVELS[CONF.log_level]
42
+    LOGGER.setLevel(log_level)
43
+    ## console logging
44
+    console_handler = logging.StreamHandler()
45
+    console_handler.setLevel(log_level)
46
+    console_handler.setFormatter(CONF.log_formatter)
47
+    LOGGER.addHandler(console_handler)
48
+    ## file logging
49
+    if CONF.log_dir is not None and CONF.log_file is not None:
50
+        if not os.path.exists(CONF.log_dir):
51
+            os.makedirs(CONF.log_dir)
52
+        file_handler = logging.FileHandler(os.path.join(CONF.log_dir,
53
+                                                        CONF.log_file))
54
+        file_handler.setLevel(log_level)
55
+        file_handler.setFormatter(CONF.log_formatter)
56
+        LOGGER.addHandler(file_handler)

+ 4
- 1
inception/utils/wrapper.py View File

@@ -2,9 +2,12 @@
2 2
 Simple wrappers of various Python standard library modules
3 3
 """
4 4
 
5
+import logging
5 6
 import threading
6 7
 import traceback
7 8
 
9
+LOGGER = logging.getLogger(__name__)
10
+
8 11
 
9 12
 class FuncThread(threading.Thread):
10 13
     """
@@ -26,5 +29,5 @@ class FuncThread(threading.Thread):
26 29
             func_info = (str(self._func.func) + " " + str(self._func.args) +
27 30
                          " " + str(self._func.keywords))
28 31
             info = (self.name, func_info, traceback.format_exc())
29
-            print info
32
+            LOGGER.info(info)
30 33
             self._exception_queue.put(info)

Loading…
Cancel
Save