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 2015/05/08 05:23:45 UTC
[3/3] mesos git commit: Improved HTTP request logging for
master/slave endpoints.
Improved HTTP request logging for master/slave endpoints.
Review: https://reviews.apache.org/r/33935
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/115db925
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/115db925
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/115db925
Branch: refs/heads/master
Commit: 115db9250e096edf70da54c3f6aea18aefeb1a06
Parents: 21ee7fa
Author: Benjamin Mahler <be...@gmail.com>
Authored: Wed May 6 22:18:39 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Thu May 7 20:11:30 2015 -0700
----------------------------------------------------------------------
src/master/http.cpp | 53 ++++++++++++++++++++++++----------------------
src/master/master.cpp | 49 +++++++++++++++++++++++++++++++++---------
src/master/master.hpp | 29 ++++++++++++++-----------
src/slave/http.cpp | 22 +++++++++++++++----
src/slave/slave.cpp | 17 ++++++++++++---
src/slave/slave.hpp | 10 ++++++---
6 files changed, 123 insertions(+), 57 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/115db925/src/master/http.cpp
----------------------------------------------------------------------
diff --git a/src/master/http.cpp b/src/master/http.cpp
index f0668aa..acc85b6 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -254,6 +254,22 @@ JSON::Object model(const Role& role)
}
+void Master::Http::log(const Request& request)
+{
+ Option<string> userAgent = request.headers.get("User-Agent");
+ Option<string> forwardedFor = request.headers.get("X-Forwarded-For");
+
+ LOG(INFO) << "HTTP " << request.method << " for " << request.path
+ << " from " << request.client
+ << (userAgent.isSome()
+ ? " with User-Agent='" + userAgent.get() + "'"
+ : "")
+ << (forwardedFor.isSome()
+ ? " with X-Forwarded-For='" + forwardedFor.get() + "'"
+ : "");
+}
+
+
const string Master::Http::HEALTH_HELP = HELP(
TLDR(
"Health check of the Master."),
@@ -264,7 +280,7 @@ const string Master::Http::HEALTH_HELP = HELP(
"Delayed responses are also indicative of poor health."));
-Future<Response> Master::Http::health(const Request& request)
+Future<Response> Master::Http::health(const Request& request) const
{
return OK();
}
@@ -313,10 +329,8 @@ Try<string> getFormValue(
}
-Future<Response> Master::Http::observe(const Request& request)
+Future<Response> Master::Http::observe(const Request& request) const
{
- LOG(INFO) << "HTTP request for '" << request.path << "'";
-
Try<hashmap<string, string>> decode =
process::http::query::decode(request.body);
@@ -384,10 +398,8 @@ const string Master::Http::REDIRECT_HELP = HELP(
"this will attempt to redirect to the private IP address."));
-Future<Response> Master::Http::redirect(const Request& request)
+Future<Response> Master::Http::redirect(const Request& request) const
{
- LOG(INFO) << "HTTP request for '" << request.path << "'";
-
// If there's no leader, redirect to this master's base url.
MasterInfo info = master->leader.isSome()
? master->leader.get()
@@ -418,9 +430,8 @@ const string Master::Http::SLAVES_HELP = HELP(
"this master formated as a json object."));
-Future<Response> Master::Http::slaves(const Request& request) {
- LOG(INFO) << "HTTP request for '" << request.path << "'";
-
+Future<Response> Master::Http::slaves(const Request& request) const
+{
JSON::Object object;
{
@@ -439,10 +450,8 @@ Future<Response> Master::Http::slaves(const Request& request) {
}
-Future<Response> Master::Http::state(const Request& request)
+Future<Response> Master::Http::state(const Request& request) const
{
- LOG(INFO) << "HTTP request for '" << request.path << "'";
-
JSON::Object object;
object.values["version"] = MESOS_VERSION;
@@ -725,10 +734,8 @@ private:
};
-Future<Response> Master::Http::stateSummary(const Request& request)
+Future<Response> Master::Http::stateSummary(const Request& request) const
{
- LOG(INFO) << "HTTP request for '" << request.path << "'";
-
JSON::Object object;
object.values["hostname"] = master->info().hostname();
@@ -835,10 +842,8 @@ Future<Response> Master::Http::stateSummary(const Request& request)
}
-Future<Response> Master::Http::roles(const Request& request)
+Future<Response> Master::Http::roles(const Request& request) const
{
- LOG(INFO) << "HTTP request for '" << request.path << "'";
-
JSON::Object object;
// Model all of the roles.
@@ -866,7 +871,7 @@ const string Master::Http::SHUTDOWN_HELP = HELP(
"Returns 200 OK if the framework was correctly shutdown."));
-Future<Response> Master::Http::shutdown(const Request& request)
+Future<Response> Master::Http::shutdown(const Request& request) const
{
if (request.method != "POST") {
return BadRequest("Expecting POST");
@@ -932,7 +937,7 @@ Future<Response> Master::Http::shutdown(const Request& request)
Future<Response> Master::Http::_shutdown(
const FrameworkID& id,
- bool authorized)
+ bool authorized) const
{
if (!authorized) {
return Unauthorized("Mesos master");
@@ -1013,10 +1018,8 @@ struct TaskComparator
};
-Future<Response> Master::Http::tasks(const Request& request)
+Future<Response> Master::Http::tasks(const Request& request) const
{
- LOG(INFO) << "HTTP request for '" << request.path << "'";
-
// Get list options (limit and offset).
Result<int> result = numify<int>(request.query.get("limit"));
size_t limit = result.isSome() ? result.get() : TASK_LIMIT;
@@ -1075,7 +1078,7 @@ Future<Response> Master::Http::tasks(const Request& request)
}
-Result<Credential> Master::Http::authenticate(const Request& request)
+Result<Credential> Master::Http::authenticate(const Request& request) const
{
// By default, assume everyone is authenticated if no credentials
// were provided.
http://git-wip-us.apache.org/repos/asf/mesos/blob/115db925/src/master/master.cpp
----------------------------------------------------------------------
diff --git a/src/master/master.cpp b/src/master/master.cpp
index 49638ce..4ad683e 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -38,6 +38,7 @@
#include <process/collect.hpp>
#include <process/defer.hpp>
#include <process/delay.hpp>
+#include <process/http.hpp>
#include <process/id.hpp>
#include <process/limiter.hpp>
#include <process/owned.hpp>
@@ -111,6 +112,8 @@ namespace mesos {
namespace internal {
namespace master {
+namespace http = process::http;
+
using mesos::master::RoleInfo;
using mesos::master::allocator::Allocator;
@@ -277,7 +280,6 @@ Master::Master(
const Option<shared_ptr<RateLimiter>>& _slaveRemovalLimiter,
const Flags& _flags)
: ProcessBase("master"),
- http(this),
flags(_flags),
allocator(_allocator),
registrar(_registrar),
@@ -721,33 +723,60 @@ void Master::initialize()
&AuthenticateMessage::pid);
// Setup HTTP routes.
+ Http http = Http(this);
+
route("/health",
Http::HEALTH_HELP,
- lambda::bind(&Http::health, http, lambda::_1));
+ [http](const http::Request& request) {
+ return http.health(request);
+ });
route("/observe",
Http::OBSERVE_HELP,
- lambda::bind(&Http::observe, http, lambda::_1));
+ [http](const http::Request& request) {
+ Http::log(request);
+ return http.observe(request);
+ });
route("/redirect",
Http::REDIRECT_HELP,
- lambda::bind(&Http::redirect, http, lambda::_1));
+ [http](const http::Request& request) {
+ return http.redirect(request);
+ });
route("/roles.json",
None(),
- lambda::bind(&Http::roles, http, lambda::_1));
+ [http](const http::Request& request) {
+ Http::log(request);
+ return http.roles(request);
+ });
route("/shutdown",
Http::SHUTDOWN_HELP,
- lambda::bind(&Http::shutdown, http, lambda::_1));
+ [http](const http::Request& request) {
+ Http::log(request);
+ return http.shutdown(request);
+ });
route("/slaves",
Http::SLAVES_HELP,
- lambda::bind(&Http::slaves, http, lambda::_1));
+ [http](const http::Request& request) {
+ Http::log(request);
+ return http.slaves(request);
+ });
route("/state.json",
None(),
- lambda::bind(&Http::state, http, lambda::_1));
+ [http](const http::Request& request) {
+ Http::log(request);
+ return http.state(request);
+ });
route("/state-summary",
None(),
- lambda::bind(&Http::stateSummary, http, lambda::_1));
+ [http](const http::Request& request) {
+ Http::log(request);
+ return http.stateSummary(request);
+ });
route("/tasks.json",
Http::TASKS_HELP,
- lambda::bind(&Http::tasks, http, lambda::_1));
+ [http](const http::Request& request) {
+ Http::log(request);
+ return http.tasks(request);
+ });
// Provide HTTP assets from a "webui" directory. This is either
// specified via flags (which is necessary for running out of the
http://git-wip-us.apache.org/repos/asf/mesos/blob/115db925/src/master/master.hpp
----------------------------------------------------------------------
diff --git a/src/master/master.hpp b/src/master/master.hpp
index d00be17..ee53dfb 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -477,41 +477,45 @@ private:
public:
explicit Http(Master* _master) : master(_master) {}
+ // Logs the request, route handlers can compose this with the
+ // desired request handler to get consistent request logging.
+ static void log(const process::http::Request& request);
+
// /master/health
process::Future<process::http::Response> health(
- const process::http::Request& request);
+ const process::http::Request& request) const;
// /master/observe
process::Future<process::http::Response> observe(
- const process::http::Request& request);
+ const process::http::Request& request) const;
// /master/redirect
process::Future<process::http::Response> redirect(
- const process::http::Request& request);
+ const process::http::Request& request) const;
// /master/roles.json
process::Future<process::http::Response> roles(
- const process::http::Request& request);
+ const process::http::Request& request) const;
// /master/shutdown
process::Future<process::http::Response> shutdown(
- const process::http::Request& request);
+ const process::http::Request& request) const;
// /master/slaves
process::Future<process::http::Response> slaves(
- const process::http::Request& request);
+ const process::http::Request& request) const;
// /master/state.json
process::Future<process::http::Response> state(
- const process::http::Request& request);
+ const process::http::Request& request) const;
// /master/state-summary
process::Future<process::http::Response> stateSummary(
- const process::http::Request& request);
+ const process::http::Request& request) const;
// /master/tasks.json
process::Future<process::http::Response> tasks(
- const process::http::Request& request);
+ const process::http::Request& request) const;
const static std::string HEALTH_HELP;
const static std::string OBSERVE_HELP;
@@ -524,15 +528,16 @@ private:
// Helper for doing authentication, returns the credential used if
// the authentication was successful (or none if no credentials
// have been given to the master), otherwise an Error.
- Result<Credential> authenticate(const process::http::Request& request);
+ Result<Credential> authenticate(
+ const process::http::Request& request) const;
// Continuations.
process::Future<process::http::Response> _shutdown(
const FrameworkID& id,
- bool authorized = true);
+ bool authorized = true) const;
Master* master;
- } http;
+ };
Master(const Master&); // No copying.
Master& operator = (const Master&); // No assigning.
http://git-wip-us.apache.org/repos/asf/mesos/blob/115db925/src/slave/http.cpp
----------------------------------------------------------------------
diff --git a/src/slave/http.cpp b/src/slave/http.cpp
index f678aab..b5e77b0 100644
--- a/src/slave/http.cpp
+++ b/src/slave/http.cpp
@@ -229,6 +229,22 @@ JSON::Object model(const Framework& framework)
}
+void Slave::Http::log(const Request& request)
+{
+ Option<string> userAgent = request.headers.get("User-Agent");
+ Option<string> forwardedFor = request.headers.get("X-Forwarded-For");
+
+ LOG(INFO) << "HTTP " << request.method << " for " << request.path
+ << " from " << request.client
+ << (userAgent.isSome()
+ ? " with User-Agent='" + userAgent.get() + "'"
+ : "")
+ << (forwardedFor.isSome()
+ ? " with X-Forwarded-For='" + forwardedFor.get() + "'"
+ : "");
+}
+
+
const string Slave::Http::HEALTH_HELP = HELP(
TLDR(
"Health check of the Slave."),
@@ -239,16 +255,14 @@ const string Slave::Http::HEALTH_HELP = HELP(
"Delayed responses are also indicative of poor health."));
-Future<Response> Slave::Http::health(const Request& request)
+Future<Response> Slave::Http::health(const Request& request) const
{
return OK();
}
-Future<Response> Slave::Http::state(const Request& request)
+Future<Response> Slave::Http::state(const Request& request) const
{
- LOG(INFO) << "HTTP request for '" << request.path << "'";
-
JSON::Object object;
object.values["version"] = MESOS_VERSION;
http://git-wip-us.apache.org/repos/asf/mesos/blob/115db925/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index c78ee3c..bf290bf 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -39,6 +39,7 @@
#include <process/defer.hpp>
#include <process/delay.hpp>
#include <process/dispatch.hpp>
+#include <process/http.hpp>
#include <process/id.hpp>
#include <process/time.hpp>
@@ -105,6 +106,8 @@ namespace mesos {
namespace internal {
namespace slave {
+namespace http = process::http;
+
using namespace state;
Slave::Slave(const slave::Flags& _flags,
@@ -115,7 +118,6 @@ Slave::Slave(const slave::Flags& _flags,
StatusUpdateManager* _statusUpdateManager)
: ProcessBase(process::ID::generate("slave")),
state(RECOVERING),
- http(this),
flags(_flags),
completedFrameworks(MAX_COMPLETED_FRAMEWORKS),
detector(_detector),
@@ -462,10 +464,19 @@ void Slave::initialize()
&PingSlaveMessage::connected);
// Setup HTTP routes.
+ Http http = Http(this);
+
route("/health",
Http::HEALTH_HELP,
- lambda::bind(&Http::health, http, lambda::_1));
- route("/state.json", None(), lambda::bind(&Http::state, http, lambda::_1));
+ [http](const http::Request& request) {
+ return http.health(request);
+ });
+ route("/state.json",
+ None(),
+ [http](const http::Request& request) {
+ Http::log(request);
+ return http.state(request);
+ });
// Expose the log file for the webui. Fall back to 'log_dir' if
// an explicit file was not specified.
http://git-wip-us.apache.org/repos/asf/mesos/blob/115db925/src/slave/slave.hpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.hpp b/src/slave/slave.hpp
index 654a869..adb52b5 100644
--- a/src/slave/slave.hpp
+++ b/src/slave/slave.hpp
@@ -373,19 +373,23 @@ private:
public:
explicit Http(Slave* _slave) : slave(_slave) {}
+ // Logs the request, route handlers can compose this with the
+ // desired request handler to get consistent request logging.
+ static void log(const process::http::Request& request);
+
// /slave/health
process::Future<process::http::Response> health(
- const process::http::Request& request);
+ const process::http::Request& request) const;
// /slave/state.json
process::Future<process::http::Response> state(
- const process::http::Request& request);
+ const process::http::Request& request) const;
static const std::string HEALTH_HELP;
private:
Slave* slave;
- } http;
+ };
friend struct Framework;
friend struct Executor;