package jetbrains.buildServer.profile; import java.io.File; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jetbrains.buildServer.controllers.ActionErrors; import jetbrains.buildServer.controllers.AjaxRequestProcessor; import jetbrains.buildServer.controllers.BaseController; import jetbrains.buildServer.serverSide.SBuildServer; import jetbrains.buildServer.util.FileUtil; import jetbrains.buildServer.util.StringUtil; import jetbrains.buildServer.web.openapi.WebControllerManager; import jetbrains.buildServer.web.openapi.WebResourcesManager; import jetbrains.buildServer.log.Loggers; import jetbrains.buildServer.version.ServerVersionHolder; import jetbrains.buildServer.version.ServerVersionInfo; import jetbrains.buildServer.util.PropertiesUtil; import org.jdom.Element; import org.jetbrains.annotations.Nullable; import org.springframework.web.servlet.ModelAndView; public class ProfilerController extends BaseController { private final Profiler myProfiler; public ProfilerController(final SBuildServer server, WebControllerManager manager, Profiler profiler, WebResourcesManager webResources) { super(server); myProfiler = profiler; manager.registerController("/profiler.html", this); //in TeamCity < 4.x EAP we need to register plugin resources automatically. final ServerVersionInfo serverVersionInfo = ServerVersionHolder.getVersion(); if (serverVersionInfo.getDisplayVersionMajor()<4){ webResources.addPluginResources("serverProfile", "serverProfile.jar"); } } @Nullable protected ModelAndView doHandle(final HttpServletRequest request, final HttpServletResponse response) throws Exception { new AjaxRequestProcessor().processRequest(request, response, new AjaxRequestProcessor.RequestHandler() { public void handleRequest(final HttpServletRequest request, final HttpServletResponse response, final Element xmlResponse) { try { doAction(request); } catch (Exception e) { Loggers.SERVER.warn(e.getMessage()); Loggers.SERVER.debug(e); ActionErrors errors = new ActionErrors(); errors.addError("profilerProblem", getMessageWithNested(e)); errors.serialize(xmlResponse); } } }); return null; } static private String getMessageWithNested(Throwable e) { String result = e.getMessage(); Throwable cause = e.getCause(); if (cause != null) { result += " Caused by: " + getMessageWithNested(cause); } return result; } private void doAction(final HttpServletRequest request) throws Exception { String j2eeProfilingEnabledParameter = request.getParameter("j2eeProfilingEnabled"); myProfiler.getSettings().setJ2eeCPUProfilingEnabled(PropertiesUtil.getBoolean(j2eeProfilingEnabledParameter)); String action = request.getParameter("profilerAction"); if ("StartCpu".equals(action)) { myProfiler.startProfiler(); } else if ("CaptureCPU".equals(action)) { try { String result = myProfiler.captureAndStop(); addSuccessMessage(request, "CPU snapshot is saved to the file on the server: \"" + result + "\"" + getFileSizeString(result)); } catch (Exception e) { throw new Exception("Cannot capture CPU snapshot.", e); } } else if ("StopCPU".equals(action)) { myProfiler.stopProfiler(); } else if ("CaptureMemory".equals(action)) { try { String result = myProfiler.captureMemorySnapshot(); addSuccessMessage(request, "Memory snapshot is saved to the file on the server: \"" + result + "\"" + getFileSizeString(result)); } catch (Exception e) { throw new Exception("Cannot capture memory snapshot.", e); } } } private String getFileSizeString(final String fileName) { try { return " (" + StringUtil.formatFileSize(new File(fileName).length()) + ")"; } catch (Exception e) { return ""; } } private void addSuccessMessage(HttpServletRequest request, String result) { if (result != null) { getOrCreateMessages(request).addMessage("profilerMessage", result); } } }