Enabling logging interface (optionally with log4cxx)
diff --git a/src/logging.cc b/src/logging.cc
new file mode 100644
index 0000000..28d965b
--- /dev/null
+++ b/src/logging.cc
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Chaoyi Bian <bcy@pku.edu.cn>
+ *	   Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "logging.h"
+
+#ifdef HAVE_LOG4CXX
+
+#include <log4cxx/logger.h>
+#include <log4cxx/basicconfigurator.h>
+#include <log4cxx/consoleappender.h>
+#include <log4cxx/patternlayout.h>
+#include <log4cxx/level.h>
+#include <log4cxx/propertyconfigurator.h>
+#include <log4cxx/defaultconfigurator.h>
+#include <log4cxx/helpers/exception.h>
+using namespace log4cxx;
+using namespace log4cxx::helpers;
+
+#include <unistd.h>
+
+void
+INIT_LOGGERS ()
+{
+  static bool configured = false;
+
+  if (configured) return;
+
+  if (access ("log4cxx.properties", R_OK)==0)
+    PropertyConfigurator::configureAndWatch ("log4cxx.properties");
+  else
+    {
+      PatternLayoutPtr   layout   (new PatternLayout ("%d{HH:mm:ss} %p %c{1} - %m%n"));
+      ConsoleAppenderPtr appender (new ConsoleAppender (layout));
+
+      BasicConfigurator::configure( appender );
+      Logger::getRootLogger()->setLevel (log4cxx::Level::getInfo ());
+    }
+
+  configured = true;
+}
+
+#endif
diff --git a/src/logging.h b/src/logging.h
new file mode 100644
index 0000000..15784ff
--- /dev/null
+++ b/src/logging.h
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ *	   Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ */
+
+#ifndef LOGGING_H
+#define LOGGING_H
+
+#include "config.h"
+
+#ifdef HAVE_LOG4CXX
+
+#include <log4cxx/logger.h>
+
+#define INIT_LOGGER(name) \
+  static log4cxx::LoggerPtr staticModuleLogger = log4cxx::Logger::getLogger (name);
+
+#define _LOG_DEBUG(x) \
+  LOG4CXX_DEBUG(staticModuleLogger, x);
+
+#define _LOG_TRACE(x) \
+  LOG4CXX_TRACE(staticModuleLogger, x);
+
+#define _LOG_FUNCTION(x) \
+  LOG4CXX_TRACE(staticModuleLogger, __FUNCTION__ << "(" << x << ")");
+
+#define _LOG_FUNCTION_NOARGS \
+  LOG4CXX_TRACE(staticModuleLogger, __FUNCTION__ << "()");
+
+#define _LOG_ERROR(x) \
+  LOG4CXX_ERROR(staticModuleLogger, x);
+
+void
+INIT_LOGGERS ();
+
+#else
+
+#define INIT_LOGGER(name)
+#define _LOG_FUNCTION(x)
+#define _LOG_FUNCTION_NOARGS
+#define _LOG_TRACE(x)
+#define INIT_LOGGERS(x)
+#define _LOG_ERROR(x)
+
+#ifdef _DEBUG
+
+#include <boost/thread/thread.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <iostream>
+
+#define _LOG_DEBUG(x) \
+  std::clog << boost::get_system_time () << " " << boost::this_thread::get_id () << " " << x << endl;
+
+#else
+#define _LOG_DEBUG(x)
+#endif
+
+#endif // HAVE_LOG4CXX
+
+#endif // LOGGING_H
diff --git a/src/sync-core.cc b/src/sync-core.cc
index 9861c44..cae3d6b 100644
--- a/src/sync-core.cc
+++ b/src/sync-core.cc
@@ -20,19 +20,24 @@
  */
 
 #include "sync-core.h"
-
-#include "one-time-task.h"
+#include "logging.h"
 #include "random-interval-generator.h"
 
+#include <boost/lexical_cast.hpp>
+
+INIT_LOGGER ("Sync.Core");
+
 const string SyncCore::RECOVER = "RECOVER";
 const double SyncCore::WAIT = 0.05;
 const double SyncCore::RANDOM_PERCENT = 0.5;
 
