You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2014/04/24 01:57:55 UTC

git commit: Added libprocess metrics to master/slave '/stats.json'.

Repository: mesos
Updated Branches:
  refs/heads/master 7f2f049f3 -> 6e2da2093


Added libprocess metrics to master/slave '/stats.json'.

Review: https://reviews.apache.org/r/20373


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/6e2da209
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/6e2da209
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/6e2da209

Branch: refs/heads/master
Commit: 6e2da209344fb2fac3f8719e5bdbf804fa3fc6ed
Parents: 7f2f049
Author: Benjamin Hindman <be...@berkeley.edu>
Authored: Wed Apr 23 16:57:48 2014 -0700
Committer: Benjamin Mahler <bm...@twitter.com>
Committed: Wed Apr 23 16:57:48 2014 -0700

----------------------------------------------------------------------
 src/master/http.cpp        | 45 ++++++++++++++++++++++++++++++++++++++++
 src/slave/http.cpp         | 46 +++++++++++++++++++++++++++++++++++++++++
 src/tests/master_tests.cpp | 39 ++++++++++++++++++++++++++++++++++
 3 files changed, 130 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/6e2da209/src/master/http.cpp
----------------------------------------------------------------------
diff --git a/src/master/http.cpp b/src/master/http.cpp
index 72d8e91..f54c841 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -26,8 +26,11 @@
 
 #include <process/help.hpp>
 
+#include <process/metrics/metrics.hpp>
+
 #include <stout/foreach.hpp>
 #include <stout/json.hpp>
+#include <stout/lambda.hpp>
 #include <stout/memory.hpp>
 #include <stout/net.hpp>
 #include <stout/numify.hpp>
@@ -61,6 +64,8 @@ using process::http::NotFound;
 using process::http::OK;
 using process::http::TemporaryRedirect;
 
+using process::metrics::internal::MetricsProcess;
+
 using std::map;
 using std::string;
 using std::vector;
@@ -332,6 +337,13 @@ Future<Response> Master::Http::redirect(const Request& request)
 }
 
 
+// Declaration of 'stats' continuation.
+static Future<Response> _stats(
+    const Request& request,
+    JSON::Object object,
+    const Response& response);
+
+
 Future<Response> Master::Http::stats(const Request& request)
 {
   LOG(INFO) << "HTTP request for '" << request.path << "'";
@@ -398,6 +410,39 @@ Future<Response> Master::Http::stats(const Request& request)
     object.values[resource.name() + "_percent"] = percent;
   }
 
+  // Include metrics from libprocess metrics while we sunset this
+  // endpoint in favor of libprocess metrics.
+  // TODO(benh): Remove this after transitioning to libprocess metrics.
+  return process::http::get(MetricsProcess::instance()->self(), "snapshot")
+    .then(lambda::bind(&_stats, request, object, lambda::_1));
+}
+
+
+static Future<Response> _stats(
+    const Request& request,
+    JSON::Object object,
+    const Response& response)
+{
+  if (response.status != process::http::statuses[200]) {
+    return InternalServerError("Failed to get metrics: " + response.status);
+  }
+
+  Option<string> type = response.headers.get("Content-Type");
+
+  if (type.isNone() || type.get() != "application/json") {
+    return InternalServerError("Failed to get metrics: expecting JSON");
+  }
+
+  Try<JSON::Object> parse = JSON::parse<JSON::Object>(response.body);
+
+  if (parse.isError()) {
+    return InternalServerError("Failed to parse metrics: " + parse.error());
+  }
+
+  // Now add all the values from metrics.
+  // TODO(benh): Make sure we're not overwriting any values.
+  object.values.insert(parse.get().values.begin(), parse.get().values.end());
+
   return OK(object, request.query.get("jsonp"));
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/6e2da209/src/slave/http.cpp
----------------------------------------------------------------------
diff --git a/src/slave/http.cpp b/src/slave/http.cpp
index 70e409a..cd7f692 100644
--- a/src/slave/http.cpp
+++ b/src/slave/http.cpp
@@ -24,8 +24,11 @@
 #include <process/help.hpp>
 #include <process/owned.hpp>
 
+#include <process/metrics/metrics.hpp>
+
 #include <stout/foreach.hpp>
 #include <stout/json.hpp>
+#include <stout/lambda.hpp>
 #include <stout/net.hpp>
 #include <stout/numify.hpp>
 #include <stout/stringify.hpp>
@@ -50,8 +53,11 @@ using process::Owned;
 using process::TLDR;
 using process::USAGE;
 
+using process::http::InternalServerError;
 using process::http::OK;
 
+using process::metrics::internal::MetricsProcess;
+
 using std::map;
 using std::string;
 using std::vector;
@@ -227,6 +233,13 @@ Future<Response> Slave::Http::health(const Request& request)
 }
 
 
