You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2011/06/05 10:48:05 UTC

svn commit: r1132128 - in /incubator/mesos/trunk: ./ src/ src/event_history/ src/examples/ src/local/ src/master/ src/messaging/ src/slave/ src/tests/ src/webui/master/

Author: benh
Date: Sun Jun  5 08:48:04 2011
New Revision: 1132128

URL: http://svn.apache.org/viewvc?rev=1132128&view=rev
Log:
The event history logging infrastructure (not including the webui improvements).

Added:
    incubator/mesos/trunk/src/event_history/
    incubator/mesos/trunk/src/event_history/event_history.cpp
    incubator/mesos/trunk/src/event_history/event_history.hpp
Modified:
    incubator/mesos/trunk/Makefile.in
    incubator/mesos/trunk/src/Makefile.in
    incubator/mesos/trunk/src/examples/Makefile.in
    incubator/mesos/trunk/src/local/local.cpp
    incubator/mesos/trunk/src/master/main.cpp
    incubator/mesos/trunk/src/master/master.cpp
    incubator/mesos/trunk/src/master/master.hpp
    incubator/mesos/trunk/src/master/state.hpp
    incubator/mesos/trunk/src/messaging/messages.hpp
    incubator/mesos/trunk/src/slave/slave.cpp
    incubator/mesos/trunk/src/slave/webui.cpp
    incubator/mesos/trunk/src/tests/Makefile.in
    incubator/mesos/trunk/src/tests/test_master.cpp
    incubator/mesos/trunk/src/webui/master/index.tpl

Modified: incubator/mesos/trunk/Makefile.in
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/Makefile.in?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/Makefile.in (original)
+++ incubator/mesos/trunk/Makefile.in Sun Jun  5 08:48:04 2011
@@ -18,7 +18,8 @@ LIBPROCESS = third_party/libprocess
 ZOOKEEPER = third_party/zookeeper-3.3.1/src/c
 
 GLOG = third_party/glog-0.3.1
-GMOCK = third_party/gmock-1.5.0
+GTEST = third_party/gtest-1.5.0
+SQLITE = third_party/sqlite-3.6.23.1
 
 
 default: all
@@ -29,7 +30,8 @@ src: third_party
 third_party:
 	$(MAKE) -C $(LIBPROCESS)
 	$(MAKE) -C $(GLOG)
-	$(MAKE) -C $(GMOCK)
+	$(MAKE) -C $(GTEST)
+	$(MAKE) -C $(SQLITE)
 ifeq ($(WITH_INCLUDED_ZOOKEEPER),1)
 	$(MAKE) -C $(ZOOKEEPER)
 endif
@@ -83,7 +85,8 @@ distclean:
 	$(MAKE) -C src clean
 	$(MAKE) -C $(LIBPROCESS) distclean
 	$(MAKE) -C $(GLOG) distclean
-	$(MAKE) -C $(GMOCK) distclean
+	$(MAKE) -C $(GTEST) distclean
+	$(MAKE) -C $(SQLITE) distclean
 ifeq ($(WITH_INCLUDED_ZOOKEEPER),1)
 	$(MAKE) -C $(ZOOKEEPER) distclean
 endif
@@ -116,7 +119,8 @@ clean:
 	$(MAKE) -C src clean
 	$(MAKE) -C $(LIBPROCESS) clean
 	$(MAKE) -C $(GLOG) clean
-	$(MAKE) -C $(GMOCK) clean
+	$(MAKE) -C $(GTEST) clean
+	$(MAKE) -C $(SQLITE) clean
 ifeq ($(WITH_INCLUDED_ZOOKEEPER),1)
 	$(MAKE) -C $(ZOOKEEPER) clean
 endif

Modified: incubator/mesos/trunk/src/Makefile.in
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/Makefile.in?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/Makefile.in (original)
+++ incubator/mesos/trunk/src/Makefile.in Sun Jun  5 08:48:04 2011
@@ -39,6 +39,8 @@ LIBEV = $(LIBPROCESS)/third_party/libev-
 
 GLOG = third_party/glog-0.3.1
 
+SQLITE = third_party/glog-0.3.1
+
 ZOOKEEPER = third_party/zookeeper-3.3.1/src/c
 
 # Ensure that we get better debugging info.
@@ -69,6 +71,10 @@ LDFLAGS += -L@top_builddir@/$(LIBEV)/.li
 CXXFLAGS += -I@top_srcdir@/$(GLOG)/src -I@top_builddir@/$(GLOG)/src
 LDFLAGS += -L@top_builddir@/$(GLOG)/.libs
 
+# Add sqlite to include and lib paths.
+CXXFLAGS += -I@top_srcdir@/$(SQLITE)/src -I@top_builddir@/$(SQLITE)/src
+LDFLAGS += -L@top_builddir@/$(SQLITE)/.libs
+
 # Add included ZooKeeper to include and lib paths if necessary.
 ifeq ($(WITH_INCLUDED_ZOOKEEPER),1)
   CXXFLAGS += -I@top_srcdir@/$(ZOOKEEPER)/include -I@top_srcdir@/$(ZOOKEEPER)/generated
@@ -91,7 +97,7 @@ CXXFLAGS += -DBUILD_USER="\"$$USER\""
 LDFLAGS += -L$(LIBEV)/.libs
 
 # Add glog, libev, libprocess, pthread, and dl to LIBS.
-LIBS += -lglog -lprocess -lev -lpthread -ldl
+LIBS += -lglog -lprocess -lev -lpthread -ldl -lsqlite3
 
 # Add ZooKeeper if necessary.
 ifeq ($(WITH_ZOOKEEPER),1)
