Line data Source code
1 : #include "source/server/admin/profiling_handler.h" 2 : 3 : #include "source/common/profiler/profiler.h" 4 : #include "source/server/admin/utils.h" 5 : 6 : namespace Envoy { 7 : namespace Server { 8 : 9 134 : ProfilingHandler::ProfilingHandler(const std::string& profile_path) : profile_path_(profile_path) {} 10 : 11 : Http::Code ProfilingHandler::handlerCpuProfiler(Http::ResponseHeaderMap&, 12 : Buffer::Instance& response, 13 0 : AdminStream& admin_stream) { 14 0 : Http::Utility::QueryParamsMulti query_params = admin_stream.queryParams(); 15 0 : const auto enableVal = query_params.getFirstValue("enable"); 16 0 : if (query_params.data().size() != 1 || !enableVal.has_value() || 17 0 : (enableVal.value() != "y" && enableVal.value() != "n")) { 18 0 : response.add("?enable=<y|n>\n"); 19 0 : return Http::Code::BadRequest; 20 0 : } 21 : 22 0 : bool enable = enableVal.value() == "y"; 23 0 : if (enable && !Profiler::Cpu::profilerEnabled()) { 24 0 : if (!Profiler::Cpu::startProfiler(profile_path_)) { 25 0 : response.add("failure to start the profiler"); 26 0 : return Http::Code::InternalServerError; 27 0 : } 28 : 29 0 : } else if (!enable && Profiler::Cpu::profilerEnabled()) { 30 0 : Profiler::Cpu::stopProfiler(); 31 0 : } 32 : 33 0 : response.add("OK\n"); 34 0 : return Http::Code::OK; 35 0 : } 36 : 37 : Http::Code ProfilingHandler::handlerHeapProfiler(Http::ResponseHeaderMap&, 38 : Buffer::Instance& response, 39 0 : AdminStream& admin_stream) { 40 0 : if (!Profiler::Heap::profilerEnabled()) { 41 0 : response.add("The current build does not support heap profiler"); 42 0 : return Http::Code::NotImplemented; 43 0 : } 44 : 45 0 : Http::Utility::QueryParamsMulti query_params = admin_stream.queryParams(); 46 0 : const auto enableVal = query_params.getFirstValue("enable"); 47 0 : if (query_params.data().size() != 1 || !enableVal.has_value() || 48 0 : (enableVal.value() != "y" && enableVal.value() != "n")) { 49 0 : response.add("?enable=<y|n>\n"); 50 0 : return Http::Code::BadRequest; 51 0 : } 52 : 53 0 : Http::Code res = Http::Code::OK; 54 0 : bool enable = enableVal.value() == "y"; 55 0 : if (enable) { 56 0 : if (Profiler::Heap::isProfilerStarted()) { 57 0 : response.add("Fail to start heap profiler: already started"); 58 0 : res = Http::Code::BadRequest; 59 0 : } else if (!Profiler::Heap::startProfiler(profile_path_)) { 60 0 : response.add("Fail to start the heap profiler"); 61 0 : res = Http::Code::InternalServerError; 62 0 : } else { 63 0 : response.add("Starting heap profiler"); 64 0 : res = Http::Code::OK; 65 0 : } 66 0 : } else { 67 : // !enable 68 0 : if (!Profiler::Heap::isProfilerStarted()) { 69 0 : response.add("Fail to stop heap profiler: not started"); 70 0 : res = Http::Code::BadRequest; 71 0 : } else { 72 0 : Profiler::Heap::stopProfiler(); 73 0 : response.add( 74 0 : fmt::format("Heap profiler stopped and data written to {}. See " 75 0 : "http://goog-perftools.sourceforge.net/doc/heap_profiler.html for details.", 76 0 : profile_path_)); 77 0 : res = Http::Code::OK; 78 0 : } 79 0 : } 80 0 : return res; 81 0 : } 82 : 83 : Http::Code TcmallocProfilingHandler::handlerHeapDump(Http::ResponseHeaderMap&, 84 0 : Buffer::Instance& response, AdminStream&) { 85 0 : auto dump_result = Profiler::TcmallocProfiler::tcmallocHeapProfile(); 86 : 87 0 : if (dump_result.ok()) { 88 0 : response.add(dump_result.value()); 89 0 : return Http::Code::OK; 90 0 : } 91 : 92 0 : response.add(dump_result.status().message()); 93 0 : return Http::Code::NotImplemented; 94 0 : } 95 : 96 : } // namespace Server 97 : } // namespace Envoy