+using namespace boost;
+
 // for debugging
 static void
 printMsg(SyncStateMsgPtr &msg)
 {
-  cerr << " ===== start Msg ======" << endl;
+  _LOG_TRACE (" ===== start Msg ======");
   int size = msg->state_size();
   if (size > 0)
   {
@@ -43,17 +48,17 @@
       string strName = state.name();
       string strLocator = state.locator();
       sqlite3_int64 seq = state.seq();
-      cerr << "Name: " << Name((const unsigned char *)strName.c_str(), strName.size());
-      cerr << ", Locator: " << Name((const unsigned char *)strLocator.c_str(), strLocator.size());
-      cerr << ", seq: " << seq << endl;
+      _LOG_TRACE ("Name: " << Name((const unsigned char *)strName.c_str(), strName.size())
+                  <<", Locator: " << Name((const unsigned char *)strLocator.c_str(), strLocator.size())
+                  << ", seq: " << seq);
       index ++;
     }
   }
   else
   {
-    cerr << "Msg size 0" << endl;
+    _LOG_TRACE ("Msg size 0");
   }
-  cerr << " ++++++++ end Msg  ++++++++ \n\n" << endl;
+  _LOG_TRACE (" ++++++++ end Msg  ++++++++ ");
 }
 
 SyncCore::SyncCore(SyncLogPtr syncLog, const Name &userName, const Name &localPrefix, const Name &syncPrefix, const StateMsgCallback &callback, const CcnxWrapperPtr &handle, const SchedulerPtr &scheduler)
@@ -128,15 +133,15 @@
   Bytes syncData;
   msgToBytes(msg, syncData);
   m_handle->publishData(syncName, syncData, FRESHNESS);
-  cerr << m_log->GetLocalName () << " publishes: " << *oldHash << endl;
+  _LOG_DEBUG (m_log->GetLocalName () << " publishes: " << *oldHash);
   printMsg(msg);
 
   // no hurry in sending out new Sync Interest; if others send the new Sync Interest first, no problem, we know the new root hash already;
   // this is trying to avoid the situation that the order of SyncData and new Sync Interest gets reversed at receivers
-  ostringstream ss;
-  ss << *m_rootHash;
-  TaskPtr task(new OneTimeTask(boost::bind(&SyncCore::sendSyncInterest, this), ss.str(), m_scheduler, 0.1));
-  m_scheduler->addTask(task);
+  Scheduler::scheduleOneTimeTask (m_scheduler, 0.1,
+                                  bind(&SyncCore::sendSyncInterest, this),
+                                  lexical_cast<string> (*m_rootHash));
+
   sendSyncInterest();
 }
 
@@ -194,7 +199,7 @@
     Bytes syncData;
     msgToBytes(msg, syncData);
     m_handle->publishData(name, syncData, FRESHNESS);
-    cerr << m_log->GetLocalName () << " publishes " << hash << endl;
+    _LOG_DEBUG (m_log->GetLocalName () << " publishes " << hash);
     printMsg(msg);
   }
   else
@@ -211,32 +216,31 @@
   if (*hash == *m_rootHash)
   {
     // we have the same hash; nothing needs to be done
-    cerr << "same as root hash: " << *hash << endl;
+    _LOG_DEBUG ("same as root hash: " << *hash);
     return;
   }
   else if (m_log->LookupSyncLog(*hash) > 0)
   {
     // we know something more
-    cerr << "found hash in sync log" << endl;
+    _LOG_DEBUG ("found hash in sync log");
     SyncStateMsgPtr msg = m_log->FindStateDifferences(*hash, *m_rootHash);
 
     Bytes syncData;
     msgToBytes(msg, syncData);
     m_handle->publishData(name, syncData, FRESHNESS);
-    cerr << m_log->GetLocalName () << " publishes: " << *hash << endl;
+    _LOG_DEBUG (m_log->GetLocalName () << " publishes: " << *hash);
     printMsg(msg);
   }
   else
   {
     // we don't recognize the hash, send recover Interest if still don't know the hash after a randomized wait period
-    ostringstream ss;
-    ss << "r-" << *hash;
     double wait = m_recoverWaitGenerator->nextInterval();
-    cerr << m_log->GetLocalName () << ", rootHash: " << *m_rootHash << ", hash: " << *hash << endl;
-    cerr << "recover task scheduled after wait: " << wait << endl;
-    TaskPtr task(new OneTimeTask(boost::bind(&SyncCore::recover, this, hash), ss.str(), m_scheduler, wait));
-    m_scheduler->addTask(task);
+    _LOG_DEBUG (m_log->GetLocalName () << ", rootHash: " << *m_rootHash << ", hash: " << *hash);
+    _LOG_DEBUG ("recover task scheduled after wait: " << wait);
 
+    Scheduler::scheduleOneTimeTask (m_scheduler,
+                                    wait, boost::bind(&SyncCore::recover, this, hash),
+                                    "r-"+lexical_cast<string> (*hash));
   }
 }
 
