-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Issue 596: Add profiler path to configuration #603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
6a3b748
2059a8b
45eeba9
f9968bb
9e3ae3d
a92b095
0aa7ac9
8dd2764
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,8 +14,9 @@ class Cpu { | |
|
|
||
| /** | ||
| * Start the profiler and write to the specified path. | ||
| * @return bool whether the call to start profiler succeeded. | ||
| */ | ||
| static void startProfiler(const std::string& output_path); | ||
| static bool startProfiler(const std::string& output_path); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add some return value documentation. |
||
|
|
||
| /** | ||
| * Stop the profiler. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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(); | ||
| } | ||
|
|
@@ -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())), | ||
|
|
@@ -317,7 +322,6 @@ AdminImpl::AdminImpl(const std::string& access_log_path, | |
| {"/server_info", "print server version/status information", | ||
| MAKE_HANDLER(handlerServerInfo)}, | ||
| {"/stats", "print server stats", MAKE_HANDLER(handlerStats)}} { | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: unrelated line deletion? |
||
| access_logs_.emplace_back(new Http::AccessLog::InstanceImpl( | ||
| access_log_path, {}, Http::AccessLog::AccessLogFormatUtils::defaultAccessLogFormatter(), | ||
| server.accessLogManager())); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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_; } | ||
|
|
@@ -113,6 +113,7 @@ class AdminImpl : public Admin, | |
|
|
||
| Server::Instance& server_; | ||
| std::list<Http::AccessLog::InstanceSharedPtr> access_logs_; | ||
| std::string profile_path_; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. const |
||
| Network::ListenSocketPtr socket_; | ||
| Http::ConnectionManagerStats stats_; | ||
| Http::ConnectionManagerTracingStats tracing_stats_; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -105,28 +105,39 @@ 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", "", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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", "", | ||
| // Successful call to startProfiler requires tcmalloc. | ||
| #ifdef TCMALLOC | ||
|
|
||
| TEST_F(IntegrationTest, AdminCpuProfilerStart) { | ||
| BufferingStreamDecoderPtr response = IntegrationUtil::makeSingleRequest( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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", "/", "", Http::CodecClient::Type::HTTP1); | ||
| EXPECT_TRUE(response->complete()); | ||
| EXPECT_STREQ("404", response->headers().Status()->value().c_str()); | ||
|
|
||
| response = IntegrationUtil::makeSingleRequest(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 | ||
| 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" | ||
|
|
@@ -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"), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't a fault in this PR (it's a widespread issue in Envoy today), but using
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've filed #605 to track this work. |
||
| server_), | ||
| filter_(admin_), request_headers_{{":path", "/"}} { | ||
| filter_.setDecoderFilterCallbacks(callbacks_); | ||
| } | ||
|
|
@@ -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", "/var/log/envoy/envoy.prof", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not going to fail in all envs. I would use a totally bogus path here.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. /var/log/envoy/envoy.prof might be a valid path in some environments. Maybe use |
||
| 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 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "start the profiler"