[CalendarServer-changes] [2319]
CalendarServer/branches/users/wsanchez/logging/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Wed Apr 16 12:19:33 PDT 2008
Revision: 2319
http://trac.macosforge.org/projects/calendarserver/changeset/2319
Author: wsanchez at apple.com
Date: 2008-04-16 12:19:33 -0700 (Wed, 16 Apr 2008)
Log Message:
-----------
First pass at level-based logging support.
Added Paths:
-----------
CalendarServer/branches/users/wsanchez/logging/twistedcaldav/log.py
CalendarServer/branches/users/wsanchez/logging/twistedcaldav/test/test_log.py
Added: CalendarServer/branches/users/wsanchez/logging/twistedcaldav/log.py
===================================================================
--- CalendarServer/branches/users/wsanchez/logging/twistedcaldav/log.py (rev 0)
+++ CalendarServer/branches/users/wsanchez/logging/twistedcaldav/log.py 2008-04-16 19:19:33 UTC (rev 2319)
@@ -0,0 +1,120 @@
+##
+# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Classes and functions to do better logging.
+
+Example usage in a module:
+
+ from twistedcaldav.log import Logger
+ log = Logger()
+
+ log.info("Blah blah")
+
+Or in a class:
+
+ from twistedcaldav.log import LoggingMixIn
+
+ class Foo (object, LoggingMixIn):
+ def oops(self):
+ self.error("Oops!")
+"""
+
+__all__ = [
+ "logLevels",
+ "Logger",
+ "LoggingMixIn",
+]
+
+import inspect
+
+from twisted.python import log
+
+logLevels = (
+ "debug",
+ "info",
+ "warn",
+ "error",
+)
+
+logLevelIndexes = dict(zip(logLevels, xrange(0, len(logLevels))))
+
+class Logger (object):
+ """
+ Logging object.
+ """
+ def __init__(self, namespace=None):
+ """
+ @param namespace: The namespace for this logger. Uses a
+ dotted notation, as used by python modules. If not
+ C{None}, then the name of the module of the caller
+ is used.
+ """
+ if namespace is None:
+ currentFrame = inspect.currentframe()
+ callerFrame = currentFrame.f_back
+ callerModule = callerFrame.f_globals["__name__"]
+
+ namespace = callerModule
+
+ self.namespace = namespace
+
+ def emit(self, level, message, **kwargs):
+ log.msg(
+ str(message),
+ isError = (level == "error"),
+ level = level,
+ namespace = self.namespace,
+ **kwargs
+ )
+
+class LoggingMixIn (object):
+ """
+ Mix-in class for logging methods.
+ """
+ def _getLogger(self):
+ try:
+ return self._logger
+ except AttributeError:
+ namespace = repr(self.__class__)[8:-2]
+
+ assert repr(self.__class__)[:8] == "<class '"
+ assert repr(self.__class__)[-2:] == "'>"
+ assert namespace.find("'") == -1
+
+ self._logger = Logger(namespace)
+
+ return self._logger
+
+ def _setLogger(self, value):
+ self._logger = value
+
+ logger = property(_getLogger, _setLogger)
+
+for level in logLevels:
+ def log_level(self, message, level=level, **kwargs):
+ self.emit(level, message, **kwargs)
+ setattr(Logger, level, log_level)
+
+ def log_level(self, message, level=level, **kwargs):
+ self.logger.emit(level, message, **kwargs)
+ setattr(LoggingMixIn, "log_%s" % (level,), log_level)
+
+del level, log_level
+
+# Add some compatibility with twisted's log module
+Logger.msg = Logger.info
+Logger.err = Logger.error
Added: CalendarServer/branches/users/wsanchez/logging/twistedcaldav/test/test_log.py
===================================================================
--- CalendarServer/branches/users/wsanchez/logging/twistedcaldav/test/test_log.py (rev 0)
+++ CalendarServer/branches/users/wsanchez/logging/twistedcaldav/test/test_log.py 2008-04-16 19:19:33 UTC (rev 2319)
@@ -0,0 +1,75 @@
+##
+# Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from twistedcaldav.log import Logger, LoggingMixIn, logLevels
+
+import twisted.trial.unittest
+
+class TestLogger (Logger):
+ def __init__(self, namespace=None, test_emit=None):
+ super(TestLogger, self).__init__(namespace)
+ self._test_emit = test_emit
+
+ def emit(self, level, message, **kwargs):
+ if self._test_emit is not None:
+ self._test_emit(level, message, **kwargs)
+ super(TestLogger, self).emit(level, message, **kwargs)
+
+class LoggingEnabledObject (LoggingMixIn):
+ pass
+
+class Logging (twisted.trial.unittest.TestCase):
+ def test_namespace_default(self):
+ """
+ Default namespace is module name.
+ """
+ log = Logger()
+ self.assertEquals(log.namespace, __name__)
+
+ def test_namespace_mixin(self):
+ """
+ Default namespace for classes using L{LoggingMixIn} is the class name.
+ """
+ object = LoggingEnabledObject()
+ self.assertEquals(object.logger.namespace, "twistedcaldav.test.test_log.LoggingEnabledObject")
+
+ def test_basic(self):
+ """
+ Test that log levels and messages are emitted correctly.
+ Tests both Logger and LoggingMixIn.
+ """
+ object = LoggingEnabledObject()
+
+ for level in logLevels:
+ message = "This is a %s message" % (level,)
+
+ def test_emit(emit_level, emit_message, **kwargs):
+ emitted["level" ] = emit_level
+ emitted["message"] = emit_message
+ emitted["junk" ] = kwargs["junk"]
+
+ log = TestLogger(test_emit=test_emit)
+ object.logger = log
+
+ for method in (getattr(log, level), getattr(object, "log_" + level)):
+ emitted = {}
+
+ method(message, junk=message)
+
+ # Ensure that test_emit got called with expected arguments
+ self.failUnless(emitted["level" ] == level )
+ self.failUnless(emitted["message"] == message)
+ self.failUnless(emitted["junk" ] == message)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080416/329a6b1e/attachment.html
More information about the calendarserver-changes
mailing list