BIND 10 trac756, updated. 4fd41636ae9c11a96b3893cbc939fd4854b64b56 [trac756] is****Enabled methods
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Jun 8 14:43:55 UTC 2011
The branch, trac756 has been updated
via 4fd41636ae9c11a96b3893cbc939fd4854b64b56 (commit)
via a149f9e04c33ce6012a4a3e837c98db6d3074a44 (commit)
via 4e18854902a306ea6ad390eb90a9f43f49c8222b (commit)
from 88119987e9f33fa12243eacee75bd9ec4c99f936 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 4fd41636ae9c11a96b3893cbc939fd4854b64b56
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Jun 8 16:43:21 2011 +0200
[trac756] is****Enabled methods
commit a149f9e04c33ce6012a4a3e837c98db6d3074a44
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Jun 8 15:44:29 2011 +0200
[trac756] Severity manipulation
commit 4e18854902a306ea6ad390eb90a9f43f49c8222b
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Wed Jun 8 14:14:15 2011 +0200
[trac756] The Logger class wrapper
Only initialization and destruction for now, needs to add methods.
-----------------------------------------------------------------------
Summary of changes:
src/lib/python/isc/log/log.cc | 279 +++++++++++++++++++++++++++++-
src/lib/python/isc/log/tests/log_test.py | 58 ++++++
2 files changed, 329 insertions(+), 8 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/python/isc/log/log.cc b/src/lib/python/isc/log/log.cc
index 07a490e..006b3c5 100644
--- a/src/lib/python/isc/log/log.cc
+++ b/src/lib/python/isc/log/log.cc
@@ -20,12 +20,12 @@
#include <log/message_dictionary.h>
#include <log/logger_manager.h>
+#include <log/logger.h>
using namespace isc::log;
namespace {
-
// This is for testing only. The real module will have it always set as
// NULL and will use the global dictionary.
MessageDictionary* testDictionary = NULL;
@@ -44,9 +44,9 @@ setTestDictionary(PyObject*, PyObject* args) {
}
bool enable(enableI != 0);
- delete testDictionary;
- testDictionary = NULL;
try {
+ delete testDictionary;
+ testDictionary = NULL;
if (enable) {
testDictionary = new MessageDictionary;
}
@@ -161,21 +161,21 @@ init(PyObject*, PyObject* args) {
}
PyMethodDef methods[] = {
- {"set_test_dictionary", &setTestDictionary, METH_VARARGS,
+ {"set_test_dictionary", setTestDictionary, METH_VARARGS,
"Set or unset testing mode for message dictionary. In testing, "
"the create_message and get_message functions work on different "
"than the logger-global dictionary, not polluting it."},
- {"create_message", &createMessage, METH_VARARGS,
+ {"create_message", createMessage, METH_VARARGS,
"Creates a new message in the dictionary. You shouldn't need to "
"call this directly, it should be called by the generated message "
"file. Returns the identifier to be used in logging. The text "
"shouldn't be empty."},
- {"get_message", &getMessage, METH_VARARGS,
+ {"get_message", getMessage, METH_VARARGS,
"Get a message. This function is for testing purposes and you don't "
"need to call it. It returns None if the message does not exist."},
- {"reset", &reset, METH_VARARGS,
+ {"reset", reset, METH_NOARGS,
"Reset all logging. For testing purposes only, do not use."},
- {"init", &init, METH_VARARGS,
+ {"init", init, METH_VARARGS,
"Run-time initialization. You need to call this before you do any "
"logging, to configure the root logger name. You may also provide "
"a filename with message translations (or None if you don't want "
@@ -184,6 +184,258 @@ PyMethodDef methods[] = {
{NULL, NULL, 0, NULL}
};
+class LoggerWrapper : public PyObject {
+// Everything is public here, as it is accessible only inside this .cc file.
+public:
+ Logger *logger_;
+};
+
+extern PyTypeObject logger_type;
+
+int
+Logger_init(LoggerWrapper* self, PyObject* args) {
+ const char* name;
+ if (!PyArg_ParseTuple(args, "s", &name)) {
+ return (-1);
+ }
+ try {
+ self->logger_ = new Logger(name);
+ return (0);
+ }
+ catch (const std::exception& e) {
+ PyErr_SetString(PyExc_RuntimeError, e.what());
+ return (-1);
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
+ return (-1);
+ }
+}
+
+void
+Logger_destroy(LoggerWrapper* const self) {
+ delete self->logger_;
+ self->logger_ = NULL;
+ Py_TYPE(self)->tp_free(self);
+}
+
+// The isc::log doesn't contain function to convert this way
+const char*
+severityToText(const Severity& severity) {
+ switch (severity) {
+ case DEFAULT:
+ return ("DEFAULT");
+ case DEBUG:
+ return ("DEBUG");
+ case INFO:
+ return ("INFO");
+ case WARN:
+ return ("WARN");
+ case ERROR:
+ return ("ERROR");
+ case FATAL:
+ return ("FATAL");
+ default:
+ return (NULL);
+ }
+}
+
+PyObject*
+Logger_getEffectiveSeverity(LoggerWrapper* self, PyObject*) {
+ try {
+ return (Py_BuildValue("s",
+ severityToText(
+ self->logger_->getEffectiveSeverity())));
+ }
+ catch (const std::exception& e) {
+ PyErr_SetString(PyExc_RuntimeError, e.what());
+ return (NULL);
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
+ return (NULL);
+ }
+}
+
+PyObject*
+Logger_getDebugLevel(LoggerWrapper* self, PyObject*) {
+ try {
+ return (Py_BuildValue("i", self->logger_->getDebugLevel()));
+ }
+ catch (const std::exception& e) {
+ PyErr_SetString(PyExc_RuntimeError, e.what());
+ return (NULL);
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
+ return (NULL);
+ }
+}
+
+PyObject*
+Logger_setSeverity(LoggerWrapper* self, PyObject* args) {
+ const char* severity;
+ int dbgLevel = 0;
+ if (!PyArg_ParseTuple(args, "z|i", &severity, &dbgLevel)) {
+ return (NULL);
+ }
+ try {
+ self->logger_->setSeverity((severity == NULL) ? DEFAULT :
+ getSeverity(severity), dbgLevel);
+ }
+ catch (const std::exception& e) {
+ PyErr_SetString(PyExc_RuntimeError, e.what());
+ return (NULL);
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
+ return (NULL);
+ }
+ Py_RETURN_NONE;
+}
+
+template<class FPtr> // Who should remember the pointer-to-method syntax
+PyObject*
+Logger_isLevelEnabled(LoggerWrapper* self, FPtr function) {
+ try {
+ if ((self->logger_->*function)()) {
+ Py_RETURN_TRUE;
+ } else {
+ Py_RETURN_FALSE;
+ }
+ }
+ catch (const std::exception& e) {
+ PyErr_SetString(PyExc_RuntimeError, e.what());
+ return (NULL);
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
+ return (NULL);
+ }
+}
+
+PyObject*
+Logger_isInfoEnabled(LoggerWrapper* self, PyObject*) {
+ return (Logger_isLevelEnabled(self, &Logger::isInfoEnabled));
+}
+
+PyObject*
+Logger_isWarnEnabled(LoggerWrapper* self, PyObject*) {
+ return (Logger_isLevelEnabled(self, &Logger::isWarnEnabled));
+}
+
+PyObject*
+Logger_isErrorEnabled(LoggerWrapper* self, PyObject*) {
+ return (Logger_isLevelEnabled(self, &Logger::isErrorEnabled));
+}
+
+PyObject*
+Logger_isFatalEnabled(LoggerWrapper* self, PyObject*) {
+ return (Logger_isLevelEnabled(self, &Logger::isFatalEnabled));
+}
+
+PyObject*
+Logger_isDebugEnabled(LoggerWrapper* self, PyObject* args) {
+ int level = MIN_DEBUG_LEVEL;
+ if (!PyArg_ParseTuple(args, "|i", &level)) {
+ return (NULL);
+ }
+
+ try {
+ if (self->logger_->isDebugEnabled(level)) {
+ Py_RETURN_TRUE;
+ } else {
+ Py_RETURN_FALSE;
+ }
+ }
+ catch (const std::exception& e) {
+ PyErr_SetString(PyExc_RuntimeError, e.what());
+ return (NULL);
+ }
+ catch (...) {
+ PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
+ return (NULL);
+ }
+}
+
+PyMethodDef loggerMethods[] = {
+ { "get_effective_severity",
+ reinterpret_cast<PyCFunction>(Logger_getEffectiveSeverity),
+ METH_NOARGS, "Returns the effective logging severity as string" },
+ { "get_debug_level", reinterpret_cast<PyCFunction>(Logger_getDebugLevel),
+ METH_NOARGS, "Returns the current debug level." },
+ { "set_severity",
+ reinterpret_cast<PyCFunction>(Logger_setSeverity), METH_VARARGS,
+ "Sets the severity of a logger. The parameters are severity as a "
+ "string and, optionally, a debug level (integer in range 0-99). "
+ "The severity may be NULL, in which case an inherited value is taken."
+ },
+ { "is_debug_enabled", reinterpret_cast<PyCFunction>(Logger_isDebugEnabled),
+ METH_VARARGS, "Returns if the logger would log debug message now. "
+ "You can provide a desired debug level."
+ },
+ { "is_info_enabled", reinterpret_cast<PyCFunction>(Logger_isInfoEnabled),
+ METH_NOARGS, "Returns if the logger would log info message now." },
+ { "is_warn_enabled", reinterpret_cast<PyCFunction>(Logger_isWarnEnabled),
+ METH_NOARGS, "Returns if the logger would log warn message now." },
+ { "is_error_enabled", reinterpret_cast<PyCFunction>(Logger_isErrorEnabled),
+ METH_NOARGS, "Returns if the logger would log error message now." },
+ { "is_fatal_enabled", reinterpret_cast<PyCFunction>(Logger_isFatalEnabled),
+ METH_NOARGS, "Returns if the logger would log fatal message now." },
+ { NULL, NULL, 0, NULL }
+};
+
+PyTypeObject logger_type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "isc.log.Logger",
+ sizeof(LoggerWrapper), // tp_basicsize
+ 0, // tp_itemsize
+ reinterpret_cast<destructor>(Logger_destroy), // tp_dealloc
+ NULL, // tp_print
+ NULL, // tp_getattr
+ NULL, // tp_setattr
+ NULL, // tp_reserved
+ NULL, // tp_repr
+ NULL, // tp_as_number
+ NULL, // tp_as_sequence
+ NULL, // tp_as_mapping
+ NULL, // tp_hash
+ NULL, // tp_call
+ NULL, // tp_str
+ NULL, // tp_getattro
+ NULL, // tp_setattro
+ NULL, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ "Wrapper around the C++ isc::log::Logger class."
+ "It is not complete, but everything important should be here.",
+ NULL, // tp_traverse
+ NULL, // tp_clear
+ NULL, // tp_richcompare
+ 0, // tp_weaklistoffset
+ NULL, // tp_iter
+ NULL, // tp_iternext
+ loggerMethods, // tp_methods
+ NULL, // tp_members
+ NULL, // tp_getset
+ NULL, // tp_base
+ NULL, // tp_dict
+ NULL, // tp_descr_get
+ NULL, // tp_descr_set
+ 0, // tp_dictoffset
+ reinterpret_cast<initproc>(Logger_init), // tp_init
+ NULL, // tp_alloc
+ PyType_GenericNew, // tp_new
+ NULL, // tp_free
+ NULL, // tp_is_gc
+ NULL, // tp_bases
+ NULL, // tp_mro
+ NULL, // tp_cache
+ NULL, // tp_subclasses
+ NULL, // tp_weaklist
+ NULL, // tp_del
+ 0 // tp_version_tag
+};
+
PyModuleDef iscLog = {
{ PyObject_HEAD_INIT(NULL) NULL, 0, NULL},
"log",
@@ -207,5 +459,16 @@ PyInit_log(void) {
return (NULL);
}
+ if (PyType_Ready(&logger_type) < 0) {
+ return (NULL);
+ }
+
+ if (PyModule_AddObject(mod, "Logger",
+ static_cast<PyObject*>(static_cast<void*>(
+ &logger_type))) < 0) {
+ return (NULL);
+ }
+ Py_INCREF(&logger_type);
+
return (mod);
}
diff --git a/src/lib/python/isc/log/tests/log_test.py b/src/lib/python/isc/log/tests/log_test.py
index 2f4a6b9..c8a1ab1 100644
--- a/src/lib/python/isc/log/tests/log_test.py
+++ b/src/lib/python/isc/log/tests/log_test.py
@@ -52,5 +52,63 @@ class Manager(unittest.TestCase):
# ignore errors like missing file?
isc.log.init("root", "/no/such/file");
+class Logger(unittest.TestCase):
+ def tearDown(self):
+ isc.log.reset()
+
+ def setUp(self):
+ isc.log.init("root", None, "DEBUG", 50)
+ self.sevs = ['INFO', 'WARN', 'ERROR', 'FATAL']
+
+ # Checks defaults of the logger
+ def defaults(self, logger):
+ self.assertEqual(logger.get_effective_severity(), "DEBUG")
+ self.assertEqual(logger.get_debug_level(), 0)
+
+ # Because there's a bug in the C++ backend currently. When it's fixed,
+ # it should no longer fail
+ @unittest.expectedFailure
+ def test_default_severity(self):
+ logger = isc.log.Logger("child")
+ self.defaults(logger)
+
+ # Try changing the severities little bit
+ def test_severity(self):
+ logger = isc.log.Logger("child")
+ logger.set_severity('DEBUG', 25)
+ self.assertEqual(logger.get_effective_severity(), "DEBUG")
+ self.assertEqual(logger.get_debug_level(), 25)
+ for sev in self.sevs:
+ logger.set_severity(sev)
+ self.assertEqual(logger.get_effective_severity(), sev)
+ self.assertEqual(logger.get_debug_level(), 0)
+ # Return to default
+ logger.set_severity(None)
+ # The same bug here
+ #self.defaults(logger)
+
+ def test_enabled(self):
+ logger = isc.log.Logger("child")
+ self.sevs.insert(0, 'DEBUG')
+ methods = {
+ 'DEBUG': logger.is_debug_enabled,
+ 'INFO': logger.is_info_enabled,
+ 'WARN': logger.is_warn_enabled,
+ 'ERROR': logger.is_error_enabled,
+ 'FATAL': logger.is_fatal_enabled
+ }
+ for sev in self.sevs:
+ logger.set_severity(sev)
+ enabled = False
+ for tested in self.sevs:
+ if tested == sev:
+ enabled = True
+ self.assertEqual(methods[tested](), enabled)
+ logger.set_severity('DEBUG', 50)
+ self.assertTrue(logger.is_debug_enabled())
+ self.assertTrue(logger.is_debug_enabled(0))
+ self.assertTrue(logger.is_debug_enabled(50))
+ self.assertFalse(logger.is_debug_enabled(99))
+
if __name__ == '__main__':
unittest.main()
More information about the bind10-changes
mailing list