Browse Source

Merge #393

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac327@3602 e5f2f494-b856-4b98-b285-d166d9295462
Michal Vaner 14 years ago
parent
commit
bf4ed5396e

+ 5 - 0
ChangeLog

@@ -1,4 +1,9 @@
   TBD.  [func]      vorner
+	New temporary logging function available in isc::log. It is used by
+	b10-recurse.
+	(Trac #393, r3602)
+
+  TBD.  [func]      vorner
 	The b10-recursive is configured through config manager.
 	It has "listen_on" and "forward_addresses" options.
 	(Trac #389, r3448)

+ 1 - 0
configure.ac

@@ -519,6 +519,7 @@ AC_CONFIG_FILES([Makefile
                  src/lib/datasrc/Makefile
                  src/lib/datasrc/tests/Makefile
                  src/lib/xfr/Makefile
+                 src/lib/log/Makefile
                  src/lib/testutils/Makefile
                  src/lib/testutils/testdata/Makefile
                ])

+ 1 - 1
doc/Doxyfile

@@ -568,7 +568,7 @@ WARN_LOGFILE           =
 # directories like "/usr/src/myproject". Separate the files or directories
 # with spaces.
 
-INPUT                  = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/lib/bench ../src/lib/asiolink/
+INPUT                  = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/lib/bench ../src/lib/log ../src/lib/asiolink/
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is

+ 22 - 14
src/bin/recurse/main.cc

@@ -22,7 +22,7 @@
 #include <stdlib.h>
 #include <errno.h>
 
-#include <cassert>
+#include <string>
 #include <iostream>
 
 #include <boost/foreach.hpp>
@@ -47,18 +47,17 @@
 #include <recurse/spec_config.h>
 #include <recurse/recursor.h>
 
+#include <log/dummylog.h>
+
 using namespace std;
-using namespace isc::data;
 using namespace isc::cc;
 using namespace isc::config;
-using namespace isc::dns;
-using namespace isc::xfr;
+using namespace isc::data;
+using isc::log::dlog;
 using namespace asiolink;
 
 namespace {
 
-static bool verbose_mode = false;
-
 // Default port current 5300 for testing purposes
 static const string PROGRAM = "Recurse";
 
@@ -96,6 +95,7 @@ usage() {
 
 int
 main(int argc, char* argv[]) {
+    isc::log::dprefix = "b10-recurse";
     int ch;
     const char* uid = NULL;
 
@@ -105,7 +105,7 @@ main(int argc, char* argv[]) {
             uid = optarg;
             break;
         case 'v':
-            verbose_mode = true;
+            isc::log::denabled = true;
             break;
         case '?':
         default:
@@ -117,6 +117,14 @@ main(int argc, char* argv[]) {
         usage();
     }
 
+    if (isc::log::denabled) { // Show the command line
+        string cmdline("Command line:");
+        for (int i = 0; i < argc; ++ i) {
+            cmdline = cmdline + " " + argv[i];
+        }
+        dlog(cmdline);
+    }
+
     int ret = 0;
 
     Session* cc_session = NULL;
@@ -131,8 +139,7 @@ main(int argc, char* argv[]) {
         }
 
         recursor = new Recursor();
-        recursor->setVerbose(verbose_mode);
-        cout << "[b10-recurse] Server created." << endl;
+        dlog("Server created.");
 
         SimpleCallback* checkin = recursor->getCheckinProvider();
         DNSLookup* lookup = recursor->getDNSLookupProvider();
@@ -141,15 +148,15 @@ main(int argc, char* argv[]) {
         DNSService dns_service(io_service, checkin, lookup, answer);
 
         recursor->setDNSService(dns_service);
-        cout << "[b10-recurse] IOService created." << endl;
+        dlog("IOService created.");
 
         cc_session = new Session(io_service.get_io_service());
-        cout << "[b10-recurse] Configuration session channel created." << endl;
+        dlog("Configuration session channel created.");
 
         config_session = new ModuleCCSession(specfile, *cc_session,
                                              my_config_handler,
                                              my_command_handler);
-        cout << "[b10-recurse] Configuration channel established." << endl;
+        dlog("Configuration channel established.");
 
         // FIXME: This does not belong here, but inside Boss
         if (uid != NULL) {
@@ -158,11 +165,12 @@ main(int argc, char* argv[]) {
 
         recursor->setConfigSession(config_session);
         recursor->updateConfig(config_session->getFullConfig());
+        dlog("Config loaded");
 
-        cout << "[b10-recurse] Server started." << endl;
+        dlog("Server started.");
         io_service.run();
     } catch (const std::exception& ex) {
-        cerr << "[b10-recurse] Server failed: " << ex.what() << endl;
+        dlog(string("Server failed: ") + ex.what());
         ret = 1;
     }
 

+ 55 - 77
src/bin/recurse/recursor.cc

@@ -19,19 +19,16 @@
 #include <netinet/in.h>
 
 #include <algorithm>
-#include <cassert>
-#include <iostream>
 #include <vector>
 
 #include <asiolink/asiolink.h>
 #include <asiolink/ioaddress.h>
 
 #include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
 
 #include <config/ccsession.h>
 
-#include <cc/data.h>
-
 #include <exceptions/exceptions.h>
 
 #include <dns/opcode.h>
@@ -45,19 +42,17 @@
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
 
-#include <xfr/xfrout_client.h>
+#include <log/dummylog.h>
 
 #include <recurse/recursor.h>
 
 using namespace std;
 
 using namespace isc;
-using namespace isc::cc;
 using namespace isc::dns;
-using namespace isc::dns::rdata;
 using namespace isc::data;
 using namespace isc::config;
-using namespace isc::xfr;
+using isc::log::dlog;
 using namespace asiolink;
 
 typedef pair<string, uint16_t> addr_t;
@@ -70,7 +65,6 @@ private:
 public:
     RecursorImpl() :
         config_session_(NULL),
-        verbose_mode_(false),
         rec_query_()
     {}
 
@@ -79,10 +73,12 @@ public:
     }
 
     void querySetup(DNSService& dnss) {
+        dlog("Query setup");
         rec_query_ = new RecursiveQuery(dnss, upstream_);
     }
 
     void queryShutdown() {
+        dlog("Query shutdown");
         delete rec_query_;
         rec_query_ = NULL;
     }
@@ -94,9 +90,14 @@ public:
         upstream_ = upstream;
         if (dnss) {
             if (upstream_.empty()) {
-                cerr << "[b10-recurse] Asked to do full recursive," << endl <<
-                    "but not implemented yet. I'll do nothing." << endl;
+                dlog("Asked to do full recursive, but not implemented yet. "
+                    "I'll do nothing.");
             } else {
+                dlog("Setting forward addresses:");
+                BOOST_FOREACH(const addr_t& address, upstream) {
+                    dlog(" " + address.first + ":" +
+                        boost::lexical_cast<string>(address.second));
+                }
                 querySetup(*dnss);
             }
         }
@@ -111,7 +112,6 @@ public:
 
     /// These members are public because Recursor accesses them directly.
     ModuleCCSession* config_session_;
-    bool verbose_mode_;
     /// Addresses of the forward nameserver
     vector<addr_t> upstream_;
     /// Addresses we listen on
@@ -127,6 +127,8 @@ class QuestionInserter {
 public:
     QuestionInserter(MessagePtr message) : message_(message) {}
     void operator()(const QuestionPtr question) {
+        dlog(string("Adding question ") + question->getName().toText() +
+            " to message");
         message_->addQuestion(question);
     }
     MessagePtr message_;
@@ -139,6 +141,8 @@ public:
         message_(message), section_(sect), sign_(sign)
     {}
     void operator()(const RRsetPtr rrset) {
+        dlog("Adding RRSet to message section " +
+            boost::lexical_cast<string>(section_));
         message_->addRRset(section_, rrset, true);
     }
     MessagePtr message_;
@@ -148,7 +152,7 @@ public:
 
 void
 makeErrorMessage(MessagePtr message, OutputBufferPtr buffer,
-                 const Rcode& rcode, const bool verbose_mode)
+                 const Rcode& rcode)
 {
     // extract the parameters that should be kept.
     // XXX: with the current implementation, it's not easy to set EDNS0
@@ -180,10 +184,9 @@ makeErrorMessage(MessagePtr message, OutputBufferPtr buffer,
     MessageRenderer renderer(*buffer);
     message->toWire(renderer);
 
-    if (verbose_mode) {
-        cerr << "[b10-recurse] sending an error response (" <<
-            renderer.getLength() << " bytes):\n" << message->toText() << endl;
-    }
+    dlog(string("Sending an error response (") +
+        boost::lexical_cast<string>(renderer.getLength()) + " bytes):\n" +
+        message->toText());
 }
 
 // This is a derived class of \c DNSLookup, to serve as a
@@ -281,11 +284,9 @@ public:
 
         message->toWire(renderer);
 
-        if (server_->getVerbose()) {
-            cerr << "[b10-recurse] sending a response ("
-                 << renderer.getLength() << " bytes):\n"
-                 << message->toText() << endl;
-        }
+        dlog(string("sending a response (") +
+            boost::lexical_cast<string>(renderer.getLength()) + "bytes): \n" +
+            message->toText());
     }
 
 private:
@@ -319,6 +320,7 @@ Recursor::~Recursor() {
     delete checkin_;
     delete dns_lookup_;
     delete dns_answer_;
+    dlog("Deleting the Recursor");
 }
 
 void
@@ -329,16 +331,6 @@ Recursor::setDNSService(asiolink::DNSService& dnss) {
 }
 
 void
-Recursor::setVerbose(const bool on) {
-    impl_->verbose_mode_ = on;
-}
-
-bool
-Recursor::getVerbose() const {
-    return (impl_->verbose_mode_);
-}
-
-void
 Recursor::setConfigSession(ModuleCCSession* config_session) {
     impl_->config_session_ = config_session;
 }
@@ -352,6 +344,7 @@ void
 Recursor::processMessage(const IOMessage& io_message, MessagePtr message,
                         OutputBufferPtr buffer, DNSServer* server)
 {
+    dlog("Got a DNS message");
     InputBuffer request_buffer(io_message.getData(), io_message.getDataSize());
     // First, check the header part.  If we fail even for the base header,
     // just drop the message.
@@ -360,17 +353,12 @@ Recursor::processMessage(const IOMessage& io_message, MessagePtr message,
 
         // Ignore all responses.
         if (message->getHeaderFlag(Message::HEADERFLAG_QR)) {
-            if (impl_->verbose_mode_) {
-                cerr << "[b10-recurse] received unexpected response, ignoring"
-                     << endl;
-            }
+            dlog("Received unexpected response, ignoring");
             server->resume(false);
             return;
         }
     } catch (const Exception& ex) {
-        if (impl_->verbose_mode_) {
-            cerr << "[b10-recurse] DNS packet exception: " << ex.what() << endl;
-        }
+        dlog(string("DNS packet exception: ") + ex.what());
         server->resume(false);
         return;
     }
@@ -379,57 +367,45 @@ Recursor::processMessage(const IOMessage& io_message, MessagePtr message,
     try {
         message->fromWire(request_buffer);
     } catch (const DNSProtocolError& error) {
-        if (impl_->verbose_mode_) {
-            cerr << "[b10-recurse] returning " <<  error.getRcode().toText()
-                 << ": " << error.what() << endl;
-        }
-        makeErrorMessage(message, buffer, error.getRcode(),
-                         impl_->verbose_mode_);
+        dlog(string("returning ") + error.getRcode().toText() + ": " + 
+            error.what());
+        makeErrorMessage(message, buffer, error.getRcode());
         server->resume(true);
         return;
     } catch (const Exception& ex) {
-        if (impl_->verbose_mode_) {
-            cerr << "[b10-recurse] returning SERVFAIL: " << ex.what() << endl;
-        }
-        makeErrorMessage(message, buffer, Rcode::SERVFAIL(),
-                         impl_->verbose_mode_);
+        dlog(string("returning SERVFAIL: ") + ex.what());
+        makeErrorMessage(message, buffer, Rcode::SERVFAIL());
         server->resume(true);
         return;
     } // other exceptions will be handled at a higher layer.
 
-    if (impl_->verbose_mode_) {
-        cerr << "[b10-recurse] received a message:\n"
-             << message->toText() << endl;
-    }
+    dlog("received a message:\n" + message->toText());
 
     // Perform further protocol-level validation.
     bool sendAnswer = true;
     if (message->getOpcode() == Opcode::NOTIFY()) {
-        makeErrorMessage(message, buffer, Rcode::NOTAUTH(),
-                         impl_->verbose_mode_);
+        makeErrorMessage(message, buffer, Rcode::NOTAUTH());
+        dlog("Notify arrived, but we are not authoritative");
     } else if (message->getOpcode() != Opcode::QUERY()) {
-        if (impl_->verbose_mode_) {
-            cerr << "[b10-recurse] unsupported opcode" << endl;
-        }
-        makeErrorMessage(message, buffer, Rcode::NOTIMP(),
-                         impl_->verbose_mode_);
+        dlog("Unsupported opcode (got: " + message->getOpcode().toText() +
+            ", expected: " + Opcode::QUERY().toText());
+        makeErrorMessage(message, buffer, Rcode::NOTIMP());
     } else if (message->getRRCount(Message::SECTION_QUESTION) != 1) {
-        makeErrorMessage(message, buffer, Rcode::FORMERR(),
-                         impl_->verbose_mode_);
+        dlog("The query contained " +
+            boost::lexical_cast<string>(message->getRRCount(
+            Message::SECTION_QUESTION) + " questions, exactly one expected"));
+        makeErrorMessage(message, buffer, Rcode::FORMERR());
     } else {
         ConstQuestionPtr question = *message->beginQuestion();
         const RRType &qtype = question->getType();
         if (qtype == RRType::AXFR()) {
             if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
-                makeErrorMessage(message, buffer, Rcode::FORMERR(),
-                                 impl_->verbose_mode_);
+                makeErrorMessage(message, buffer, Rcode::FORMERR());
             } else {
-                makeErrorMessage(message, buffer, Rcode::NOTIMP(),
-                                 impl_->verbose_mode_);
+                makeErrorMessage(message, buffer, Rcode::NOTIMP());
             }
         } else if (qtype == RRType::IXFR()) {
-            makeErrorMessage(message, buffer, Rcode::NOTIMP(),
-                         impl_->verbose_mode_);
+            makeErrorMessage(message, buffer, Rcode::NOTIMP());
         } else {
             // The RecursiveQuery object will post the "resume" event to the
             // DNSServer when an answer arrives, so we don't have to do it now.
@@ -447,6 +423,7 @@ void
 RecursorImpl::processNormalQuery(const Question& question, MessagePtr message,
                                  OutputBufferPtr buffer, DNSServer* server)
 {
+    dlog("Processing normal query");
     ConstEDNSPtr edns(message->getEDNS());
     const bool dnssec_ok = edns && edns->getDNSSECAwareness();
 
@@ -504,9 +481,8 @@ parseAddresses(ConstElementPtr addresses) {
 
 ConstElementPtr
 Recursor::updateConfig(ConstElementPtr config) {
-    if (impl_->verbose_mode_) {
-        cout << "[b10-recurse] Update with config: " << config->str() << endl;
-    }
+    dlog("New config comes: " + config->toWire());
+
     try {
         // Parse forward_addresses
         ConstElementPtr forwardAddressesE(config->get("forward_addresses"));
@@ -523,9 +499,7 @@ Recursor::updateConfig(ConstElementPtr config) {
         }
         return (isc::config::createAnswer());
     } catch (const isc::Exception& error) {
-        if (impl_->verbose_mode_) {
-            cerr << "[b10-recurse] error: " << error.what() << endl;
-        }
+        dlog(string("error in config: ") + error.what());
         return (isc::config::createAnswer(1, error.what()));
     }
 }
@@ -561,6 +535,10 @@ setAddresses(DNSService *service, const vector<addr_t>& addresses) {
 void
 Recursor::setListenAddresses(const vector<addr_t>& addresses) {
     try {
+        dlog("Setting listen addresses:");
+        BOOST_FOREACH(const addr_t& addr, addresses) {
+            dlog(" " + addr.first + boost::lexical_cast<string>(addr.second));
+        }
         setAddresses(dnss_, addresses);
         impl_->listen_ = addresses;
     }
@@ -576,8 +554,8 @@ Recursor::setListenAddresses(const vector<addr_t>& addresses) {
             setAddresses(dnss_, impl_->listen_);
         }
         catch (const exception& e2) {
-            cerr << "[b10-recurse] Unable to recover from error: " << e.what()
-                << endl << "Rollback failed with: " << e2.what() << endl;
+            dlog(string("Unable to recover from error: ") + e.what() +
+                " Rollback failed with: " + e2.what());
             abort();
         }
         throw e; // Let it fly a little bit further

+ 0 - 8
src/bin/recurse/recursor.h

@@ -60,14 +60,6 @@ public:
                         isc::dns::OutputBufferPtr buffer,
                         asiolink::DNSServer* server);
 
-    /// \brief Set verbose flag
-    ///
-    /// \param on The new value of the verbose flag
-    void setVerbose(bool on);
-
-    /// \brief Get the current value of the verbose flag
-    bool getVerbose() const;
-
     /// \brief Set and get the config session
     isc::config::ModuleCCSession* getConfigSession() const;
     void setConfigSession(isc::config::ModuleCCSession* config_session);

+ 0 - 5
src/bin/recurse/tests/recursor_unittest.cc

@@ -39,11 +39,6 @@ TEST_F(RecursorTest, unsupportedRequest) {
     UNSUPPORTED_REQUEST_TEST;
 }
 
-// Simple API check
-TEST_F(RecursorTest, verbose) {
-    VERBOSE_TEST;
-}
-
 // Multiple questions.  Should result in FORMERR.
 TEST_F(RecursorTest, multiQuestion) {
     MULTI_QUESTION_TEST; 

+ 2 - 1
src/lib/Makefile.am

@@ -1 +1,2 @@
-SUBDIRS = exceptions dns asiolink cc config datasrc python xfr bench testutils
+SUBDIRS = exceptions dns cc config datasrc python xfr bench log asiolink \
+    testutils

+ 1 - 0
src/lib/asiolink/Makefile.am

@@ -31,3 +31,4 @@ if USE_CLANGPP
 libasiolink_la_CXXFLAGS += -Wno-error
 endif
 libasiolink_la_CPPFLAGS = $(AM_CPPFLAGS)
+libasiolink_la_LIBADD = $(top_builddir)/src/lib/log/liblog.la

+ 6 - 2
src/lib/asiolink/asiolink.cc

@@ -36,12 +36,15 @@
 #include <asiolink/internal/tcpdns.h>
 #include <asiolink/internal/udpdns.h>
 
+#include <log/dummylog.h>
+
 using namespace asio;
 using asio::ip::udp;
 using asio::ip::tcp;
 
 using namespace std;
 using namespace isc::dns;
+using isc::log::dlog;
 
 namespace asiolink {
 
@@ -273,14 +276,15 @@ void
 RecursiveQuery::sendQuery(const Question& question, OutputBufferPtr buffer,
                           DNSServer* server)
 {
-
+    int serverIndex(random() % upstream_.size());
+    dlog("Sending upstream query (" + question.toText() + ") to " +
+        upstream_[serverIndex].first);
     // XXX: eventually we will need to be able to determine whether
     // the message should be sent via TCP or UDP, or sent initially via
     // UDP and then fall back to TCP on failure, but for the moment
     // we're only going to handle UDP.
     asio::io_service& io = dns_service_.get_io_service();
     // TODO: Better way to choose the server
-    int serverIndex(random() % upstream_.size());
     UDPQuery q(io, question, upstream_[serverIndex].first,
         upstream_[serverIndex].second, buffer, server);
     io.post(q);

+ 1 - 0
src/lib/asiolink/tests/Makefile.am

@@ -25,6 +25,7 @@ run_unittests_LDADD += $(SQLITE_LIBS)
 run_unittests_LDADD +=  $(top_builddir)/src/lib/dns/libdns++.la
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 run_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
+run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
 # Note: the ordering matters: -Wno-... must follow -Wextra (defined in
 # B10_CXXFLAGS)
 run_unittests_CXXFLAGS = $(AM_CXXFLAGS)

+ 6 - 0
src/lib/asiolink/udpdns.cc

@@ -29,6 +29,7 @@
 #include <dns/buffer.h>
 #include <dns/message.h>
 #include <dns/messagerenderer.h>
+#include <log/dummylog.h>
 #include <dns/opcode.h>
 #include <dns/rcode.h>
 
@@ -39,6 +40,7 @@
 using namespace asio;
 using asio::ip::udp;
 using asio::ip::tcp;
+using isc::log::dlog;
 
 using namespace std;
 using namespace isc::dns;
@@ -208,6 +210,8 @@ UDPQuery::operator()(error_code ec, size_t length) {
             msg.addQuestion(question_);
             MessageRenderer renderer(*msgbuf_);
             msg.toWire(renderer);
+            dlog("Sending " + msg.toText() + " to " +
+                remote_.address().to_string());
         }
 
         // Begin an asynchronous send, and then yield.  When the
@@ -224,6 +228,8 @@ UDPQuery::operator()(error_code ec, size_t length) {
         /// completes, we will resume immediately after this point.
         CORO_YIELD socket_->async_receive_from(buffer(data_.get(), MAX_LENGTH),
                                                remote_, *this);
+        // The message is not rendered yet, so we can't print it easilly
+        dlog("Received response from " + remote_.address().to_string());
 
         /// Copy the answer into the response buffer.  (XXX: If the
         /// OutputBuffer object were made to meet the requirements of

+ 4 - 0
src/lib/log/Makefile.am

@@ -0,0 +1,4 @@
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+lib_LTLIBRARIES = liblog.la
+liblog_la_SOURCES = dummylog.cc dummylog.h

+ 37 - 0
src/lib/log/dummylog.cc

@@ -0,0 +1,37 @@
+// Copyright (C) 2010  CZ NIC
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include "dummylog.h"
+
+#include <iostream>
+
+using namespace std;
+
+namespace isc {
+namespace log {
+
+bool denabled = false;
+string dprefix;
+
+void dlog(const string& message) {
+    if (denabled) {
+        if (!dprefix.empty()) {
+            cerr << "[" << dprefix << "] ";
+        }
+        cerr << message << endl;
+    }
+}
+
+}
+}

+ 60 - 0
src/lib/log/dummylog.h

@@ -0,0 +1,60 @@
+// Copyright (C) 2010  CZ NIC
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef _ISC_DUMMYLOG_H
+#define _ISC_DUMMYLOG_H 1
+
+#include <string>
+
+namespace isc {
+namespace log {
+
+/// Are we doing logging?
+extern bool denabled;
+/**
+ * \short Prefix into logs.
+ *
+ * The prefix is printed in front of every log message in square brackets.
+ * The usual convention is to put the name of program here.
+ */
+extern std::string dprefix;
+
+/**
+ * \short Temporary interface to logging.
+ *
+ * This is a temporary function to do logging. It has wrong interface currently
+ * and should be replaced by something else. It's main purpose now is to mark
+ * places where logging should happen. When it is removed, compiler will do
+ * our work of finding the places.
+ *
+ * The only thing it does is printing the dprogram prefix, message and
+ * a newline if denabled is true.
+ *
+ * There are no tests for this function, since it is only temporary and
+ * trivial. Tests will be written for the real logging framework when it is
+ * created.
+ *
+ * It has the d in front of the name so it is unlikely anyone will create
+ * a real logging function with the same name and the place wouldn't be found
+ * as a compilation error.
+ *
+ * @param message The message to log. The real interface will probably have
+ *     more parameters.
+ */
+void dlog(const std::string& message);
+
+}
+}
+
+#endif // _ISC_DUMMYLOG_H