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 2012/05/15 21:12:19 UTC

svn commit: r1338838 [1/11] - in /incubator/mesos/trunk/src: local/ master/ webui/master/static/ webui/master/static/bootstrap/ webui/master/static/bootstrap/css/ webui/master/static/bootstrap/ico/ webui/master/static/bootstrap/img/ webui/master/static...

Author: benh
Date: Tue May 15 19:12:15 2012
New Revision: 1338838

URL: http://svn.apache.org/viewvc?rev=1338838&view=rev
Log:
Added a javascript based webui using Twitter Bootstrap and AngularJS (contributed by Jonathan Fuchs, https://reviews.apache.org/r/5105).

Added:
    incubator/mesos/trunk/src/webui/master/static/
    incubator/mesos/trunk/src/webui/master/static/angular-1.0.0rc8.js
    incubator/mesos/trunk/src/webui/master/static/app.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/
    incubator/mesos/trunk/src/webui/master/static/bootstrap/css/
    incubator/mesos/trunk/src/webui/master/static/bootstrap/css/bootstrap-responsive.css
    incubator/mesos/trunk/src/webui/master/static/bootstrap/css/bootstrap.css
    incubator/mesos/trunk/src/webui/master/static/bootstrap/css/docs.css
    incubator/mesos/trunk/src/webui/master/static/bootstrap/ico/
    incubator/mesos/trunk/src/webui/master/static/bootstrap/ico/favicon.ico
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/bird.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/bootstrap-mdo-sfmoma-01.jpg
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/bootstrap-mdo-sfmoma-02.jpg
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/bootstrap-mdo-sfmoma-03.jpg
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/browsers.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/github-16px.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/glyphicons/
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/glyphicons-halflings-white.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/glyphicons-halflings.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/glyphicons/glyphicons_009_magic.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/glyphicons/glyphicons_042_group.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/glyphicons/glyphicons_079_podium.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/glyphicons/glyphicons_082_roundabout.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/glyphicons/glyphicons_155_show_thumbnails.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/glyphicons/glyphicons_163_iphone.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/glyphicons/glyphicons_214_resize_small.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/glyphicons/glyphicons_266_book_open.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/grid-18px-masked.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/icon-css3.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/icon-github.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/icon-html5.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/icon-twitter.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/less-logo-large.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/less-small.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/img/responsive-illustrations.png
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/README.md
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/application.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap-alert.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap-button.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap-carousel.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap-collapse.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap-dropdown.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap-modal.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap-popover.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap-scrollspy.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap-tab.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap-tooltip.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap-transition.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap-typeahead.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/bootstrap.min.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/google-code-prettify/
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/google-code-prettify/prettify.css
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/google-code-prettify/prettify.js
    incubator/mesos/trunk/src/webui/master/static/bootstrap/js/jquery.js
    incubator/mesos/trunk/src/webui/master/static/controllers.js
    incubator/mesos/trunk/src/webui/master/static/cubism.v1.js
    incubator/mesos/trunk/src/webui/master/static/d3.v2.js
    incubator/mesos/trunk/src/webui/master/static/dashboard.html
    incubator/mesos/trunk/src/webui/master/static/dashboard.js
    incubator/mesos/trunk/src/webui/master/static/framework.html
    incubator/mesos/trunk/src/webui/master/static/frameworks.html
    incubator/mesos/trunk/src/webui/master/static/graph.css
    incubator/mesos/trunk/src/webui/master/static/home.html
    incubator/mesos/trunk/src/webui/master/static/index.html
    incubator/mesos/trunk/src/webui/master/static/log.html
    incubator/mesos/trunk/src/webui/master/static/mesos.css
    incubator/mesos/trunk/src/webui/master/static/slaves.html
    incubator/mesos/trunk/src/webui/master/static/underscore-min.js
Modified:
    incubator/mesos/trunk/src/local/main.cpp
    incubator/mesos/trunk/src/master/http.cpp
    incubator/mesos/trunk/src/master/http.hpp
    incubator/mesos/trunk/src/master/main.cpp
    incubator/mesos/trunk/src/master/master.cpp
    incubator/mesos/trunk/src/master/master.hpp

Modified: incubator/mesos/trunk/src/local/main.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/local/main.cpp?rev=1338838&r1=1338837&r2=1338838&view=diff
==============================================================================
--- incubator/mesos/trunk/src/local/main.cpp (original)
+++ incubator/mesos/trunk/src/local/main.cpp Tue May 15 19:12:15 2012
@@ -88,7 +88,7 @@ int main(int argc, char **argv)
   }
 
   // Initialize libprocess.
