Permalink
Browse files

Added profiler endpoints in libprocess.

From: Ben Mahler <benjamin.mahler@gmail.com>
Review: https://reviews.apache.org/r/8453

git-svn-id: https://svn.apache.org/repos/asf/incubator/mesos/trunk@1424627 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
1 parent a114982 commit 71b7a93e87e849b3d9d9263f058d1fb31365c529 @benh benh committed Dec 20, 2012
@@ -30,7 +30,7 @@ libprocess_la_SOURCES = src/process.cpp src/pid.cpp src/latch.cpp \
src/encoder.hpp src/gate.hpp src/synchronized.hpp
libprocess_la_CPPFLAGS = -I$(srcdir)/include -I$(BOOST) -I$(GLOG)/src \
- -I$(RY_HTTP_PARSER) -I$(LIBEV) $(AM_CPPFLAGS)
+ -I$(GPERFTOOLS)/src -I$(RY_HTTP_PARSER) -I$(LIBEV) $(AM_CPPFLAGS)
libprocess_la_LIBADD = $(GLOG)/libglog.la $(GPERFTOOLS)/libprofiler.la \
third_party/libry_http_parser.la $(LIBEV)/libev.la
@@ -59,6 +59,7 @@ libprocess_la_SOURCES += $(top_srcdir)/include/process/async.hpp \
$(top_srcdir)/include/process/pid.hpp \
$(top_srcdir)/include/process/preprocessor.hpp \
$(top_srcdir)/include/process/process.hpp \
+ $(top_srcdir)/include/process/profiler.hpp \
$(top_srcdir)/include/process/protobuf.hpp \
$(top_srcdir)/include/process/run.hpp \
$(top_srcdir)/include/process/socket.hpp \
@@ -93,6 +93,11 @@ struct OK : Response
status = "200 OK";
}
+ OK(const char* body) : Response(std::string(body))
+ {
+ status = "200 OK";
+ }
+
OK(const std::string& body) : Response(body)
{
status = "200 OK";
@@ -0,0 +1,94 @@
+#ifndef __PROCESS_PROFILER_HPP__
+#define __PROCESS_PROFILER_HPP__
+
+#include <glog/logging.h>
+
+#include <gperftools/profiler.h>
+
+#include <string>
+
+#include <process/future.hpp>
+#include <process/http.hpp>
+#include <process/process.hpp>
+
+#include <stout/format.hpp>
+
+namespace process {
+
+const std::string PROFILE_FILE = "perftools.out";
+
+class Profiler : public Process<Profiler>
+{
+public:
+ Profiler() : ProcessBase("profiler"), started(false) {}
+
+ virtual ~Profiler() {}
+
+protected:
+ virtual void initialize()
+ {
+ route("/start", &Profiler::start);
+ route("/stop", &Profiler::stop);
+ }
+
+private:
+ // HTTP endpoints.
+
+ // Starts the profiler. There are no request parameters.
+ Future<http::Response> start(const http::Request& request)
+ {
+ if (started) {
+ return http::BadRequest("Profiler already started.\n");
+ }
+
+ LOG(INFO) << "Starting Profiler";
+
+ // WARNING: If using libunwind < 1.0.1, profiling should not be used, as
+ // there are reports of crashes.
+ // WARNING: If using libunwind 1.0.1, profiling should not be turned on
+ // when it's possible for new threads to be created.
+ // This may cause a deadlock. The workaround used in libprocess is described
+ // here:
+ // https://groups.google.com/d/topic/google-perftools/Df10Uy4Djrg/discussion
+ // NOTE: We have not tested this with libunwind > 1.0.1.
+ if (!ProfilerStart(PROFILE_FILE.c_str())) {
+ std::string error =
+ strings::format("Failed to start profiler: %s", strerror(errno)).get();
+ LOG(ERROR) << error;
+ return http::InternalServerError(error);
+ }
+
+ started = true;
+ return http::OK("Profiler started.\n");
+ }
+
+ // Stops the profiler. There are no request parameters.
+ // This returns the profile output, it will also remain present
+ // in the working directory.
+ Future<http::Response> stop(const http::Request& request)
+ {
+ if (!started) {
+ return http::BadRequest("Profiler not running.\n");
+ }
+
+ LOG(INFO) << "Stopping Profiler";
+
+ ProfilerStop();
+
+ http::OK response;
+ response.type = response.PATH;
+ response.path = "perftools.out";
+ response.headers["Content-Type"] = "application/octet-stream";
+ response.headers["Content-Disposition"] =
+ strings::format("attachment; filename=%s", PROFILE_FILE).get();
+
+ started = false;
+ return response;
+ }
+
+ bool started;
+};
+
+} // namespace process {
+
+#endif // __PROCESS_PROCESS_HPP__
@@ -57,6 +57,7 @@
#include <process/io.hpp>
#include <process/mime.hpp>
#include <process/process.hpp>
+#include <process/profiler.hpp>
#include <process/socket.hpp>
#include <process/thread.hpp>
#include <process/timer.hpp>
@@ -1390,6 +1391,9 @@ void initialize(const string& delegate)
// Create global garbage collector.
gc = spawn(new GarbageCollector());
+ // Create the global profiler.
+ spawn(new Profiler(), true);
+
// Initialize the mime types.
mime::initialize();

0 comments on commit 71b7a93

Please sign in to comment.