Skip to content

Commit

Permalink
feat(http): support CPU profiling using gperf (#290)
Browse files Browse the repository at this point in the history
  • Loading branch information
andylin-hao authored and HuangWei committed Oct 15, 2019
1 parent dfe95f4 commit 4167057
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
55 changes: 55 additions & 0 deletions src/dist/http/pprof_http_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

#include <cstdlib>
#include <chrono>
#include <fstream>
#include <sstream>

#include "pprof_http_service.h"

Expand Down Expand Up @@ -408,6 +410,59 @@ void pprof_http_service::growth_handler(const http_request &req, http_response &
malloc_ext->GetHeapGrowthStacks(&resp.body);
}

// //
// == ip:port/pprof/profile == //
// //
static bool get_cpu_profile(std::string &result, useconds_t seconds)
{
const char *file_name = "cpu.prof";

ProfilerStart(file_name);
usleep(seconds);
ProfilerStop();

std::ifstream in(file_name);
if (!in.is_open()) {
result = "No profile file";
return false;
}
std::ostringstream content;
content << in.rdbuf();
result = content.str();
in.close();
if (remove(file_name) != 0) {
result = "Failed to remove temporary profile file";
return false;
}
return true;
}

void pprof_http_service::profile_handler(const http_request &req, http_response &resp)
{
useconds_t seconds = 60000000;

const char *req_url = req.full_url.to_string().data();
size_t len = req.full_url.length();
string_splitter url_sp(req_url, req_url + len, '?');
if (url_sp != NULL && ++url_sp != NULL) {
string_splitter param_sp(url_sp.field(), url_sp.field() + url_sp.length(), '&');
while (param_sp != NULL) {
string_splitter kv_sp(param_sp.field(), param_sp.field() + param_sp.length(), '=');
std::string key(kv_sp.field(), kv_sp.length());
if (kv_sp != NULL && key == "seconds" && ++kv_sp != NULL) {
char *end_ptr;
seconds = strtoul(kv_sp.field(), &end_ptr, 10) * 1000000;
break;
}
param_sp++;
}
}

resp.status_code = http_status_code::ok;

get_cpu_profile(resp.body, seconds);
}

} // namespace dsn

#endif // DSN_ENABLE_GPERF
9 changes: 9 additions & 0 deletions src/dist/http/pprof_http_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ class pprof_http_service : public http_service
this,
std::placeholders::_1,
std::placeholders::_2));

// ip:port/pprof/profile
register_handler("profile",
std::bind(&pprof_http_service::profile_handler,
this,
std::placeholders::_1,
std::placeholders::_2));
}

std::string path() const override { return "pprof"; }
Expand All @@ -53,6 +60,8 @@ class pprof_http_service : public http_service
void cmdline_handler(const http_request &req, http_response &resp);

void growth_handler(const http_request &req, http_response &resp);

void profile_handler(const http_request &req, http_response &resp);
};

} // namespace dsn
Expand Down

0 comments on commit 4167057

Please sign in to comment.