-  process::initialize();
+  process::initialize("master");
 
   logging::initialize(argv[0], conf);
 

Modified: incubator/mesos/trunk/src/master/http.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/master/http.cpp?rev=1338838&r1=1338837&r2=1338838&view=diff
==============================================================================
--- incubator/mesos/trunk/src/master/http.cpp (original)
+++ incubator/mesos/trunk/src/master/http.cpp Tue May 15 19:12:15 2012
@@ -17,13 +17,18 @@
  */
 
 #include <iomanip>
+#include <map>
 #include <sstream>
 #include <string>
+#include <vector>
 
 #include "common/build.hpp"
 #include "common/foreach.hpp"
 #include "common/json.hpp"
+#include "common/logging.hpp"
 #include "common/resources.hpp"
+#include "common/result.hpp"
+#include "common/strings.hpp"
 #include "common/type_utils.hpp"
 #include "common/utils.hpp"
 
@@ -34,8 +39,9 @@ using process::Future;
 using process::HttpResponse;
 using process::HttpRequest;
 
+using std::map;
 using std::string;
-
+using std::vector;
 
 namespace mesos {
 namespace internal {
@@ -154,7 +160,7 @@ Future<HttpResponse> vars(
     const Master& master,
     const HttpRequest& request)
 {
-  LOG(INFO) << "HTTP request for '" << request.path << "'";
+  VLOG(1) << "HTTP request for '" << request.path << "'";
 
   // TODO(benh): Consider separating collecting the actual vars we
   // want to display from rendering them. Trying to just create a
@@ -187,7 +193,7 @@ Future<HttpResponse> stats(
     const Master& master,
     const HttpRequest& request)
 {
-  LOG(INFO) << "HTTP request for '" << request.path << "'";
+  VLOG(1) << "HTTP request for '" << request.path << "'";
 
   JSON::Object object;
   object.values["uptime"] = Clock::now() - master.startTime;
@@ -244,7 +250,7 @@ Future<HttpResponse> state(
     const Master& master,
     const HttpRequest& request)
 {
-  LOG(INFO) << "HTTP request for '" << request.path << "'";
+  VLOG(1) << "HTTP request for '" << request.path << "'";
 
   JSON::Object object;
   object.values["build_date"] = build::DATE;
@@ -295,6 +301,119 @@ Future<HttpResponse> state(
   return response;
 }
 
+
+Future<HttpResponse> log(
+    const Master& master,
+    const HttpRequest& request)
+{
+  VLOG(1) << "HTTP request for '" << request.path << "'";
+
+  map<string, vector<string> > pairs =
+    strings::pairs(request.query, ";&", "=");
+
+  off_t offset = -1;
+  ssize_t length = -1;
+  string level = pairs.count("level") ? pairs["level"][0] : "INFO";
+
+  if (pairs.count("offset") > 0) {
+    CHECK(pairs["offset"].size() > 0);
+    Try<off_t> result = utils::numify<off_t>(pairs["offset"].back());
+    if (result.isError()) {
+      LOG(WARNING) << "Failed to \"numify\" the 'offset' ("
+                   << pairs["offset"].back() << "): "
+                   << result.error();
+      return HttpInternalServerErrorResponse();
+    }
+    offset = result.get();
+  }
+
+  if (pairs.count("length") > 0) {
+    CHECK(pairs["length"].size() > 0);
+    Try<ssize_t> result = utils::numify<ssize_t>(pairs["length"].back());
+    if (result.isError()) {
+      LOG(WARNING) << "Failed to \"numify\" the 'length' ("
+                   << pairs["length"].back() << "): "
+                   << result.error();
+      return HttpInternalServerErrorResponse();
+    }
+    length = result.get();
+  }
+
+  string directory = master.conf.get<string>("log_dir", FLAGS_log_dir);
+  string path = directory + "/mesos-master." + level;
+
+  Result<int> fd = utils::os::open(path, O_RDONLY);
+
+  if (fd.isError()) {
+    LOG(WARNING) << "Failed to open log file at "
+                 << path << ": " << fd.error();
+    return HttpNotFoundResponse();
+  }
+
+  off_t size = lseek(fd.get(), 0, SEEK_END);
+
+  if (size == -1) {
+    PLOG(WARNING) << "Failed to seek in the log";
+    close(fd.get());
+    return HttpInternalServerErrorResponse();
+  }
+
+  if (offset == -1) {
+    offset = size;
+  }
+
+  if (length == -1) {
+    length = size - offset;
+  }
+
+  JSON::Object object;
+
+  if (offset < size) {
+    // Seek to the offset we want to read from.
+    if (lseek(fd.get(), offset, SEEK_SET) == -1) {
+      PLOG(WARNING) << "Failed to seek in the log";
+      close(fd.get());
+      return HttpInternalServerErrorResponse();
+    }
+
+    // Read length bytes (or to EOF).
+    char* temp = new char[length];
+
+    length = ::read(fd.get(), temp, length);
+
+    if (length == 0) {
+      object.values["offset"] = offset;
+      object.values["length"] = 0;
+      delete[] temp;
+    } else if (length == -1) {
+      PLOG(WARNING) << "Failed to read from the log";
+      delete[] temp;
+      close(fd.get());
+      return HttpInternalServerErrorResponse();
+    } else {
+      object.values["offset"] = offset;
+      object.values["length"] = length;
+      object.values["data"] = string(temp, length);
+      delete[] temp;
+    }
+  } else {
+    object.values["offset"] = size;
+    object.values["length"] = 0;
+  }
+
+  close(fd.get());
+
+  std::ostringstream out;
+
+  JSON::render(out, object);
+
+  HttpOKResponse response;
+  response.headers["Content-Type"] = "application/json";
+  response.headers["Content-Length"] = utils::stringify(out.str().size());
+  response.body = out.str().data();
+  return response;
+}
+
 } // namespace json {
 } // namespace http {
 } // namespace master {

Modified: incubator/mesos/trunk/src/master/http.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/master/http.hpp?rev=1338838&r1=1338837&r2=1338838&view=diff
==============================================================================
--- incubator/mesos/trunk/src/master/http.hpp (original)
+++ incubator/mesos/trunk/src/master/http.hpp Tue May 15 19:12:15 2012
@@ -51,6 +51,11 @@ process::Future<process::HttpResponse> s
     const Master& master,
     const process::HttpRequest& request);
 
+// Returns data from the log.
+process::Future<process::HttpResponse> log(
+    const Master& master,
+    const process::HttpRequest& request);
+
 } // namespace json {
 } // namespace http {
 } // namespace master {

