test_log.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. from __future__ import generators
  2. import os
  3. import sys
  4. import logging
  5. import unittest2 as unittest
  6. from tempfile import mktemp
  7. from StringIO import StringIO
  8. try:
  9. from contextlib import contextmanager
  10. except ImportError:
  11. from celery.tests.utils import fallback_contextmanager as contextmanager
  12. from carrot.utils import rpartition
  13. from celery import log
  14. from celery.log import (setup_logger, setup_task_logger, emergency_error,
  15. get_default_logger, get_task_logger,
  16. redirect_stdouts_to_logger, LoggingProxy)
  17. from celery.tests.utils import override_stdouts, execute_context
  18. from celery.utils import gen_unique_id
  19. from celery.utils.compat import LoggerAdapter
  20. from celery.utils.compat import _CompatLoggerAdapter
  21. def get_handlers(logger):
  22. if isinstance(logger, LoggerAdapter):
  23. return logger.logger.handlers
  24. return logger.handlers
  25. def set_handlers(logger, new_handlers):
  26. if isinstance(logger, LoggerAdapter):
  27. logger.logger.handlers = new_handlers
  28. logger.handlers = new_handlers
  29. @contextmanager
  30. def wrap_logger(logger, loglevel=logging.ERROR):
  31. old_handlers = get_handlers(logger)
  32. sio = StringIO()
  33. siohandler = logging.StreamHandler(sio)
  34. set_handlers(logger, [siohandler])
  35. yield sio
  36. set_handlers(logger, old_handlers)
  37. class test_default_logger(unittest.TestCase):
  38. def setUp(self):
  39. self.setup_logger = setup_logger
  40. self.get_logger = get_default_logger
  41. log._setup = False
  42. def _assertLog(self, logger, logmsg, loglevel=logging.ERROR):
  43. def with_wrap_logger(sio):
  44. logger.log(loglevel, logmsg)
  45. return sio.getvalue().strip()
  46. context = wrap_logger(logger, loglevel=loglevel)
  47. execute_context(context, with_wrap_logger)
  48. def assertDidLogTrue(self, logger, logmsg, reason, loglevel=None):
  49. val = self._assertLog(logger, logmsg, loglevel=loglevel)
  50. return self.assertEqual(val, logmsg, reason)
  51. def assertDidLogFalse(self, logger, logmsg, reason, loglevel=None):
  52. val = self._assertLog(logger, logmsg, loglevel=loglevel)
  53. return self.assertFalse(val, reason)
  54. def test_setup_logger(self):
  55. logger = self.setup_logger(loglevel=logging.ERROR, logfile=None,
  56. root=False)
  57. set_handlers(logger, [])
  58. logger = self.setup_logger(loglevel=logging.ERROR, logfile=None,
  59. root=False)
  60. self.assertIs(get_handlers(logger)[0].stream, sys.__stderr__,
  61. "setup_logger logs to stderr without logfile argument.")
  62. self.assertDidLogFalse(logger, "Logging something",
  63. "Logger doesn't info when loglevel is ERROR",
  64. loglevel=logging.INFO)
  65. def test_emergency_error(self):
  66. sio = StringIO()
  67. emergency_error(sio, "Testing emergency error facility")
  68. self.assertEqual(rpartition(sio.getvalue(), ":")[2].strip(),
  69. "Testing emergency error facility")
  70. def test_setup_logger_no_handlers_stream(self):
  71. l = self.get_logger()
  72. set_handlers(l, [])
  73. def with_override_stdouts(outs):
  74. stdout, stderr = outs
  75. l = self.setup_logger(logfile=stderr, loglevel=logging.INFO,
  76. root=False)
  77. l.info("The quick brown fox...")
  78. self.assertIn("The quick brown fox...", stderr.getvalue())
  79. context = override_stdouts()
  80. execute_context(context, with_override_stdouts)
  81. def test_setup_logger_no_handlers_file(self):
  82. l = self.get_logger()
  83. set_handlers(l, [])
  84. tempfile = mktemp(suffix="unittest", prefix="celery")
  85. l = self.setup_logger(logfile=tempfile, loglevel=0, root=False)
  86. self.assertIsInstance(get_handlers(l)[0],
  87. logging.FileHandler)
  88. def test_emergency_error_stderr(self):
  89. def with_override_stdouts(outs):
  90. stdout, stderr = outs
  91. emergency_error(None, "The lazy dog crawls under the fast fox")
  92. self.assertIn("The lazy dog crawls under the fast fox",
  93. stderr.getvalue())
  94. context = override_stdouts()
  95. execute_context(context, with_override_stdouts)
  96. def test_emergency_error_file(self):
  97. tempfile = mktemp(suffix="unittest", prefix="celery")
  98. emergency_error(tempfile, "Vandelay Industries")
  99. tempfilefh = open(tempfile, "r")
  100. try:
  101. self.assertIn("Vandelay Industries", "".join(tempfilefh))
  102. finally:
  103. tempfilefh.close()
  104. os.unlink(tempfile)
  105. def test_redirect_stdouts(self):
  106. logger = self.setup_logger(loglevel=logging.ERROR, logfile=None,
  107. root=False)
  108. try:
  109. def with_wrap_logger(sio):
  110. redirect_stdouts_to_logger(logger, loglevel=logging.ERROR)
  111. logger.error("foo")
  112. self.assertIn("foo", sio.getvalue())
  113. context = wrap_logger(logger)
  114. execute_context(context, with_wrap_logger)
  115. finally:
  116. sys.stdout, sys.stderr = sys.__stdout__, sys.__stderr__
  117. def test_logging_proxy(self):
  118. logger = self.setup_logger(loglevel=logging.ERROR, logfile=None,
  119. root=False)
  120. def with_wrap_logger(sio):
  121. p = LoggingProxy(logger)
  122. p.close()
  123. p.write("foo")
  124. self.assertNotIn("foo", sio.getvalue())
  125. p.closed = False
  126. p.write("foo")
  127. self.assertIn("foo", sio.getvalue())
  128. lines = ["baz", "xuzzy"]
  129. p.writelines(lines)
  130. for line in lines:
  131. self.assertIn(line, sio.getvalue())
  132. p.flush()
  133. p.close()
  134. self.assertFalse(p.isatty())
  135. self.assertIsNone(p.fileno())
  136. context = wrap_logger(logger)
  137. execute_context(context, with_wrap_logger)
  138. class test_task_logger(test_default_logger):
  139. def setUp(self):
  140. self.setup_logger = setup_task_logger
  141. self.get_logger = get_task_logger
  142. class MockLogger(logging.Logger):
  143. _records = None
  144. def __init__(self, *args, **kwargs):
  145. self._records = []
  146. logging.Logger.__init__(self, *args, **kwargs)
  147. def handle(self, record):
  148. self._records.append(record)
  149. def isEnabledFor(self, level):
  150. return True
  151. class test_CompatLoggerAdapter(unittest.TestCase):
  152. levels = ("debug",
  153. "info",
  154. "warn", "warning",
  155. "error",
  156. "fatal", "critical")
  157. def setUp(self):
  158. self.logger, self.adapter = self.createAdapter()
  159. def createAdapter(self, name=None, extra={"foo": "bar"}):
  160. logger = MockLogger(name=name or gen_unique_id())
  161. return logger, _CompatLoggerAdapter(logger, extra)
  162. def test_levels(self):
  163. for level in self.levels:
  164. msg = "foo bar %s" % (level, )
  165. logger, adapter = self.createAdapter()
  166. getattr(adapter, level)(msg)
  167. self.assertEqual(logger._records[0].msg, msg)
  168. def test_exception(self):
  169. try:
  170. raise KeyError("foo")
  171. except KeyError:
  172. self.adapter.exception("foo bar exception")
  173. self.assertEqual(self.logger._records[0].msg, "foo bar exception")
  174. def test_setLevel(self):
  175. self.adapter.setLevel(logging.INFO)
  176. self.assertEqual(self.logger.level, logging.INFO)
  177. def test_process(self):
  178. msg, kwargs = self.adapter.process("foo bar baz", {"exc_info": 1})
  179. self.assertDictEqual(kwargs, {"exc_info": 1,
  180. "extra": {"foo": "bar"}})
  181. def test_add_remove_handlers(self):
  182. handler = logging.StreamHandler()
  183. self.adapter.addHandler(handler)
  184. self.assertIs(self.logger.handlers[0], handler)
  185. self.adapter.removeHandler(handler)
  186. self.assertListEqual(self.logger.handlers, [])