@@ -261,7 +265,7 @@
 void
 SyncCore::handleRecoverData(const Name &name, PcoPtr content)
 {
-  //cout << "handle recover data" << endl;
+  //cout << "handle recover data" << end;
   handleStateData(*content->contentPtr ());
   sendSyncInterest();
 }
@@ -284,11 +288,11 @@
   if(!success)
   {
     // ignore misformed SyncData
-    cerr << "Misformed SyncData"<< endl;
+    _LOG_ERROR ("Misformed SyncData");
     return;
   }
 
-  cerr << m_log->GetLocalName () << " receives Msg " << endl;
+  _LOG_DEBUG (m_log->GetLocalName () << " receives Msg ");
   printMsg (msg);
   int size = msg->state_size();
   int index = 0;
@@ -311,12 +315,12 @@
         m_log->UpdateLocator(deviceName, locatorName);
         // WriteLock lock(m_ypMutex);
         // m_yp[deviceName] = locatorName;
-        cerr << "self: " << m_log->GetLocalName () << ", device: " << deviceName << " < == > " << locatorName << endl;
+        _LOG_DEBUG ("self: " << m_log->GetLocalName () << ", device: " << deviceName << " < == > " << locatorName);
       }
     }
     else
     {
-      cerr << "nani" << endl;
+      _LOG_TRACE ("nani");
       deregister(deviceName);
     }
     index++;
@@ -339,7 +343,7 @@
 {
   Name syncInterest = constructSyncName(m_rootHash);
   m_handle->sendInterest(syncInterest, m_syncClosure);
-  cerr << m_log->GetLocalName () << " send SYNC interest: " << *m_rootHash << endl;
+  _LOG_DEBUG (m_log->GetLocalName () << " send SYNC interest: " << *m_rootHash);
 }
 
 void
@@ -347,7 +351,7 @@
 {
   if (!(*hash == *m_rootHash) && m_log->LookupSyncLog(*hash) <= 0)
   {
-    cerr << m_log->GetLocalName () << ", Recover for: " << *hash << endl;
+    _LOG_DEBUG (m_log->GetLocalName () << ", Recover for: " << *hash);
     // unfortunately we still don't recognize this hash
     Bytes bytes;
     readRaw(bytes, (const unsigned char *)hash->GetHash(), hash->GetHashBytes());
@@ -356,7 +360,7 @@
     // append the unknown hash
     recoverInterest.appendComp(bytes);
     m_handle->sendInterest(recoverInterest, m_recoverClosure);
-    cerr << m_log->GetLocalName () << " send RECOVER Interest: " << *hash << endl;
+    _LOG_DEBUG (m_log->GetLocalName () << " send RECOVER Interest: " << *hash);
   }
   else
   {
diff --git a/src/sync-core.h b/src/sync-core.h
index f77b133..ef65d5d 100644
--- a/src/sync-core.h
+++ b/src/sync-core.h
@@ -96,7 +96,7 @@
   sqlite3_int64
   seq(const Name &name);
 
-protected:
+private:
   void
   sendSyncInterest();
 
@@ -115,7 +115,7 @@
   static void
   msgToBytes(const SyncStateMsgPtr &msg, Bytes &bytes);
 
-protected:
+private:
   SyncLogPtr m_log;
   SchedulerPtr m_scheduler;
   StateMsgCallback m_stateMsgCallback;
@@ -130,7 +130,6 @@
   Closure m_recoverClosure;
 
   IntervalGeneratorPtr m_recoverWaitGenerator;
-
 };
 
 #endif // SYNC_CORE_H