Modified: incubator/mesos/trunk/src/master/main.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/master/main.cpp?rev=1338838&r1=1338837&r2=1338838&view=diff
==============================================================================
--- incubator/mesos/trunk/src/master/main.cpp (original)
+++ incubator/mesos/trunk/src/master/main.cpp Tue May 15 19:12:15 2012
@@ -95,7 +95,7 @@ int main(int argc, char **argv)
   }
 
   // Initialize libprocess.
-  process::initialize();
+  process::initialize("master");
 
   logging::initialize(argv[0], conf);
 

Modified: incubator/mesos/trunk/src/master/master.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/master/master.cpp?rev=1338838&r1=1338837&r2=1338838&view=diff
==============================================================================
--- incubator/mesos/trunk/src/master/master.cpp (original)
+++ incubator/mesos/trunk/src/master/master.cpp Tue May 15 19:12:15 2012
@@ -401,6 +401,19 @@ void Master::initialize()
   route("vars", bind(&http::vars, cref(*this), params::_1));
   route("stats.json", bind(&http::json::stats, cref(*this), params::_1));
   route("state.json", bind(&http::json::state, cref(*this), params::_1));
+  route("log.json", bind(&http::json::log, cref(*this), params::_1));
+
+  // Use either a directory specified via configuration options (which
+  // is necessary for running out of the build directory before 'make
+  // install') or the directory determined at build time via the
+  // preprocessor macro '-DMESOS_WEBUI_DIR' set in the Makefile.
+  std::string directory = conf.get<std::string>("webui_dir", MESOS_WEBUI_DIR);
+
+  // Remove any trailing '/' in directory.
+  directory = strings::remove(directory, "/", strings::SUFFIX);
+
+  provide("", directory + "/master/static/index.html");
+  provide("static", directory + "/master/static");
 }
 
 

Modified: incubator/mesos/trunk/src/master/master.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/master/master.hpp?rev=1338838&r1=1338837&r2=1338838&view=diff
==============================================================================
--- incubator/mesos/trunk/src/master/master.hpp (original)
+++ incubator/mesos/trunk/src/master/master.hpp Tue May 15 19:12:15 2012
@@ -195,6 +195,10 @@ private:
       const Master& master,
       const HttpRequest& request);
 
+  friend Future<HttpResponse> http::json::log(
+      const Master& master,
+      const HttpRequest& request);
+
   const Configuration conf;
 
   bool elected;