Merge lp:~gmb/maas/oo-logging-sexy into lp:~maas-committers/maas/trunk

Proposed by Graham Binns
Status: Merged
Approved by: Graham Binns
Approved revision: no longer in the source branch.
Merged at revision: 2614
Proposed branch: lp:~gmb/maas/oo-logging-sexy
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 143 lines (+66/-16)
4 files modified
src/maasfascist.py (+1/-1)
src/provisioningserver/import_images/tests/test_boot_resources.py (+1/-1)
src/provisioningserver/logger/log.py (+29/-7)
src/provisioningserver/logger/tests/test_logger.py (+35/-7)
To merge this branch: bzr merge lp:~gmb/maas/oo-logging-sexy
Reviewer Review Type Date Requested Status
Julian Edwards (community) Approve
Review via email: mp+228686@code.launchpad.net

Commit message

Put the maaslogger inside a get_maas_logger() function for the sake of sanity and customisation.

To post a comment you must log in.
Revision history for this message
Julian Edwards (julian-edwards) wrote :

Nice work - just the stuff inline as discussed in person.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasfascist.py'
2--- src/maasfascist.py 2014-07-21 20:12:28 +0000
3+++ src/maasfascist.py 2014-07-29 14:38:06 +0000
4@@ -33,7 +33,7 @@
5 from inspect import (
6 getmodule,
7 getsourcefile,
8-)
9+ )
10 from sys import (
11 _getframe as getframe,
12 meta_path,
13
14=== modified file 'src/provisioningserver/import_images/tests/test_boot_resources.py'
15--- src/provisioningserver/import_images/tests/test_boot_resources.py 2014-07-25 13:47:09 +0000
16+++ src/provisioningserver/import_images/tests/test_boot_resources.py 2014-07-29 14:38:06 +0000
17@@ -14,11 +14,11 @@
18 __metaclass__ = type
19 __all__ = []
20
21-import errno
22 from datetime import (
23 datetime,
24 timedelta,
25 )
26+import errno
27 import hashlib
28 import json
29 import os
30
31=== modified file 'src/provisioningserver/logger/log.py'
32--- src/provisioningserver/logger/log.py 2014-07-29 09:36:01 +0000
33+++ src/provisioningserver/logger/log.py 2014-07-29 14:38:06 +0000
34@@ -13,16 +13,38 @@
35
36 __metaclass__ = type
37 __all__ = [
38- "maaslog",
39+ "get_maas_logger",
40 ]
41
42
43 import logging
44 from logging.handlers import SysLogHandler
45
46-maaslog = logging.getLogger("maas")
47-maaslog.setLevel(logging.DEBUG)
48-handler = SysLogHandler("/dev/log")
49-maaslog.addHandler(handler)
50-formatter = logging.Formatter(fmt="maas: %(message)s")
51-handler.setFormatter(formatter)
52+
53+def get_maas_logger(syslog_tag=None):
54+ """Return a MAAS logger that will log to syslog.
55+
56+ :param syslog_tag: A string that will be used to prefix the message
57+ in syslog. Will be appended to "maas" in the form
58+ "maas.<syslog_tag>". If None, the syslog tag will simply be
59+ "maas". syslog_tag is also used to name the logger with the
60+ Python logging module; loggers will be named "maas.<syslog_tag>"
61+ unless syslog_tag is None.
62+ """
63+ if syslog_tag is None:
64+ logger_name = "maas"
65+ else:
66+ logger_name = "maas.%s" % syslog_tag
67+ maaslog = logging.getLogger(logger_name)
68+ # If the logger already has handlers, it's already been
69+ # instantiated, so we don't need to go through the setup dance
70+ # again.
71+ if len(maaslog.handlers) > 0:
72+ return maaslog
73+
74+ maaslog.setLevel(logging.DEBUG)
75+ handler = SysLogHandler("/dev/log")
76+ maaslog.addHandler(handler)
77+ formatter = logging.Formatter(fmt=maaslog.name + ": %(message)s")
78+ handler.setFormatter(formatter)
79+ return maaslog
80
81=== modified file 'src/provisioningserver/logger/tests/test_logger.py'
82--- src/provisioningserver/logger/tests/test_logger.py 2014-07-29 09:36:01 +0000
83+++ src/provisioningserver/logger/tests/test_logger.py 2014-07-29 14:38:06 +0000
84@@ -14,24 +14,52 @@
85 __metaclass__ = type
86 __all__ = []
87
88-import logging.handlers
89+import logging
90+
91 from maastesting.factory import factory
92 from maastesting.matchers import MockCalledOnceWith
93+from provisioningserver.logger import log
94+from provisioningserver.logger.log import get_maas_logger
95 from provisioningserver.testing.testcase import PservTestCase
96
97
98-class TestMAASLog(PservTestCase):
99+class TestGetMAASLogger(PservTestCase):
100
101- def test_logs_to_syslog(self):
102- handler = self.patch(logging.handlers, 'SysLogHandler')
103- from provisioningserver.logger.log import maaslog
104- from provisioningserver.logger import log
105+ def test_logger_logs_to_syslog(self):
106+ handler = self.patch(log, 'SysLogHandler')
107+ self.patch(logging, 'Formatter')
108+ maaslog = get_maas_logger()
109 random_log_text = factory.make_string()
110 maaslog.warn(random_log_text)
111 self.assertThat(
112 handler.return_value.setFormatter,
113- MockCalledOnceWith(log.formatter))
114+ MockCalledOnceWith(logging.Formatter.return_value))
115 self.assertThat(
116 handler, MockCalledOnceWith("/dev/log"))
117 # For future hackers, handler.emit should be getting called here
118 # but it's not. NFI why. HALP.
119+
120+ def test_adds_custom_formatting(self):
121+ self.patch(log, 'SysLogHandler')
122+ formatter = self.patch(logging, 'Formatter')
123+ extra_formatting = factory.make_string()
124+ get_maas_logger(extra_formatting)
125+ self.assertThat(
126+ formatter,
127+ MockCalledOnceWith(
128+ fmt=("maas.%s:" % extra_formatting) + " %(message)s"))
129+
130+ def test_sets_logger_name(self):
131+ self.patch(log, 'SysLogHandler')
132+ self.patch(logging, 'Formatter')
133+ name = factory.make_string()
134+ maaslog = get_maas_logger(name)
135+ self.assertEqual("maas.%s" % name, maaslog.name)
136+
137+ def test_returns_same_logger_if_called_twice(self):
138+ self.patch(log, 'SysLogHandler')
139+ self.patch(logging, 'Formatter')
140+ name = factory.make_string()
141+ maaslog = get_maas_logger(name)
142+ maaslog_2 = get_maas_logger(name)
143+ self.assertIs(maaslog, maaslog_2)