@@ -123,7 +129,7 @@ SWIG_WEBUI_OBJ = $(MASTER_SWIG_WEBUI_OBJ
 COMMON_OBJ = common/fatal.o messaging/messages.o common/lock.o		\
 	     detector/detector.o common/params.o			\
 	     detector/url_processor.o configurator/configurator.o	\
-	     common/string_utils.o common/logging.o common/date_utils.o
+	     common/string_utils.o common/logging.o event_history/event_history.o
 
 ifeq ($(WITH_ZOOKEEPER),1)
   COMMON_OBJ += detector/zookeeper.o
@@ -216,8 +222,8 @@ DEPLOY_FILES = $(DEPLOYDIR)/deploy-to-sl
 
 # Create rules for building the directories that aren't created
 # automagically by configure.
-OBJ_DIRECTORIES = common configurator detector exec launcher local	\
-                  master messaging sched slave
+OBJ_DIRECTORIES = common configurator detector event_history exec launcher \
+                  local	master messaging sched slave
 
 WEBUI_DIRECTORIES = $(BINDIR)/webui/common $(BINDIR)/webui/master	\
                     $(BINDIR)/webui/slave $(BINDIR)/webui/static	\

Added: incubator/mesos/trunk/src/event_history/event_history.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/event_history/event_history.cpp?rev=1132128&view=auto
==============================================================================
--- incubator/mesos/trunk/src/event_history/event_history.cpp (added)
+++ incubator/mesos/trunk/src/event_history/event_history.cpp Sun Jun  5 08:48:04 2011
@@ -0,0 +1,298 @@
+#include "event_history.hpp"
+#include <cstdlib>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdarg.h>
+
+#include <glog/logging.h>
+
+using namespace mesos::internal::eventhistory;
+
+//returns the current time in microseconds
+long getTimeStamp(){
+  struct timeval curr_time;
+  struct timezone tzp;
+  gettimeofday(&curr_time, &tzp);
+  return (long)(curr_time.tv_sec * 1000000 + curr_time.tv_usec);
+}
+
+
+//returns a human readable timestamp
+string getHumanReadableTimeStamp(){
+  time_t currTime; /* calendar time */
+  currTime=time(NULL); /* get current cal time */
+  string timestamp = asctime(localtime(&currTime));
+  return timestamp.erase(24); /* chop off the newline */
+}
+
+
+//////////FileEventWriter/////////
+
+/* Pre-condition: params["log_dir"] exists and is writable */
+FileEventWriter::FileEventWriter(const Params& params) {
+  string logDir = params.get("log_dir","");
+  CHECK_NE(logDir, "") << "FileEventWriter was created when no log_dir was set";
+  logfile.open ((logDir + "/event_history_log.txt").c_str(),ios::app|ios::out);
+}
+
+
+string FileEventWriter::getName() {
+  return "File Event Writer";
+}
+
+
+FileEventWriter::~FileEventWriter() {
+  logfile.close();
+  DLOG(INFO) << "closed event log file" << endl;
+}
+
+
+int FileEventWriter::logTaskCreated(TaskID tid, FrameworkID fwid, SlaveID sid,
+                                    string webuiUrl, Resources resVec)
+{
+  logfile << getHumanReadableTimeStamp() << ",CreateTask, "
+          << "taskid: " << tid << ", "
+          << "fwid: " << fwid << ", "
+          << "sid: " << sid << ","
+          << "cpus: " << resVec.cpus << ", mem: " << resVec.mem << endl;
+
+  return 0;
+}
+
+
+int FileEventWriter::logTaskStateUpdated(TaskID tid, FrameworkID fwid,
+                                         TaskState state)
+{
+  logfile << getHumanReadableTimeStamp() << ", TaskStateUpdate, "
+          << "taskid: " << tid << ", "
+          << "fwid: " << fwid << ", "
+          << "state: " << state << endl;
+
+  return 0;
+}
+
+
+int FileEventWriter::logFrameworkRegistered(FrameworkID fwid, string user) {
+  logfile << getHumanReadableTimeStamp() << ", CreateFramework, "
+          << "fwid: " << fwid << ", "
+          << "userid: " << user << endl;
+
+  return 0;
+}
+
+
+int FileEventWriter::logFrameworkUnregistered(FrameworkID fwid) {
+  LOG(FATAL) << "FileEventWriter::logFrameworkUnregistered not implemented yet";
+  return -1;
+}
+
+
+//////////SqlLiteEventWriter/////////
+static int callback(void *NotUsed, int argc, char **argv, char **azColName){
+  int i;
+  for(i=0; i<argc; i++){
+    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
+  }
+  printf("\n");
+  return 0;
+}
+
+
+string SqlLiteEventWriter::getName(){
+  return "Sqlite Event Writer";
+}
+
+
+/* Pre-condition: params["log_dir"] exists and is writable */
+SqlLiteEventWriter::SqlLiteEventWriter(const Params& params) {
+  zErrMsg = 0;
+  string logDir = params.get("log_dir","");
+  CHECK_NE(logDir, "") << "SqlLiteEventWriter constructor failed pre-condition."
+                       << " params[\"log_dir\" must be set.";
+
+  //set up log file in log dir
+  int rc = sqlite3_open((logDir + "/event_history_db.sqlite3").c_str(),&db);
+  if( rc ) {
+    LOG(ERROR) << "Can't open database: " << sqlite3_errmsg(db) << endl;
+    sqlite3_close(db);
+  } else {
+    DLOG(INFO) << "opened sql lite db" << endl;
+  }
+  //create task table in case it doesn't already exist,
+  //if it does this shouldn't destroy it
+  sqlite3_exec(db, "CREATE TABLE task (taskid Varchar(255), fwid Varchar(255), \
+                    sid Varchar(255), webuiUrl Varchar(255), \
+                    datetime_created integer, resource_list Varchar(255))",
+               ::callback, 0, &zErrMsg);
+
+  sqlite3_exec(db, "CREATE TABLE taskstate (taskid Varchar(255), \
+                    fwid Varchar(255), state Varchar(255), \
+                    datetime_updated integer)",
+               ::callback, 0, &zErrMsg);
+
+  sqlite3_exec(db, "CREATE TABLE framework (fwid Varchar(255), \
+                    user Varchar(255), datetime_registered integer)",
+               ::callback, 0, &zErrMsg);
+}
+
+
+SqlLiteEventWriter::~SqlLiteEventWriter() {
+  sqlite3_close(db);
+  DLOG(INFO) << "closed sqllite db" << endl;
+}
+
+
+int SqlLiteEventWriter::logTaskCreated(TaskID tid, FrameworkID fwid,
+                                       SlaveID sid, string webuiUrl, 
+                                       Resources resVec)
+{
+  stringstream ss;
+  ss << "INSERT INTO task VALUES ("
+     << "\"" << tid << "\"" << ","
+     << "\"" << fwid << "\"" << ","
+     << "\"" << sid << "\"" << ","
+     << "\"" << webuiUrl << "\"" << ","
+     << getTimeStamp() << ","
+     << "'{"
+       << "\"cpus\":\"" << resVec.cpus << "\","
+       << "\"mem\":\"" << resVec.mem << "\""
+     << "}'"
+     << ")" << endl;
+  DLOG(INFO) << "executing " << ss.str() << endl;
+  sqlite3_exec(db, ss.str().c_str(), callback, 0, &zErrMsg);
+
+  return 0;
+}
+
+
+int SqlLiteEventWriter::logTaskStateUpdated(TaskID tid, FrameworkID fwid,
+                                            TaskState state)
+{
+  stringstream ss;
+  ss << "INSERT INTO taskstate VALUES ("
+     << "\"" << tid << "\"" << ","
+     << "\"" << fwid << "\"" << ","
+     << "\"" << state << "\"" << ","
+     << getTimeStamp() << ")" << endl;
+  DLOG(INFO) << "executing " << ss.str() << endl;
+  sqlite3_exec(db, ss.str().c_str(), callback, 0, &zErrMsg);
+
+  return 0;
+}
+
+
+int SqlLiteEventWriter::logFrameworkRegistered(FrameworkID fwid, string user) {
+  stringstream ss;
+  ss << "INSERT INTO framework VALUES ("
+     << "\"" << fwid << "\"" << ","
+     << "\"" << user << "\"" << ","
+     << getTimeStamp() << ")" << endl;
+  DLOG(INFO) << "executing " << ss.str() << endl;
+  sqlite3_exec(db, ss.str().c_str(), callback, 0, &zErrMsg); 
+  return 0;
+}
+
+
+int SqlLiteEventWriter::logFrameworkUnregistered(FrameworkID fwid) {
+  LOG(FATAL) << "SqlLiteEvent::logFrameworkUnregistered not implemented yet";
+  return -1;
+}
+
+
+/////////////EventLogger//////////
+void EventLogger::registerOptions(Configurator* conf) {
+  //TODO(andyk): We don't set the default value here, since this would
+  //             override the defaults set at the param.get() calls later.
+  //             We would like to set the default here and override it later.
+  conf->addOption<bool>("event-history-file",
+        "Enable file event history logging(default: true)");
+  conf->addOption<bool>("event-history-sqlite",
+      "Enable SQLite event history logging (default: false)");
+}
+
+
+EventLogger::EventLogger() { }
+
+
+EventLogger::EventLogger(const Params& params) {
+  struct stat sb;
+  string logDir = params.get("log_dir", "");
+  if (logDir != "") {
+    LOG(INFO) << "creating EventLogger, using log_dir: " << logDir << endl;
+    if (stat(logDir.c_str(), &sb) == -1) {
+      LOG(INFO) << "The log directory (" << logDir << ") does not exist, "
+                 << "creating it now." << endl ;
+      if (mkdir(logDir.c_str(), S_IRWXU | S_IRWXG) != 0) {
+        LOG(ERROR) << "encountered an error while creating 'logs' directory, "
+                   << "file based event history will not be captured";
+      }
+    }
+    //Create and add file based writers (i.e. writers which depend on log_dir
+    //being set) to writers list.
+    if (params.get<bool>("event-history-file", true)) {
+      LOG(INFO) << "creating FileEventWriter" << endl;
+      writers.push_front(new FileEventWriter(params));
+    }
+    if (params.get<bool>("event-history-sqlite", false)) {
+      LOG(INFO) << "creating SqliteEventWriter" << endl;
+      writers.push_front(new SqlLiteEventWriter(params));
+    }
+  } else {
+    LOG(INFO) << "No log directory was specified, so not creating "
+              << "FileEventWriter or SqliteEventWriter. No event "
+              << "logging will happen!";
+    //Create and add non file based writers to writers list here.
+  }
+}
+
+
+EventLogger::~EventLogger() {
+  //Delete all eventWriters in list.
+  list<EventWriter*>::iterator it;
+  for (it = writers.begin(); it != writers.end(); it++) {
+    delete *it;
+  }
+}
+
+int EventLogger::logFrameworkRegistered(FrameworkID fwid, string user) {
+  list<EventWriter*>::iterator it;
+  for (it = writers.begin(); it != writers.end(); it++) {
+    (*it)->logFrameworkRegistered(fwid, user);
+    DLOG(INFO) << "logged FrameworkRegistered event with " << (*it)->getName()
+               << ". fwid: " << fwid << ", user: " << user << endl;
+  }
+}
+
+
+int EventLogger::logFrameworkUnregistered(FrameworkID fwid) {
+  list<EventWriter*>::iterator it;
+  for (it = writers.begin(); it != writers.end(); it++) {
+    (*it)->logFrameworkUnregistered(fwid);
+    DLOG(INFO) << "logged FrameworkUnregistered event with " << (*it)->getName()
+               << ". fwid: " << fwid << endl;
+  }
+}
+
+
+int EventLogger::logTaskCreated(TaskID tid, FrameworkID fwid, SlaveID sid,
+                                string webuiUrl, Resources resVec)
+{
+  list<EventWriter*>::iterator it;
+  for (it = writers.begin(); it != writers.end(); it++) {
+    (*it)->logTaskCreated(tid, fwid, sid, webuiUrl, resVec);
+    DLOG(INFO) << "logged TaskCreated event with " << (*it)->getName() << endl;
+  }
+}
+
+
+int EventLogger::logTaskStateUpdated(TaskID tid, FrameworkID fwid,
+                                     TaskState state)
+{
+  list<EventWriter*>::iterator it;
+  for (it = writers.begin(); it != writers.end(); it++) {
+    (*it)->logTaskStateUpdated(tid, fwid, state);
+    DLOG(INFO) << "logged TaskStateUpated event with " << (*it)->getName()
+               << endl;
+  }
+}

Added: incubator/mesos/trunk/src/event_history/event_history.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/event_history/event_history.hpp?rev=1132128&view=auto
==============================================================================
--- incubator/mesos/trunk/src/event_history/event_history.hpp (added)
+++ incubator/mesos/trunk/src/event_history/event_history.hpp Sun Jun  5 08:48:04 2011
@@ -0,0 +1,89 @@
+#ifndef __EVENT_HISTORY_HPP__
+#define __EVENT_HISTORY_HPP__
+
+#include <ctime>
+#include <fstream>
+#include <iostream>
+#include <list>
+#include <map>
+#include <string>
+
+#include <sqlite3.h>
+
+#include "configurator/configurator.hpp"
+#include "common/resources.hpp"
+#include "mesos.hpp"
+
+namespace mesos { namespace internal { namespace eventhistory {
+
+using namespace std;
+using mesos::FrameworkID;
+using mesos::TaskID;
+using mesos::SlaveID;
+using mesos::FrameworkID;
+using mesos::TaskState;
+using mesos::internal::Resources;
+
+class EventWriter {
+public:
+  virtual ~EventWriter() {}
+  virtual string getName() = 0;
+  virtual int logTaskCreated(TaskID, FrameworkID, SlaveID, string sHostname, Resources) = 0;
+  virtual int logTaskStateUpdated(TaskID, FrameworkID, TaskState) = 0; 
+  virtual int logFrameworkRegistered(FrameworkID, string) = 0;
+  virtual int logFrameworkUnregistered(FrameworkID) = 0;
+};
+
+
+class FileEventWriter : public EventWriter {
+private:
+  ofstream logfile;
+  time_t currTime;
+public:
+  string getName();
+  FileEventWriter(); 
+  FileEventWriter(const Params&);
+  ~FileEventWriter();
+  int logTaskCreated(TaskID, FrameworkID, SlaveID, string sHostname, Resources);
+  int logTaskStateUpdated(TaskID, FrameworkID, TaskState); 
+  int logFrameworkRegistered(FrameworkID, string);
+  int logFrameworkUnregistered(FrameworkID);
+};
+
+
+class SqlLiteEventWriter : public EventWriter {
+private:
+  sqlite3 *db; 
+  char *zErrMsg;
+  time_t currTime;
+public:
+  string getName();
+  SqlLiteEventWriter(); 
+  SqlLiteEventWriter(const Params&);
+  ~SqlLiteEventWriter();
+  int logTaskCreated(TaskID, FrameworkID, SlaveID, string sHostname, Resources);
+  int logTaskStateUpdated(TaskID, FrameworkID, TaskState); 
+  int logFrameworkRegistered(FrameworkID, string);
+  int logFrameworkUnregistered(FrameworkID);
+};
+
+
+class EventLogger {
+private:
+  list<EventWriter*> writers; 
+public:
+  EventLogger();
+  EventLogger(const Params&);
+  ~EventLogger();
+  static void registerOptions(Configurator*);
+  int logResourceOffer(FrameworkID, Resources);
+  int logTaskCreated(TaskID, FrameworkID, SlaveID, string sHostname, Resources);
+  int logTaskStateUpdated(TaskID, FrameworkID, TaskState); 
+  int logFrameworkRegistered(FrameworkID, string);
+  int logFrameworkUnregistered(FrameworkID);
+  EventLogger operator() (string, string);
+};
+
+}}} /* namespace */
+
+#endif /* __EVENT_HISTORY_HPP__ */

Modified: incubator/mesos/trunk/src/examples/Makefile.in
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/examples/Makefile.in?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/examples/Makefile.in (original)
+++ incubator/mesos/trunk/src/examples/Makefile.in Sun Jun  5 08:48:04 2011
@@ -29,6 +29,8 @@ LIBEV = $(LIBPROCESS)/third_party/libev-
 
 GLOG = third_party/glog-0.3.1
 
+SQLITE = third_party/sqlite-3.6.23.1
+
 ZOOKEEPER = third_party/zookeeper-3.3.1/src/c
 
 # Ensure that we get better debugging info.
@@ -56,8 +58,8 @@ LDFLAGS += -L@top_builddir@/$(LIBPROCESS
 LDFLAGS += -L@top_builddir@/$(LIBEV)/.libs
 
 # Add glog to include and lib paths.
-CXXFLAGS += -I@top_srcdir@/$(GLOG)/src -I@top_builddir@/$(GLOG)/src
-LDFLAGS += -L@top_builddir@/$(GLOG)/.libs
+CXXFLAGS += -I@top_srcdir@/$(GLOG)/src -I@top_builddir@/$(GLOG)/src -I@top_srcdir@/$(SQLITE)
+LDFLAGS += -L@top_builddir@/$(GLOG)/.libs -L@top_builddir@/$(SQLITE)/.libs
 
 # Add included ZooKeeper to include and lib paths if necessary.
 ifeq ($(WITH_INCLUDED_ZOOKEEPER),1)
@@ -81,7 +83,7 @@ CXXFLAGS += -DBUILD_USER="\"$$USER\""
 LDFLAGS += -L$(LIBEV)/.libs
 
 # Add glog, libev, libprocess, pthread, and dl to LIBS.
-LIBS += -lglog -lprocess -lev -lpthread -ldl
+LIBS += -lglog -lprocess -lev -lpthread -ldl -lsqlite3
 
 # Add ZooKeeper if necessary.
 ifeq ($(WITH_ZOOKEEPER),1)

Modified: incubator/mesos/trunk/src/local/local.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/local/local.cpp?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/local/local.cpp (original)
+++ incubator/mesos/trunk/src/local/local.cpp Sun Jun  5 08:48:04 2011
@@ -10,6 +10,8 @@
 
 #include "configurator/configurator.hpp"
 
+#include "event_history/event_history.hpp"
+ 
 #include "master/master.hpp"
 
 #include "slave/process_based_isolation_module.hpp"
@@ -18,6 +20,7 @@
 using std::map;
 using std::vector;
 
+using mesos::internal::eventhistory::EventLogger;
 using mesos::internal::master::Master;
 using mesos::internal::slave::Slave;
 using mesos::internal::slave::IsolationModule;
@@ -40,6 +43,7 @@ void initialize_glog() {
 
 namespace mesos { namespace internal { namespace local {
 
+static EventLogger* evLogger = NULL;
 static Master *master = NULL;
 static map<IsolationModule*, Slave*> slaves;
 static MasterDetector *detector = NULL;
@@ -48,6 +52,7 @@ static MasterDetector *detector = NULL;
 void registerOptions(Configurator* conf)
 {
   conf->addOption<int>("slaves", 's', "Number of slaves", 1);
+  EventLogger::registerOptions(conf);
   Logging::registerOptions(conf);
   Master::registerOptions(conf);
   Slave::registerOptions(conf);
@@ -83,7 +88,9 @@ PID launch(const Params& conf, bool init
       google::SetStderrLogging(google::INFO);
   }
 
-  master = new Master(conf);
+  evLogger = new EventLogger(conf);
+
+  master = new Master(conf, evLogger);
 
   PID pid = Process::spawn(master);
 
@@ -109,6 +116,7 @@ void shutdown()
   MesosProcess::post(master->self(), pack<M2M_SHUTDOWN>());
   Process::wait(master->self());
   delete master;
+  delete evLogger;
   master = NULL;
 
   // TODO(benh): Ugh! Because the isolation module calls back into the

Modified: incubator/mesos/trunk/src/master/main.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/master/main.cpp?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/master/main.cpp (original)
+++ incubator/mesos/trunk/src/master/main.cpp Sun Jun  5 08:48:04 2011
@@ -13,6 +13,7 @@ using boost::lexical_cast;
 using boost::bad_lexical_cast;
 
 using namespace mesos::internal::master;
+using mesos::internal::eventhistory::EventLogger;
 
 
 void usage(const char* progName, const Configurator& conf)
@@ -39,6 +40,7 @@ int main(int argc, char **argv)
 #endif
   Logging::registerOptions(&conf);
   Master::registerOptions(&conf);
+  EventLogger::registerOptions(&conf);
 
   if (argc == 2 && string("--help") == argv[1]) {
     usage(argv[0], conf);
@@ -55,6 +57,10 @@ int main(int argc, char **argv)
 
   Logging::init(argv[0], params);
 
+  cout << "Creating event logger." << endl;
+  EventLogger evLogger(params);
+  cout << "Done creating event logger." << endl;
+
   if (params.contains("port"))
     setenv("LIBPROCESS_PORT", params["port"].c_str(), 1);
 
@@ -69,7 +75,7 @@ int main(int argc, char **argv)
   if (chdir(dirname(argv[0])) != 0)
     fatalerror("Could not chdir into %s", dirname(argv[0]));
 
-  Master *master = new Master(params);
+  Master *master = new Master(params, &evLogger);
   PID pid = Process::spawn(master);
 
   bool quiet = Logging::isQuiet(params);

Modified: incubator/mesos/trunk/src/master/master.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/master/master.cpp?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/master/master.cpp (original)
+++ incubator/mesos/trunk/src/master/master.cpp Sun Jun  5 08:48:04 2011
@@ -1,9 +1,8 @@
 #include <iomanip>
+#include <sys/time.h>
 
 #include <glog/logging.h>
 
-#include "common/date_utils.hpp"
-
 #include "allocator.hpp"
 #include "allocator_factory.hpp"
 #include "master.hpp"
@@ -83,6 +82,9 @@ protected:
 
       uint32_t total_cpus = 0;
       uint32_t total_mem = 0;
+      struct timeval curr_time;
+      struct timezone tzp;
+      gettimeofday(&curr_time, &tzp);
 
       foreach (state::Slave *s, state->slaves) {
         total_cpus += s->cpus;
@@ -96,7 +98,9 @@ protected:
           double cpu_share = f->cpus / (double) total_cpus;
           double mem_share = f->mem / (double) total_mem;
           double max_share = max(cpu_share, mem_share);
-          file << tick << "#" << f->id << "#" << f->name << "#" 
+          file << tick << "#" 
+               << (curr_time.tv_sec * 1000000 + curr_time.tv_usec) << "#" 
+               << f->id << "#" << f->name << "#" 
                << f->cpus << "#" << f->mem << "#"
                << cpu_share << "#" << mem_share << "#" << max_share << endl;
         }
@@ -115,15 +119,17 @@ public:
 }
 
 
-Master::Master()
-  : nextFrameworkId(0), nextSlaveId(0), nextSlotOfferId(0)
+Master::Master(EventLogger* evLogger_)
+  : evLogger(evLogger_), nextFrameworkId(0), nextSlaveId(0), 
+    nextSlotOfferId(0), masterId(0)
 {
   allocatorType = "simple";
 }
 
 
-Master::Master(const Params& conf_)
-  : conf(conf_), nextFrameworkId(0), nextSlaveId(0), nextSlotOfferId(0)
+Master::Master(const Params& conf_, EventLogger* evLogger_)
+  : conf(conf_), evLogger(evLogger_), nextFrameworkId(0), nextSlaveId(0), 
+    nextSlotOfferId(0), masterId(0)
 {
   allocatorType = conf.get("allocator", "simple");
 }
@@ -168,7 +174,7 @@ state::MasterState * Master::getState()
     new state::MasterState(BUILD_DATE, BUILD_USER, oss.str());
 
   foreachpair (_, Slave *s, slaves) {
-    state::Slave *slave = new state::Slave(s->id, s->hostname, s->publicDns,
+    state::Slave *slave = new state::Slave(s->id, s->hostname, s->webUIUrl,
         s->resources.cpus, s->resources.mem, s->connectTime);
     state->slaves.push_back(slave);
   }
@@ -257,15 +263,14 @@ void Master::operator () ()
 {
   LOG(INFO) << "Master started at mesos://" << self();
 
-  // Don't do anything until we get a master ID.
-  while (receive() != GOT_MASTER_ID) {
+  // Don't do anything until we get an identifier.
+  while (receive() != GOT_MASTER_ID)
     LOG(INFO) << "Oops! We're dropping a message since "
               << "we haven't received an identifier yet!";  
-  }
-  string faultToleranceId;
-  tie(faultToleranceId) = unpack<GOT_MASTER_ID>(body());
-  masterId = DateUtils::currentDate() + "-" + faultToleranceId;
-  LOG(INFO) << "Master ID: " << masterId;
+  string id;
+  tie(id) = unpack<GOT_MASTER_ID>(body());
+  masterId = lexical_cast<long>(id);
+  LOG(INFO) << "Master ID:" << masterId;
 
   // Create the allocator (we do this after the constructor because it
   // leaks 'this').
@@ -316,8 +321,12 @@ void Master::operator () ()
               1, "Root is not allowed to submit jobs on this cluster"));
         delete framework;
         break;
+
       }
 
+      cout << "About to register framework with event history" << endl;
+      evLogger->logFrameworkRegistered(fid, framework->user);
+      cout << "Registered framework with event history" << endl;
       addFramework(framework);
       break;
     }
@@ -390,8 +399,10 @@ void Master::operator () ()
       tie(fid) = unpack<F2M_UNREGISTER_FRAMEWORK>(body());
       LOG(INFO) << "Asked to unregister framework " << fid;
       Framework *framework = lookupFramework(fid);
-      if (framework != NULL && framework->pid == from())
+      if (framework != NULL && framework->pid == from()) {
         removeFramework(framework);
+        //evLogger->logFrameworkUnregistered(fid);
+      }
       else
         LOG(WARNING) << "Non-authoratative PID attempting framework "
                      << "unregistration ... ignoring";
@@ -443,9 +454,10 @@ void Master::operator () ()
         if (task != NULL) {
           LOG(INFO) << "Asked to kill " << task << " by its framework";
           killTask(task);
-	} else {
-	  LOG(INFO) << "Asked to kill UNKNOWN task by its framework";
-	  send(framework->pid, pack<M2F_STATUS_UPDATE>(tid, TASK_LOST, ""));
+          evLogger->logTaskStateUpdated(tid, fid, TASK_KILLED);
+        } else {
+          LOG(INFO) << "Asked to kill UNKNOWN task by its framework";
+          send(framework->pid, pack<M2F_STATUS_UPDATE>(tid, TASK_LOST, ""));
         }
       }
       break;
@@ -465,9 +477,10 @@ void Master::operator () ()
     }
 
     case S2M_REGISTER_SLAVE: {
-      string slaveId = masterId + "-" + lexical_cast<string>(nextSlaveId++);
+      string slaveId = lexical_cast<string>(masterId) + "-"
+        + lexical_cast<string>(nextSlaveId++);
       Slave *slave = new Slave(from(), slaveId, elapsed());
-      tie(slave->hostname, slave->publicDns, slave->resources) =
+      tie(slave->hostname, slave->webUIUrl, slave->resources) =
         unpack<S2M_REGISTER_SLAVE>(body());
       LOG(INFO) << "Registering " << slave << " at " << slave->pid;
       slaves[slave->id] = slave;
@@ -482,11 +495,12 @@ void Master::operator () ()
     case S2M_REREGISTER_SLAVE: {
       Slave *slave = new Slave(from(), "", elapsed());
       vector<Task> tasks;
-      tie(slave->id, slave->hostname, slave->publicDns,
+      tie(slave->id, slave->hostname, slave->webUIUrl,
           slave->resources, tasks) = unpack<S2M_REREGISTER_SLAVE>(body());
 
       if (slave->id == "") {
-        slave->id = masterId + "-" + lexical_cast<string>(nextSlaveId++);
+        slave->id = lexical_cast<string>(masterId) + "-"
+          + lexical_cast<string>(nextSlaveId++);
         LOG(ERROR) << "Slave re-registered without a SlaveID, "
                    << "generating a new id for it.";
       }
@@ -556,6 +570,7 @@ void Master::operator () ()
           if (task != NULL) {
             LOG(INFO) << "Status update: " << task << " is in state " << state;
             task->state = state;
+            evLogger->logTaskStateUpdated(tid, fid, state);
             // Remove the task if it finished or failed
             if (state == TASK_FINISHED || state == TASK_FAILED ||
                 state == TASK_KILLED || state == TASK_LOST) {
@@ -590,6 +605,7 @@ void Master::operator () ()
           if (task != NULL) {
             LOG(INFO) << "Status update: " << task << " is in state " << state;
             task->state = state;
+            evLogger->logTaskStateUpdated(tid, fid, state);
             // Remove the task if it finished or failed
             if (state == TASK_FINISHED || state == TASK_FAILED ||
                 state == TASK_KILLED || state == TASK_LOST) {
@@ -762,7 +778,8 @@ void Master::operator () ()
 OfferID Master::makeOffer(Framework *framework,
                           const vector<SlaveResources>& resources)
 {
-  OfferID oid = masterId + "-" + lexical_cast<string>(nextSlotOfferId++);
+  OfferID oid = lexical_cast<string>(masterId) + "-" 
+    + lexical_cast<string>(nextSlotOfferId++);
 
   SlotOffer *offer = new SlotOffer(oid, framework->id, resources);
   slotOffers[offer->id] = offer;
@@ -849,6 +866,16 @@ void Master::processOfferReply(SlotOffer
 
   // Launch the tasks in the response
   foreach (const TaskDescription &t, tasks) {
+    // Record the resources in event_history
+    Params params(t.params);
+    Resources res(params.getInt32("cpus", -1),
+                  params.getInt64("mem", -1));
+
+    Slave *slave = lookupSlave(t.slaveId);
+    evLogger->logTaskCreated(t.taskId, framework->id, t.slaveId, 
+                             slave->webUIUrl, res);
+
+    // Launch the tasks in the response
     launchTask(framework, t);
   }
 
@@ -915,6 +942,9 @@ void Master::killTask(Task *task)
   CHECK(framework != NULL);
   CHECK(slave != NULL);
   send(slave->pid, pack<M2S_KILL_TASK>(framework->id, task->id));
+  send(framework->pid,
+       pack<M2F_STATUS_UPDATE>(task->id, TASK_KILLED, task->message));
+  removeTask(task, TRR_TASK_ENDED);
 }
 
 
@@ -1117,14 +1147,21 @@ Allocator* Master::createAllocator()
 }
 
 
-// Create a new framework ID. We format the ID as MASTERID-FWID, where
-// MASTERID is the ID of the master (launch date plus fault tolerant ID)
-// and FWID is an increasing integer.
+// Create a new framework ID. We format the ID as YYYYMMDDhhmm-master-fw,
+// where the first part is the submission date and submission time, master
+// is ID of the master (emphemeral ID from ZooKeeper if ZK is used), and
+// fw is the ID of the framework within the master (an increasing integer).
 FrameworkID Master::newFrameworkId()
 {
+  time_t rawtime;
+  struct tm* timeinfo;
+  time(&rawtime);
+  timeinfo = localtime(&rawtime);
+  char timestr[32];
+  strftime(timestr, sizeof(timestr), "%Y%m%d%H%M", timeinfo);
   int fwId = nextFrameworkId++;
   ostringstream oss;
-  oss << masterId << "-" << setw(4) << setfill('0') << fwId;
+  oss << timestr << "-" << masterId << "-" << setw(4) << setfill('0') << fwId;
   return oss.str();
 }
 

Modified: incubator/mesos/trunk/src/master/master.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/master/master.hpp?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/master/master.hpp (original)
+++ incubator/mesos/trunk/src/master/master.hpp Sun Jun  5 08:48:04 2011
@@ -33,14 +33,13 @@
 
 #include "detector/detector.hpp"
 
+#include "event_history/event_history.hpp"
+
 #include "messaging/messages.hpp"
 
 
 namespace mesos { namespace internal { namespace master {
 
-using namespace mesos;
-using namespace mesos::internal;
-
 using std::make_pair;
 using std::map;
 using std::pair;
@@ -51,7 +50,9 @@ using std::vector;
 using boost::unordered_map;
 using boost::unordered_set;
 
-using foreach::_;
+using namespace mesos;
+using namespace mesos::internal;
+using mesos::internal::eventhistory::EventLogger;
 
 
 // Maximum number of slot offers to have outstanding for each framework.
@@ -76,7 +77,7 @@ const int32_t MAX_MEM = 1024 * 1024 * Me
 const double HEARTBEAT_INTERVAL = 2;
 
 // Acceptable time since we saw the last heartbeat (four heartbeats).
-const double HEARTBEAT_TIMEOUT = HEARTBEAT_INTERVAL * 4;
+const double HEARTBEAT_TIMEOUT = 15;
 
 // Time to wait for a framework to failover (TODO(benh): Make configurable)).
 const time_t FRAMEWORK_FAILOVER_TIMEOUT = 60;
@@ -240,7 +241,7 @@ struct Slave
   SlaveID id;
   bool active; // Turns false when slave is being removed
   string hostname;
-  string publicDns;
+  string webUIUrl;
   double connectTime;
   double lastHeartbeat;
   
@@ -312,6 +313,7 @@ class Master : public MesosProcess
 {
 protected:
   Params conf;
+  EventLogger* evLogger;
 
   unordered_map<FrameworkID, Framework *> frameworks;
   unordered_map<SlaveID, Slave *> slaves;
@@ -327,14 +329,13 @@ protected:
   string allocatorType;
   Allocator *allocator;
 
-  string masterId; // Contains the date the master was launched and its fault
-                   // tolerance ID (e.g. ephemeral ID returned from ZooKeeper).
-                   // Used in framework and slave IDs created by this master.
+  int64_t masterId; // Used to differentiate masters in fault tolerant mode;
+                    // will be this master's ZooKeeper ephemeral id
 
 public:
-  Master();
+  Master(EventLogger* evLogger);
 
-  Master(const Params& conf);
+  Master(const Params& conf, EventLogger* evLogger);
   
   ~Master();
 
@@ -403,8 +404,6 @@ protected:
   virtual Allocator* createAllocator();
 
   FrameworkID newFrameworkId();
-
-  string currentDate();
 };
 
 

Modified: incubator/mesos/trunk/src/master/state.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/master/state.hpp?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/master/state.hpp (original)
+++ incubator/mesos/trunk/src/master/state.hpp Sun Jun  5 08:48:04 2011
@@ -44,16 +44,16 @@ struct SlotOffer
 
 struct Slave
 {
-  Slave(SlaveID id_, const std::string& host_, const std::string& public_dns_,
+  Slave(SlaveID id_, const std::string& host_, const std::string& web_ui_url_,
 	int32_t cpus_, int64_t mem_, time_t connect_)
-    : id(id_), host(host_), public_dns(public_dns_),
+    : id(id_), host(host_), web_ui_url(web_ui_url_),
       cpus(cpus_), mem(mem_), connect_time(connect_) {}
 
   Slave() {}
 
   SlaveID id;
   std::string host;
-  std::string public_dns;
+  std::string web_ui_url;
   int32_t cpus;
   int64_t mem;
   int64_t connect_time;

Modified: incubator/mesos/trunk/src/messaging/messages.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/messaging/messages.hpp?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/messaging/messages.hpp (original)
+++ incubator/mesos/trunk/src/messaging/messages.hpp Sun Jun  5 08:48:04 2011
@@ -281,13 +281,13 @@ TUPLE(M2F_ERROR,
 
 TUPLE(S2M_REGISTER_SLAVE,
       (std::string /*name*/,
-       std::string /*publicDns*/,
+       std::string /*webUIUrl*/,
        Resources));
 
 TUPLE(S2M_REREGISTER_SLAVE,
       (SlaveID,
        std::string /*name*/,
-       std::string /*publicDns*/,
+       std::string /*webuiUrl*/,
        Resources,
        std::vector<Task>));
 

Modified: incubator/mesos/trunk/src/slave/slave.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/slave/slave.cpp?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/slave/slave.cpp (original)
+++ incubator/mesos/trunk/src/slave/slave.cpp Sun Jun  5 08:48:04 2011
@@ -151,18 +151,24 @@ void Slave::operator () ()
   LOG(INFO) << "Slave started at " << self();
 
   // Get our hostname
-  char buf[256];
+  char buf[HOST_NAME_MAX];
   gethostname(buf, sizeof(buf));
   hostent *he = gethostbyname2(buf, AF_INET);
   string hostname = he->h_name;
 
-  // Get our public DNS name. Normally this is our hostname, but on EC2
+  // Get our public Web UI URL. Normally this is our hostname, but on EC2
   // we look for the MESOS_PUBLIC_DNS environment variable. This allows
   // the master to display our public name in its web UI.
-  string publicDns = hostname;
+  LOG(INFO) << "setting up webUIUrl on port " << conf["webui_port"];
+  string webUIUrl;
   if (getenv("MESOS_PUBLIC_DNS") != NULL) {
-    publicDns = getenv("MESOS_PUBLIC_DNS");
+    webUIUrl = getenv("MESOS_PUBLIC_DNS");
+  } else {
+    webUIUrl = hostname;
   }
+#ifdef MESOS_WEBUI
+  webUIUrl += ":" + conf["webui_port"];
+#endif
 
   // Initialize isolation module.
   isolationModule->initialize(this);
@@ -182,7 +188,7 @@ void Slave::operator () ()
 
 	if (id.empty()) {
 	  // Slave started before master.
-	  send(master, pack<S2M_REGISTER_SLAVE>(hostname, publicDns, resources));
+	  send(master, pack<S2M_REGISTER_SLAVE>(hostname, webUIUrl, resources));
 	} else {
 	  // Reconnecting, so reconstruct resourcesInUse for the master.
 	  Resources resourcesInUse; 
@@ -197,7 +203,7 @@ void Slave::operator () ()
 	    }
 	  }
 
-	  send(master, pack<S2M_REREGISTER_SLAVE>(id, hostname, publicDns, resources, taskVec));
+	  send(master, pack<S2M_REREGISTER_SLAVE>(id, hostname, webUIUrl, resources, taskVec));
 	}
 	break;
       }

Modified: incubator/mesos/trunk/src/slave/webui.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/slave/webui.cpp?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/slave/webui.cpp (original)
+++ incubator/mesos/trunk/src/slave/webui.cpp Sun Jun  5 08:48:04 2011
@@ -18,25 +18,27 @@ extern "C" void init_slave();  // Initia
 namespace {
 
 PID slave;
-string webuiPort;
-string logDir;
-string workDir;
 
 }
 
 namespace mesos { namespace internal { namespace slave {
 
+struct webuiArgs {
+  string webuiPort;
+  string logDir;
+  string workDir;
+} myWebuiArgs;
 
 void *runSlaveWebUI(void *)
 {
   LOG(INFO) << "Web UI thread started";
   Py_Initialize();
   char* argv[4];
-  argv[0] = const_cast<char*>("webui/master/webui.py");
-  argv[1] = const_cast<char*>(webuiPort.c_str());
-  argv[2] = const_cast<char*>(logDir.c_str());
-  argv[3] = const_cast<char*>(workDir.c_str());
-  PySys_SetArgv(4, argv);
+  argv[0] = const_cast<char*>("webui/slave/webui.py");
+  argv[1] = const_cast<char*>(myWebuiArgs.webuiPort.c_str());
+  argv[2] = const_cast<char*>(myWebuiArgs.logDir.c_str());
+  argv[3] = const_cast<char*>(myWebuiArgs.workDir.c_str());
+  PySys_SetArgv(4,argv);
   PyRun_SimpleString("import sys\n"
       "sys.path.append('webui/slave/swig')\n"
       "sys.path.append('webui/common')\n"
@@ -57,19 +59,19 @@ void startSlaveWebUI(const PID &slave, c
   // be used! For example, what happens when the slave code changes
   // their default location for the work directory, it might not get
   // changed here!
-  webuiPort = params.get("webui_port", "8081");
-  logDir = params.get("log_dir", FLAGS_log_dir);
+  myWebuiArgs.webuiPort = params.get("webui_port", "8081");
+  myWebuiArgs.logDir = params.get("log_dir", FLAGS_log_dir);
   if (params.contains("work_dir")) {
-    workDir = params.get("work_dir", "");
+    myWebuiArgs.workDir = params.get("work_dir", "");
   } else if (params.contains("home")) {
-    workDir = params.get("home", "") + "/work";
+    myWebuiArgs.workDir = params.get("home", "") + "/work";
   } else {
-    workDir = "work";
+    myWebuiArgs.workDir = "work";
   }
 
-  CHECK(workDir != "");
+  CHECK(myWebuiArgs.workDir != "");
 
-  LOG(INFO) << "Starting slave web UI on port " << webuiPort;
+  LOG(INFO) << "Starting slave web UI on port " << myWebuiArgs.webuiPort;
 
   ::slave = slave;
   pthread_t thread;

Modified: incubator/mesos/trunk/src/tests/Makefile.in
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/Makefile.in?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/Makefile.in (original)
+++ incubator/mesos/trunk/src/tests/Makefile.in Sun Jun  5 08:48:04 2011
@@ -22,7 +22,8 @@ LIBPROCESS = third_party/libprocess
 LIBEV = $(LIBPROCESS)/third_party/libev-3.8
 
 GLOG = third_party/glog-0.3.1
-GMOCK = third_party/gmock-1.5.0
+GTEST = third_party/gtest-1.5.0
+SQLITE = third_party/sqlite-3.6.23.1
 
 ZOOKEEPER = third_party/zookeeper-3.3.1/src/c
 
@@ -50,9 +51,9 @@ LDFLAGS += -L@top_builddir@/$(LIBPROCESS
 # Add libev to LDFLAGS.
 LDFLAGS += -L@top_builddir@/$(LIBEV)/.libs
 
-# Add glog, and gmock/gtest to include paths and library paths.
-CXXFLAGS += -I@top_srcdir@/$(GLOG)/src -I@top_builddir@/$(GLOG)/src -I@top_srcdir@/$(GMOCK)/include -I@top_srcdir@/$(GMOCK)/gtest/include
-LDFLAGS += -L@top_builddir@/$(GLOG)/.libs -L@top_builddir@/$(GMOCK)/lib/.libs -L@top_builddir@/$(GMOCK)/gtest/lib/.libs
+# Add glog and gtest to include paths.
+CXXFLAGS += -I@top_srcdir@/$(GLOG)/src -I@top_builddir@/$(GLOG)/src -I@top_srcdir@/$(GTEST)/include -I@top_srcdir@/$(SQLITE)
+LDFLAGS += -L@top_builddir@/$(GLOG)/.libs -L@top_builddir@/$(GTEST)/lib/.libs -L@top_builddir@/$(SQLITE)/.libs
 
 # Add included ZooKeeper to include and lib paths if necessary.
 ifeq ($(WITH_INCLUDED_ZOOKEEPER),1)
@@ -72,8 +73,8 @@ CXXFLAGS += -DBUILD_DATE="\"$$(date '+%Y
 CFLAGS += -DBUILD_USER="\"$$USER\""
 CXXFLAGS += -DBUILD_USER="\"$$USER\""
 
-# Add glog, gmock, gtest, libev, libprocess, pthread, and dl to LIBS.
-LIBS += -lglog -lgmock -lgtest -lprocess -lev -lpthread -ldl
+# Add glog, gtest, libev, libprocess, pthread, and dl to LIBS.
+LIBS += -lglog -lgtest -lprocess -lev -lpthread -ldl -lsqlite3
 
 # Add ZooKeeper if necessary.
 ifeq ($(WITH_ZOOKEEPER),1)

Modified: incubator/mesos/trunk/src/tests/test_master.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/test_master.cpp?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/tests/test_master.cpp (original)
+++ incubator/mesos/trunk/src/tests/test_master.cpp Sun Jun  5 08:48:04 2011
@@ -5,7 +5,7 @@
 #include <mesos_exec.hpp>
 #include <mesos_sched.hpp>
 
-#include "common/date_utils.hpp"
+#include "event_history/event_history.hpp"
 
 #include "local/local.hpp"
 
@@ -23,13 +23,13 @@ using boost::lexical_cast;
 using namespace mesos;
 using namespace mesos::internal;
 
+using mesos::internal::eventhistory::EventLogger;
 using mesos::internal::master::Master;
 using mesos::internal::slave::Slave;
 using mesos::internal::slave::Framework;
 using mesos::internal::slave::IsolationModule;
 using mesos::internal::slave::ProcessBasedIsolationModule;
 
-
 class NoopScheduler : public Scheduler
 {
 public:
@@ -134,137 +134,123 @@ public:
 TEST(MasterTest, DuplicateTaskIdsInResponse)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
-  DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
   vector<TaskDescription> tasks;
   map<string, string> params;
   params["cpus"] = "1";
   params["mem"] = lexical_cast<string>(1 * Gigabyte);
-  tasks.push_back(TaskDescription(1, "200102030405-0-0", "", params, ""));
-  tasks.push_back(TaskDescription(2, "200102030405-0-0", "", params, ""));
-  tasks.push_back(TaskDescription(1, "200102030405-0-0", "", params, ""));
+  tasks.push_back(TaskDescription(1, "0-0", "", params, ""));
+  tasks.push_back(TaskDescription(2, "0-0", "", params, ""));
+  tasks.push_back(TaskDescription(1, "0-0", "", params, ""));
   FixedResponseScheduler sched(tasks);
   MesosSchedulerDriver driver(&sched, master);
   driver.run();
   EXPECT_EQ("Duplicate task ID: 1", sched.errorMessage);
   local::shutdown();
-  DateUtils::clearMockDate();
 }
 
 
 TEST(MasterTest, TooMuchMemoryInTask)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
-  DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
   vector<TaskDescription> tasks;
   map<string, string> params;
   params["cpus"] = "1";
   params["mem"] = lexical_cast<string>(4 * Gigabyte);
-  tasks.push_back(TaskDescription(1, "200102030405-0-0", "", params, ""));
+  tasks.push_back(TaskDescription(1, "0-0", "", params, ""));
   FixedResponseScheduler sched(tasks);
   MesosSchedulerDriver driver(&sched, master);
   driver.run();
   EXPECT_EQ("Too many resources accepted", sched.errorMessage);
   local::shutdown();
-  DateUtils::clearMockDate();
 }
 
 
 TEST(MasterTest, TooMuchCpuInTask)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
-  DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
   vector<TaskDescription> tasks;
   map<string, string> params;
   params["cpus"] = "4";
   params["mem"] = lexical_cast<string>(1 * Gigabyte);
-  tasks.push_back(TaskDescription(1, "200102030405-0-0", "", params, ""));
+  tasks.push_back(TaskDescription(1, "0-0", "", params, ""));
   FixedResponseScheduler sched(tasks);
   MesosSchedulerDriver driver(&sched, master);
   driver.run();
   EXPECT_EQ("Too many resources accepted", sched.errorMessage);
   local::shutdown();
-  DateUtils::clearMockDate();
 }
 
 
 TEST(MasterTest, TooLittleCpuInTask)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
-  DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
   vector<TaskDescription> tasks;
   map<string, string> params;
   params["cpus"] = "0";
   params["mem"] = lexical_cast<string>(1 * Gigabyte);
-  tasks.push_back(TaskDescription(1, "200102030405-0-0", "", params, ""));
+  tasks.push_back(TaskDescription(1, "0-0", "", params, ""));
   FixedResponseScheduler sched(tasks);
   MesosSchedulerDriver driver(&sched, master);
   driver.run();
   EXPECT_EQ("Invalid task size: <0 CPUs, 1024 MEM>", sched.errorMessage);
   local::shutdown();
-  DateUtils::clearMockDate();
 }
 
 
 TEST(MasterTest, TooLittleMemoryInTask)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
-  DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
   vector<TaskDescription> tasks;
   map<string, string> params;
   params["cpus"] = "1";
   params["mem"] = "1";
-  tasks.push_back(TaskDescription(1, "200102030405-0-0", "", params, ""));
+  tasks.push_back(TaskDescription(1, "0-0", "", params, ""));
   FixedResponseScheduler sched(tasks);
   MesosSchedulerDriver driver(&sched, master);
   driver.run();
   EXPECT_EQ("Invalid task size: <1 CPUs, 1 MEM>", sched.errorMessage);
   local::shutdown();
-  DateUtils::clearMockDate();
 }
 
 
 TEST(MasterTest, TooMuchMemoryAcrossTasks)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
-  DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
   vector<TaskDescription> tasks;
   map<string, string> params;
   params["cpus"] = "1";
   params["mem"] = lexical_cast<string>(2 * Gigabyte);
-  tasks.push_back(TaskDescription(1, "200102030405-0-0", "", params, ""));
-  tasks.push_back(TaskDescription(2, "200102030405-0-0", "", params, ""));
+  tasks.push_back(TaskDescription(1, "0-0", "", params, ""));
+  tasks.push_back(TaskDescription(2, "0-0", "", params, ""));
   FixedResponseScheduler sched(tasks);
   MesosSchedulerDriver driver(&sched, master);
   driver.run();
   EXPECT_EQ("Too many resources accepted", sched.errorMessage);
   local::shutdown();
-  DateUtils::clearMockDate();
 }
 
 
 TEST(MasterTest, TooMuchCpuAcrossTasks)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
-  DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 3, 3 * Gigabyte, false, false);
   vector<TaskDescription> tasks;
   map<string, string> params;
   params["cpus"] = "2";
   params["mem"] = lexical_cast<string>(1 * Gigabyte);
-  tasks.push_back(TaskDescription(1, "200102030405-0-0", "", params, ""));
-  tasks.push_back(TaskDescription(2, "200102030405-0-0", "", params, ""));
+  tasks.push_back(TaskDescription(1, "0-0", "", params, ""));
+  tasks.push_back(TaskDescription(2, "0-0", "", params, ""));
   FixedResponseScheduler sched(tasks);
   MesosSchedulerDriver driver(&sched, master);
   driver.run();
   EXPECT_EQ("Too many resources accepted", sched.errorMessage);
   local::shutdown();
-  DateUtils::clearMockDate();
 }
 
 
@@ -292,14 +278,13 @@ TEST(MasterTest, ResourcesReofferedAfter
 TEST(MasterTest, ResourcesReofferedAfterBadResponse)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
-  DateUtils::setMockDate("200102030405");
   PID master = local::launch(1, 2, 1 * Gigabyte, false, false);
 
   vector<TaskDescription> tasks;
   map<string, string> params;
   params["cpus"] = "0";
   params["mem"] = lexical_cast<string>(1 * Gigabyte);
-  tasks.push_back(TaskDescription(1, "200102030405-0-0", "", params, ""));
+  tasks.push_back(TaskDescription(1, "0-0", "", params, ""));
   FixedResponseScheduler sched1(tasks);
   MesosSchedulerDriver driver1(&sched1, master);
   driver1.run();
@@ -312,7 +297,6 @@ TEST(MasterTest, ResourcesReofferedAfter
   EXPECT_EQ(1, sched2.offersGotten);
 
   local::shutdown();
-  DateUtils::clearMockDate();
 }
 
 
@@ -349,7 +333,8 @@ TEST(MasterTest, SlaveLost)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
 
-  Master m;
+  EventLogger el;
+  Master m(&el);
   PID master = Process::spawn(&m);
 
   ProcessBasedIsolationModule isolationModule;
@@ -502,7 +487,8 @@ TEST(MasterTest, OfferRescinded)
   OfferReplyMessageFilter filter;
   Process::filter(&filter);
 
-  Master m;
+  EventLogger el;
+  Master m(&el);
   PID master = Process::spawn(&m);
 
   ProcessBasedIsolationModule isolationModule;
@@ -681,7 +667,8 @@ TEST(MasterTest, TaskRunning)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
 
-  Master m;
+  EventLogger el;
+  Master m(&el);
   PID master = Process::spawn(&m);
 
   TaskRunningExecutor exec;
@@ -762,7 +749,8 @@ TEST(MasterTest, SchedulerFailoverStatus
 
   ProcessClock::pause();
 
-  Master m;
+  EventLogger el;
+  Master m(&el);
   PID master = Process::spawn(&m);
 
   TaskRunningExecutor exec;
@@ -901,7 +889,8 @@ TEST(MasterTest, FrameworkMessages)
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
 
-  Master m;
+  EventLogger el;
+  Master m(&el);
   PID master = Process::spawn(&m);
 
   FrameworkMessageExecutor exec;
@@ -991,7 +980,8 @@ TEST(MasterTest, SchedulerFailoverFramew
 {
   ASSERT_TRUE(GTEST_IS_THREADSAFE);
 
-  Master m;
+  EventLogger el;
+  Master m(&el);
   PID master = Process::spawn(&m);
 
   SchedulerFailoverFrameworkMessageExecutor exec;

Modified: incubator/mesos/trunk/src/webui/master/index.tpl
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/webui/master/index.tpl?rev=1132128&r1=1132127&r2=1132128&view=diff
==============================================================================
--- incubator/mesos/trunk/src/webui/master/index.tpl (original)
+++ incubator/mesos/trunk/src/webui/master/index.tpl Sun Jun  5 08:48:04 2011
@@ -121,7 +121,7 @@ Idle: {{idle_cpus}} CPUs, {{format_mem(i
   %for s in master.slaves:
     <tr>
     <td>{{s.id}}</td>
-    <td><a href="http://{{s.public_dns}}:8081/">{{s.public_dns}}</a></td>
+    <td><a href="http://{{s.web_ui_url}}:8081/">{{s.web_ui_url}}</a></td>
     <td>{{s.cpus}}</td>
     <td>{{format_mem(s.mem)}}</td>
     <td>{{format_time(s.connect_time)}}</td>