Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/envoy/server/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ class Admin {
*/
virtual const std::string& accessLogPath() PURE;

/**
* @return const std::string& profiler output path.
*/
virtual const std::string& profilePath() PURE;

/**
* @return Network::Address::InstanceConstSharedPtr the server address.
*/
Expand Down
1 change: 1 addition & 0 deletions source/common/json/config_schemas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,7 @@ const std::string Json::Schema::TOP_LEVEL_CONFIG_SCHEMA(R"EOF(
"type" : "object",
"properties" : {
"access_log_path" : {"type" : "string"},
"profile_path" : {"type" : "string"},
"address" : {"type" : "string"}
},
"required" : ["access_log_path", "address"],
Expand Down
6 changes: 4 additions & 2 deletions source/common/profiler/profiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ namespace Profiler {

bool Cpu::profilerEnabled() { return ProfilingIsEnabledForAllThreads(); }

void Cpu::startProfiler(const std::string& output_path) { ProfilerStart(output_path.c_str()); }
bool Cpu::startProfiler(const std::string& output_path) {
return ProfilerStart(output_path.c_str());
}

void Cpu::stopProfiler() { ProfilerStop(); }

Expand All @@ -27,7 +29,7 @@ void Heap::forceLink() {
namespace Profiler {

bool Cpu::profilerEnabled() { return false; }
void Cpu::startProfiler(const std::string&) {}
bool Cpu::startProfiler(const std::string&) { return false; }
void Cpu::stopProfiler() {}

} // Profiler
Expand Down
3 changes: 2 additions & 1 deletion source/common/profiler/profiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ class Cpu {

/**
* Start the profiler and write to the specified path.
* @return bool whether the call to start the profiler succeeded.
*/
static void startProfiler(const std::string& output_path);
static bool startProfiler(const std::string& output_path);

/**
* Stop the profiler.
Expand Down
1 change: 1 addition & 0 deletions source/server/configuration_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ bool MainImpl::ListenerConfig::createFilterChain(Network::Connection& connection
InitialImpl::InitialImpl(const Json::Object& json) {
Json::ObjectPtr admin = json.getObject("admin");
admin_.access_log_path_ = admin->getString("access_log_path");
admin_.profile_path_ = admin->getString("profile_path", "/var/log/envoy/envoy.prof");
admin_.address_ = Network::Utility::resolveUrl(admin->getString("address"));

if (json.hasObject("flags_path")) {
Expand Down
2 changes: 2 additions & 0 deletions source/server/configuration_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,11 @@ class InitialImpl : public Initial {
struct AdminImpl : public Admin {
// Server::Configuration::Initial::Admin
const std::string& accessLogPath() override { return access_log_path_; }
const std::string& profilePath() override { return profile_path_; }
Network::Address::InstanceConstSharedPtr address() override { return address_; }

std::string access_log_path_;
std::string profile_path_;
Network::Address::InstanceConstSharedPtr address_;
};

Expand Down
11 changes: 8 additions & 3 deletions source/server/http/admin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,11 @@ Http::Code AdminImpl::handlerCpuProfiler(const std::string& url, Buffer::Instanc

bool enable = query_params.begin()->second == "y";
if (enable && !Profiler::Cpu::profilerEnabled()) {
Profiler::Cpu::startProfiler("/var/log/envoy/envoy.prof");
if (!Profiler::Cpu::startProfiler(profile_path_)) {
response.add("failure to start the profiler");
return Http::Code::InternalServerError;
}

} else if (!enable && Profiler::Cpu::profilerEnabled()) {
Profiler::Cpu::stopProfiler();
}
Expand Down Expand Up @@ -295,9 +299,10 @@ void AdminFilter::onComplete() {
AdminImpl::NullRouteConfigProvider::NullRouteConfigProvider()
: config_(new Router::NullConfigImpl()) {}

AdminImpl::AdminImpl(const std::string& access_log_path,
AdminImpl::AdminImpl(const std::string& access_log_path, const std::string& profile_path,
Network::Address::InstanceConstSharedPtr address, Server::Instance& server)
: server_(server), socket_(new Network::TcpListenSocket(address, true)),
: server_(server), profile_path_(profile_path),
socket_(new Network::TcpListenSocket(address, true)),
stats_(Http::ConnectionManagerImpl::generateStats("http.admin.", server_.stats())),
tracing_stats_(Http::ConnectionManagerImpl::generateTracingStats("http.admin.tracing.",
server_.stats())),
Expand Down
5 changes: 3 additions & 2 deletions source/server/http/admin.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ class AdminImpl : public Admin,
public Http::ConnectionManagerConfig,
Logger::Loggable<Logger::Id::admin> {
public:
AdminImpl(const std::string& access_log_path, Network::Address::InstanceConstSharedPtr address,
Server::Instance& server);
AdminImpl(const std::string& access_log_path, const std::string& profiler_path,
Network::Address::InstanceConstSharedPtr address, Server::Instance& server);

Http::Code runCallback(const std::string& path, Buffer::Instance& response);
Network::ListenSocket& socket() { return *socket_; }
Expand Down Expand Up @@ -113,6 +113,7 @@ class AdminImpl : public Admin,

Server::Instance& server_;
std::list<Http::AccessLog::InstanceSharedPtr> access_logs_;
const std::string profile_path_;
Network::ListenSocketPtr socket_;
Http::ConnectionManagerStats stats_;
Http::ConnectionManagerTracingStats tracing_stats_;
Expand Down
3 changes: 2 additions & 1 deletion source/server/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ void InstanceImpl::initialize(Options& options, TestHooks& hooks,
drain_manager_->startParentShutdownSequence();
original_start_time_ = info.original_start_time_;
admin_.reset(new AdminImpl(initial_config.admin().accessLogPath(),
initial_config.admin().address(), *this));
initial_config.admin().profilePath(), initial_config.admin().address(),
*this));
admin_scope_ = stats_store_.createScope("listener.admin.");
handler_.addListener(*admin_, admin_->socket(), *admin_scope_,
Network::ListenerOptions::listenerOptionsWithBindToPort());
Expand Down
2 changes: 1 addition & 1 deletion test/config/integration/server.json
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@
}]
}],

"admin": { "access_log_path": "/dev/null", "address": "tcp://127.0.0.1:10003" },
"admin": { "access_log_path": "/dev/null", "profile_path": "/tmp/envoy.prof", "address": "tcp://127.0.0.1:10003" },
"flags_path": "/invalid_flags",
"statsd_local_udp_port": 8125,
"statsd_tcp_cluster_name": "statsd",
Expand Down
18 changes: 12 additions & 6 deletions test/integration/integration_admin_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,28 +105,34 @@ TEST_F(IntegrationTest, Admin) {
EXPECT_TRUE(response->complete());
EXPECT_STREQ("400", response->headers().Status()->value().c_str());

response = IntegrationUtil::makeSingleRequest(ADMIN_PORT, "GET", "/cpuprofiler?enable=y", "",
response = IntegrationUtil::makeSingleRequest(ADMIN_PORT, "GET", "/hot_restart_version", "",
Http::CodecClient::Type::HTTP1);
EXPECT_TRUE(response->complete());
EXPECT_STREQ("200", response->headers().Status()->value().c_str());

response = IntegrationUtil::makeSingleRequest(ADMIN_PORT, "GET", "/cpuprofiler?enable=n", "",
response = IntegrationUtil::makeSingleRequest(ADMIN_PORT, "GET", "/reset_counters", "",
Http::CodecClient::Type::HTTP1);
EXPECT_TRUE(response->complete());
EXPECT_STREQ("200", response->headers().Status()->value().c_str());

response = IntegrationUtil::makeSingleRequest(ADMIN_PORT, "GET", "/hot_restart_version", "",
response = IntegrationUtil::makeSingleRequest(ADMIN_PORT, "GET", "/certs", "",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's going on with all these handler path changes? They don't seem related.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the two enable=y and enable=n into it's own integration test called AdminCpuProfilerStart. I think this has to do with line order changes.

Http::CodecClient::Type::HTTP1);
EXPECT_TRUE(response->complete());
EXPECT_STREQ("200", response->headers().Status()->value().c_str());
}

response = IntegrationUtil::makeSingleRequest(ADMIN_PORT, "GET", "/reset_counters", "",
Http::CodecClient::Type::HTTP1);
// Successful call to startProfiler requires tcmalloc.
#ifdef TCMALLOC

TEST_F(IntegrationTest, AdminCpuProfilerStart) {
BufferingStreamDecoderPtr response = IntegrationUtil::makeSingleRequest(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you meant to move this request ("/") inside here. Should go back in other section.

ADMIN_PORT, "GET", "/cpuprofiler?enable=y", "", Http::CodecClient::Type::HTTP1);
EXPECT_TRUE(response->complete());
EXPECT_STREQ("200", response->headers().Status()->value().c_str());

response = IntegrationUtil::makeSingleRequest(ADMIN_PORT, "GET", "/certs", "",
response = IntegrationUtil::makeSingleRequest(ADMIN_PORT, "GET", "/cpuprofiler?enable=n", "",
Http::CodecClient::Type::HTTP1);
EXPECT_TRUE(response->complete());
EXPECT_STREQ("200", response->headers().Status()->value().c_str());
}
#endif
28 changes: 27 additions & 1 deletion test/server/http/admin_test.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "common/http/message_impl.h"
#include "common/profiler/profiler.h"
#include "server/http/admin.h"

#include "test/mocks/server/mocks.h"
Expand All @@ -12,8 +13,10 @@ namespace Server {
class AdminFilterTest : public testing::Test {
public:
// TODO(mattklein123): Switch to mocks and do not bind to a real port.
// TODO(htuch): Use proper temporary path allocation method.
AdminFilterTest()
: admin_("/dev/null", Network::Utility::resolveUrl("tcp://127.0.0.1:9002"), server_),
: admin_("/dev/null", "/tmp/envoy.prof", Network::Utility::resolveUrl("tcp://127.0.0.1:9002"),
server_),
filter_(admin_), request_headers_{{":path", "/"}} {
filter_.setDecoderFilterCallbacks(callbacks_);
}
Expand Down Expand Up @@ -45,4 +48,27 @@ TEST_F(AdminFilterTest, Trailers) {
filter_.decodeTrailers(request_headers_);
}

// Can only get code coverage of AdminImpl::handlerCpuProfiler stopProfiler with
// a real profiler linked in (successful call to startProfiler). startProfiler
// requies tcmalloc.
#ifdef TCMALLOC

TEST_F(AdminFilterTest, AdminProfiler) {
Buffer::OwnedImpl data;
admin_.runCallback("/cpuprofiler?enable=y", data);
EXPECT_TRUE(Profiler::Cpu::profilerEnabled());
admin_.runCallback("/cpuprofiler?enable=n", data);
EXPECT_FALSE(Profiler::Cpu::profilerEnabled());
}

#endif

TEST_F(AdminFilterTest, AdminBadProfiler) {
Buffer::OwnedImpl data;
AdminImpl admin_bad_profile_path("/dev/null", "/some/unlikely/bad/path.prof",
Network::Utility::resolveUrl("tcp://127.0.0.1:9002"), server_);
admin_bad_profile_path.runCallback("/cpuprofiler?enable=y", data);
EXPECT_FALSE(Profiler::Cpu::profilerEnabled());
}

} // namespace Server