void PProfService::heap( ::google::protobuf::RpcController* controller_base, const ::brpc::ProfileRequest* /*request*/, ::brpc::ProfileResponse* /*response*/, ::google::protobuf::Closure* done) { ClosureGuard done_guard(done); Controller* cntl = static_cast<Controller*>(controller_base); MallocExtension* malloc_ext = MallocExtension::instance(); if (malloc_ext == NULL || !has_TCMALLOC_SAMPLE_PARAMETER()) { const char* extra_desc = ""; if (malloc_ext != NULL) { extra_desc = " (no TCMALLOC_SAMPLE_PARAMETER in env)"; } cntl->SetFailed(ENOMETHOD, "Heap profiler is not enabled%s," "check out http://wiki.baidu.com/display/RPC", extra_desc); return; } // Log requester std::ostringstream client_info; client_info << cntl->remote_side(); if (cntl->auth_context()) { client_info << "(auth=" << cntl->auth_context()->user() << ')'; } else { client_info << "(no auth)"; } LOG(INFO) << client_info.str() << " requests for heap profile"; std::string obj; malloc_ext->GetHeapSample(&obj); cntl->http_response().set_content_type("text/plain"); cntl->response_attachment().append(obj); }
void PProfService::growth( ::google::protobuf::RpcController* controller_base, const ::brpc::ProfileRequest* /*request*/, ::brpc::ProfileResponse* /*response*/, ::google::protobuf::Closure* done) { ClosureGuard done_guard(done); Controller* cntl = static_cast<Controller*>(controller_base); MallocExtension* malloc_ext = MallocExtension::instance(); if (malloc_ext == NULL) { cntl->SetFailed(ENOMETHOD, "%s, to enable growth profiler, check out " "docs/cn/heap_profiler.md", berror(ENOMETHOD)); return; } // Log requester std::ostringstream client_info; client_info << cntl->remote_side(); if (cntl->auth_context()) { client_info << "(auth=" << cntl->auth_context()->user() << ')'; } else { client_info << "(no auth)"; } LOG(INFO) << client_info.str() << " requests for growth profile"; std::string obj; malloc_ext->GetHeapGrowthStacks(&obj); cntl->http_response().set_content_type("text/plain"); cntl->response_attachment().append(obj); }
void PProfService::contention( ::google::protobuf::RpcController* controller_base, const ::brpc::ProfileRequest* /*request*/, ::brpc::ProfileResponse* /*response*/, ::google::protobuf::Closure* done) { ClosureGuard done_guard(done); Controller* cntl = static_cast<Controller*>(controller_base); cntl->http_response().set_content_type("text/plain"); int sleep_sec = ReadSeconds(cntl); if (sleep_sec <= 0) { if (!cntl->Failed()) { cntl->SetFailed(EINVAL, "You have to specify ?seconds=N. If you're " "using pprof, add --seconds=N"); } return; } // Log requester std::ostringstream client_info; client_info << cntl->remote_side(); if (cntl->auth_context()) { client_info << "(auth=" << cntl->auth_context()->user() << ')'; } else { client_info << "(no auth)"; } LOG(INFO) << client_info.str() << " requests for contention profile for " << sleep_sec << " seconds"; char prof_name[256]; if (MakeProfName(PROFILING_CONTENTION, prof_name, sizeof(prof_name)) != 0) { cntl->SetFailed(errno, "Fail to create .prof file, %s", berror()); return; } if (!bthread::ContentionProfilerStart(prof_name)) { cntl->SetFailed(EAGAIN, "Another profiler is running, try again later"); return; } if (bthread_usleep(sleep_sec * 1000000L) != 0) { PLOG(WARNING) << "Profiling has been interrupted"; } bthread::ContentionProfilerStop(); butil::fd_guard fd(open(prof_name, O_RDONLY)); if (fd < 0) { cntl->SetFailed(ENOENT, "Fail to open %s", prof_name); return; } butil::IOPortal portal; portal.append_from_file_descriptor(fd, ULONG_MAX); cntl->response_attachment().swap(portal); }
void PProfService::profile( ::google::protobuf::RpcController* controller_base, const ::brpc::ProfileRequest* /*request*/, ::brpc::ProfileResponse* /*response*/, ::google::protobuf::Closure* done) { ClosureGuard done_guard(done); Controller* cntl = static_cast<Controller*>(controller_base); cntl->http_response().set_content_type("text/plain"); if ((void*)ProfilerStart == NULL || (void*)ProfilerStop == NULL) { cntl->SetFailed(ENOMETHOD, "%s, to enable cpu profiler, check out " "docs/cn/cpu_profiler.md", berror(ENOMETHOD)); return; } int sleep_sec = ReadSeconds(cntl); if (sleep_sec <= 0) { if (!cntl->Failed()) { cntl->SetFailed(EINVAL, "You have to specify ?seconds=N. If you're " "using pprof, add --seconds=N"); } return; } // Log requester std::ostringstream client_info; client_info << cntl->remote_side(); if (cntl->auth_context()) { client_info << "(auth=" << cntl->auth_context()->user() << ')'; } else { client_info << "(no auth)"; } LOG(INFO) << client_info.str() << " requests for cpu profile for " << sleep_sec << " seconds"; char prof_name[256]; if (MakeProfName(PROFILING_CPU, prof_name, sizeof(prof_name)) != 0) { cntl->SetFailed(errno, "Fail to create .prof file, %s", berror()); return; } butil::File::Error error; const butil::FilePath dir = butil::FilePath(prof_name).DirName(); if (!butil::CreateDirectoryAndGetError(dir, &error)) { cntl->SetFailed(EPERM, "Fail to create directory=`%s'",dir.value().c_str()); return; } if (!ProfilerStart(prof_name)) { cntl->SetFailed(EAGAIN, "Another profiler is running, try again later"); return; } if (bthread_usleep(sleep_sec * 1000000L) != 0) { PLOG(WARNING) << "Profiling has been interrupted"; } ProfilerStop(); butil::fd_guard fd(open(prof_name, O_RDONLY)); if (fd < 0) { cntl->SetFailed(ENOENT, "Fail to open %s", prof_name); return; } butil::IOPortal portal; portal.append_from_file_descriptor(fd, ULONG_MAX); cntl->response_attachment().swap(portal); }