+// Declaration of 'stats' continuation.
+static Future<Response> _stats(
+    const Request& request,
+    JSON::Object object,
+    const Response& response);
+
+
 Future<Response> Slave::Http::stats(const Request& request)
 {
   LOG(INFO) << "HTTP request for '" << request.path << "'";
@@ -265,6 +278,39 @@ Future<Response> Slave::Http::stats(const Request& request)
   object.values["queued_tasks_gauge"] = queued_tasks;
   object.values["launched_tasks_gauge"] = launched_tasks;
 
+  // Include metrics from libprocess metrics while we sunset this
+  // endpoint in favor of libprocess metrics.
+  // TODO(benh): Remove this after transitioning to libprocess metrics.
+  return process::http::get(MetricsProcess::instance()->self(), "snapshot")
+    .then(lambda::bind(&_stats, request, object, lambda::_1));
+}
+
+
+static Future<Response> _stats(
+    const Request& request,
+    JSON::Object object,
+    const Response& response)
+{
+  if (response.status != process::http::statuses[200]) {
+    return InternalServerError("Failed to get metrics: " + response.status);
+  }
+
+  Option<string> type = response.headers.get("Content-Type");
+
+  if (type.isNone() || type.get() != "application/json") {
+    return InternalServerError("Failed to get metrics: expecting JSON");
+  }
+
+  Try<JSON::Object> parse = JSON::parse<JSON::Object>(response.body);
+
+  if (parse.isError()) {
+    return InternalServerError("Failed to parse metrics: " + parse.error());
+  }
+
+  // Now add all the values from metrics.
+  // TODO(benh): Make sure we're not overwriting any values.
+  object.values.insert(parse.get().values.begin(), parse.get().values.end());
+
   return OK(object, request.query.get("jsonp"));
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/6e2da209/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index c047397..c429432 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -29,9 +29,14 @@
 #include <process/clock.hpp>
 #include <process/future.hpp>
 #include <process/gmock.hpp>
+#include <process/http.hpp>
 #include <process/owned.hpp>
 #include <process/pid.hpp>
 
+#include <process/metrics/counter.hpp>
+#include <process/metrics/metrics.hpp>
+
+#include <stout/json.hpp>
 #include <stout/option.hpp>
 #include <stout/os.hpp>
 #include <stout/try.hpp>
@@ -1259,6 +1264,40 @@ TEST_F(MasterTest, LaunchDuplicateOfferTest)
 }
 
 
+TEST_F(MasterTest, MetricsInStatsEndpoint)
+{
+  Try<PID<Master> > master = StartMaster();
+  ASSERT_SOME(master);
+
+  process::metrics::Counter counter("master/events");
+
+  AWAIT_READY(process::metrics::add(counter));
+
+  counter += 42;
+
+  Future<process::http::Response> response =
+    process::http::get(master.get(), "stats.json");
+
+  AWAIT_READY(response);
+
+  EXPECT_SOME_EQ(
+      "application/json",
+      response.get().headers.get("Content-Type"));
+
+  Try<JSON::Object> parse = JSON::parse<JSON::Object>(response.get().body);
+
+  ASSERT_SOME(parse);
+
+  JSON::Object stats = parse.get();
+
+  EXPECT_EQ(42, stats.values["master/events"]);
+
+  AWAIT_READY(process::metrics::remove(counter));
+
+  Shutdown();
+}
+
+
 #ifdef MESOS_HAS_JAVA
 class MasterZooKeeperTest : public MesosTest
 {