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 2013/05/29 19:40:50 UTC

[12/35] git commit: Added a 'Logging' process to libprocess.

Added a 'Logging' process to libprocess.

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


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

Branch: refs/heads/master
Commit: 1f145338f5e8435e180d89f2c222a8aa4429eefd
Parents: 29183c1
Author: Benjamin Hindman <be...@twitter.com>
Authored: Sun May 26 23:26:39 2013 -0700
Committer: Benjamin Hindman <be...@twitter.com>
Committed: Tue May 28 14:18:39 2013 -0700

----------------------------------------------------------------------
 third_party/libprocess/Makefile.am                 |    1 +
 third_party/libprocess/include/process/logging.hpp |  111 +++++++++++++++
 third_party/libprocess/src/process.cpp             |   12 ++-
 3 files changed, 122 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1f145338/third_party/libprocess/Makefile.am
----------------------------------------------------------------------
diff --git a/third_party/libprocess/Makefile.am b/third_party/libprocess/Makefile.am
index 0e89be8..c1db145 100644
--- a/third_party/libprocess/Makefile.am
+++ b/third_party/libprocess/Makefile.am
@@ -76,6 +76,7 @@ libprocess_la_SOURCES +=					\
   $(top_srcdir)/include/process/id.hpp				\
   $(top_srcdir)/include/process/io.hpp				\
   $(top_srcdir)/include/process/latch.hpp			\
+  $(top_srcdir)/include/process/logging.hpp			\
   $(top_srcdir)/include/process/message.hpp			\
   $(top_srcdir)/include/process/mime.hpp			\
   $(top_srcdir)/include/process/once.hpp			\

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1f145338/third_party/libprocess/include/process/logging.hpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/include/process/logging.hpp b/third_party/libprocess/include/process/logging.hpp
new file mode 100644
index 0000000..cba2fd4
--- /dev/null
+++ b/third_party/libprocess/include/process/logging.hpp
@@ -0,0 +1,111 @@
+#ifndef __PROCESS_LOGGING_HPP__
+#define __PROCESS_LOGGING_HPP__
+
+#include <glog/logging.h>
+
+#include <process/delay.hpp>
+#include <process/future.hpp>
+#include <process/http.hpp>
+#include <process/process.hpp>
+#include <process/timeout.hpp>
+
+#include <stout/duration.hpp>
+#include <stout/numify.hpp>
+#include <stout/option.hpp>
+#include <stout/stringify.hpp>
+#include <stout/try.hpp>
+
+namespace process {
+
+class Logging : public Process<Logging>
+{
+public:
+  Logging()
+    : ProcessBase("logging"),
+      original(FLAGS_v)
+  {
+    // Make sure all reads/writes can be done atomically (i.e., to
+    // make sure VLOG(*) statements don't read partial writes).
+    // TODO(benh): Use "atomics" primitives for doing reads/writes of
+    // FLAGS_v anyway to account for proper memory barriers.
+    CHECK(sizeof(FLAGS_v) == sizeof(int32_t));
+  }
+
+  virtual ~Logging() {}
+
+protected:
+  virtual void initialize()
+  {
+    route("/toggle", &This::toggle);
+  }
+
+private:
+  Future<http::Response> toggle(const http::Request& request)
+  {
+    Option<std::string> level = request.query.get("level");
+    Option<std::string> duration = request.query.get("duration");
+
+    if (level.isNone() && duration.isNone()) {
+      return http::OK(stringify(FLAGS_v) + "\n");
+    }
+
+    if (level.isSome() && duration.isNone()) {
+      return http::BadRequest("Expecting 'duration=value' in query.\n");
+    } else if (level.isNone() && duration.isSome()) {
+      return http::BadRequest("Expecting 'level=value' in query.\n");
+    }
+
+    Try<int> v = numify<int>(level.get());
+
+    if (v.isError()) {
+      return http::BadRequest(v.error() + ".\n");
+    }
+
+    if (v.get() < 0) {
+      return http::BadRequest("Invalid level '" + stringify(v.get()) + "'.\n");
+    } else if (v.get() < original) {
+      return http::BadRequest("'" + stringify(v.get()) + "' < original level.\n");
+    }
+
+    Try<Duration> d = Duration::parse(duration.get());
+
+    if (d.isError()) {
+      return http::BadRequest(d.error() + ".\n");
+    }
+
+    // Set the logging level.
+    set(v.get());
+
+    // Start a revert timer (if necessary).
+    if (v.get() != original) {
+      timeout = d.get();
+      delay(timeout.remaining(), this, &This::revert);
+    }
+
+    return http::OK();
+  }
+
+  void set(int v)
+  {
+    if (FLAGS_v != v) {
+      VLOG(FLAGS_v) << "Setting verbose logging level to " << v;
+      FLAGS_v = v;
+      __sync_synchronize(); // Ensure 'FLAGS_v' visible in other threads.
+    }
+  }
+
+  void revert()
+  {
+    if (timeout.remaining() == Seconds(0)) {
+      set(original);
+    }
+  }
+
+  Timeout timeout;
+
+  const int32_t original; // Original value of FLAGS_v.
+};
+
+} // namespace process {
+
+#endif // __PROCESS_LOGGING_HPP__

http://git-wip-us.apache.org/repos/asf/incubator-mesos/blob/1f145338/third_party/libprocess/src/process.cpp
----------------------------------------------------------------------
diff --git a/third_party/libprocess/src/process.cpp b/third_party/libprocess/src/process.cpp
index 56f1ec5..86414e5 100644
--- a/third_party/libprocess/src/process.cpp
+++ b/third_party/libprocess/src/process.cpp
@@ -55,6 +55,7 @@
 #include <process/gc.hpp>
 #include <process/id.hpp>
 #include <process/io.hpp>
+#include <process/logging.hpp>
 #include <process/mime.hpp>
 #include <process/process.hpp>
 #include <process/profiler.hpp>
@@ -1392,10 +1393,17 @@ void initialize(const string& delegate)
   // 'spawn' below for the garbage collector.
   initializing = false;
 
-  // Create global garbage collector.
+  // TODO(benh): Make sure creating the garbage collector, logging
+  // process, and profiler always succeeds and use supervisors to make
+  // sure that none terminate.
+
+  // Create global garbage collector process.
   gc = spawn(new GarbageCollector());
 
-  // Create the global profiler.
+  // Create the global logging process.
+  spawn(new Logging(), true);
+
+  // Create the global profiler process.
   spawn(new Profiler(), true);
 
   // Create the global statistics.