提交 6784369b 编写于 作者: K Kohsuke Kawaguchi

Added a mechanism to obtain heap dump

上级 7c101d1e
......@@ -52,6 +52,9 @@ Upcoming changes</a>
Reduced the memory footprint used by fingerprints.
<li class=rfe>
Added a new extension point to support external login mechanisms.
<li class=rfe>
Heap dump of running Hudson instance can be obtained by requesting /heapDump from
the browser.
<li class=rfe>
MavenReporter#postExecute parameter Throwable error is always empty in case of mojo failure
(<a href="http://issues.hudson-ci.org/browse/HUDSON-8493">issue 8493</a>)
......
......@@ -2,7 +2,7 @@
* The MIT License
*
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi,
* Red Hat, Inc., Seiji Sogabe, Stephen Connolly, Thomas J. Black, Tom Huybrechts
* Red Hat, Inc., Seiji Sogabe, Stephen Connolly, Thomas J. Black, Tom Huybrechts, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
......@@ -25,10 +25,12 @@
package hudson.model;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Util;
import hudson.cli.declarative.CLIMethod;
import hudson.console.AnnotatedLargeText;
import hudson.model.Descriptor.FormException;
import hudson.model.Hudson.MasterComputer;
import hudson.model.queue.WorkUnit;
import hudson.node_monitors.NodeMonitor;
import hudson.remoting.Channel;
......@@ -48,6 +50,7 @@ import hudson.tasks.Publisher;
import hudson.util.DaemonThreadFactory;
import hudson.util.ExceptionCatchingThreadFactory;
import hudson.util.RemotingDiagnostics;
import hudson.util.RemotingDiagnostics.HeapDump;
import hudson.util.RunList;
import hudson.util.Futures;
import org.kohsuke.stapler.StaplerRequest;
......@@ -56,6 +59,7 @@ import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.HttpResponses;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.HttpRedirect;
import org.kohsuke.stapler.WebMethod;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
import org.kohsuke.args4j.Option;
......@@ -768,6 +772,13 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
return RemotingDiagnostics.getThreadDump(getChannel());
}
/**
* Obtains the heap dump.
*/
public HeapDump getHeapDump() throws IOException {
return new HeapDump(this,getChannel());
}
/**
* This method tries to compute the name of the host that's reachable by all the other nodes.
*
......
......@@ -3,7 +3,7 @@
*
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi,
* Erik Ramfelt, Koichi Fujikawa, Red Hat, Inc., Seiji Sogabe,
* Stephen Connolly, Tom Huybrechts, Yahoo! Inc., Alan Harder
* Stephen Connolly, Tom Huybrechts, Yahoo! Inc., Alan Harder, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
......@@ -121,6 +121,7 @@ import hudson.util.Iterators;
import hudson.util.Memoizer;
import hudson.util.MultipartFormDataParser;
import hudson.util.RemotingDiagnostics;
import hudson.util.RemotingDiagnostics.HeapDump;
import hudson.util.StreamTaskListener;
import hudson.util.TextFile;
import hudson.util.VersionNumber;
......@@ -166,6 +167,7 @@ import org.kohsuke.stapler.StaplerProxy;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.WebApp;
import org.kohsuke.stapler.WebMethod;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
import org.kohsuke.stapler.framework.adjunct.AdjunctManager;
......@@ -2567,14 +2569,14 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
bc.commit();
}
rsp.sendRedirect(req.getContextPath()+'/'); // go to the top page
rsp.sendRedirect(req.getContextPath() + '/'); // go to the top page
}
/**
* Accepts the new description.
*/
public synchronized void doSubmitDescription( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
getPrimaryView().doSubmitDescription(req,rsp);
getPrimaryView().doSubmitDescription(req, rsp);
}
/**
......@@ -2582,7 +2584,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* Use {@link #doQuietDown()} instead.
*/
public synchronized void doQuietDown(StaplerResponse rsp) throws IOException, ServletException {
doQuietDown().generateResponse(null,rsp,this);
doQuietDown().generateResponse(null, rsp, this);
}
public synchronized HttpRedirect doQuietDown() throws IOException {
......@@ -2637,7 +2639,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* @since 1.319
*/
public TopLevelItem createProjectFromXML(String name, InputStream xml) throws IOException {
return itemGroupMixIn.createProjectFromXML(name,xml);
return itemGroupMixIn.createProjectFromXML(name, xml);
}
/**
......@@ -2652,7 +2654,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
*/
@SuppressWarnings({"unchecked"})
public <T extends TopLevelItem> T copy(T src, String name) throws IOException {
return itemGroupMixIn.copy(src,name);
return itemGroupMixIn.copy(src, name);
}
// a little more convenient overloading that assumes the caller gives us the right type
......@@ -2765,7 +2767,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* Logs out the user.
*/
public void doLogout( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
securityRealm.doLogout(req,rsp);
securityRealm.doLogout(req, rsp);
}
/**
......@@ -2798,7 +2800,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
checkPermission(ADMINISTER);
// engage "loading ..." UI and then run the actual task in a separate thread
servletContext.setAttribute("app",new HudsonIsLoading());
servletContext.setAttribute("app", new HudsonIsLoading());
new Thread("Hudson config reload thread") {
@Override
......@@ -2823,7 +2825,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* Reloads the configuration synchronously.
*/
public void reload() throws IOException, InterruptedException, ReactorException {
executeReactor(null,loadTasks());
executeReactor(null, loadTasks());
User.reload();
servletContext.setAttribute("app", this);
}
......@@ -2856,6 +2858,13 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
rsp.getWriter().println("GCed");
}
/**
* Obtains the heap dump.
*/
public HeapDump getHeapDump() throws IOException {
return new HeapDump(this,MasterComputer.localChannel);
}
/**
* Simulates OutOfMemoryError.
* Useful to make sure OutOfMemoryHeapDump setting.
......@@ -2960,7 +2969,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
public void restart() throws RestartNotSupportedException {
final Lifecycle lifecycle = Lifecycle.get();
lifecycle.verifyRestartable(); // verify that Hudson is restartable
servletContext.setAttribute("app",new HudsonIsRestarting());
servletContext.setAttribute("app", new HudsonIsRestarting());
new Thread("restart thread") {
final String exitUser = getAuthentication().getName();
......@@ -3151,7 +3160,7 @@ public final class Hudson extends Node implements ItemGroup<TopLevelItem>, Stapl
* Sign up for the user account.
*/
public void doSignup( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
req.getView(getSecurityRealm(),"signup.jelly").forward(req,rsp);
req.getView(getSecurityRealm(), "signup.jelly").forward(req, rsp);
}
/**
......
/*
* The MIT License
*
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
......@@ -24,15 +24,25 @@
package hudson.util;
import groovy.lang.GroovyShell;
import hudson.FilePath;
import hudson.Functions;
import hudson.model.Hudson;
import hudson.remoting.Callable;
import hudson.remoting.VirtualChannel;
import hudson.remoting.DelegatingCallable;
import hudson.remoting.VirtualChannel;
import hudson.security.AccessControlled;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.WebMethod;
import javax.management.JMException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.util.Collections;
import java.util.LinkedHashMap;
......@@ -43,7 +53,7 @@ import java.util.TreeMap;
* Various remoting operations related to diagnostics.
*
* <p>
* These code are useful whereever {@link VirtualChannel} is used, such as master, slaves, Maven JVMs, etc.
* These code are useful wherever {@link VirtualChannel} is used, such as master, slaves, Maven JVMs, etc.
*
* @author Kohsuke Kawaguchi
* @since 1.175
......@@ -129,4 +139,65 @@ public final class RemotingDiagnostics {
return out.toString();
}
}
/**
* Obtains the heap dump in an HPROF file.
*/
public static FilePath getHeapDump(VirtualChannel channel) throws IOException, InterruptedException {
return channel.call(new Callable<FilePath, IOException>() {
public FilePath call() throws IOException {
final File hprof = File.createTempFile("hudson-heapdump", "hprof");
hprof.delete();
try {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
server.invoke(new ObjectName("com.sun.management:type=HotSpotDiagnostic"), "dumpHeap",
new Object[]{hprof.getAbsolutePath(), true}, new String[]{String.class.getName(), boolean.class.getName()});
return new FilePath(hprof);
} catch (JMException e) {
throw new IOException2(e);
}
}
private static final long serialVersionUID = 1L;
});
}
/**
* Heap dump, exposable to URL via Stapler.
*
*/
public static class HeapDump {
private final AccessControlled owner;
private final VirtualChannel channel;
public HeapDump(AccessControlled owner, VirtualChannel channel) {
this.owner = owner;
this.channel = channel;
}
/**
* Obtains the heap dump.
*/
public void doIndex(StaplerResponse rsp) throws IOException {
rsp.sendRedirect("heapdump.hprof");
}
@WebMethod(name="heapdump.hprof")
public void doHeapDump(StaplerRequest req, StaplerResponse rsp) throws IOException, InterruptedException {
owner.checkPermission(Hudson.ADMINISTER);
rsp.setContentType("application/octet-stream");
FilePath dump = obtain();
try {
dump.copyTo(rsp.getCompressedOutputStream(req));
} finally {
dump.delete();
}
}
public FilePath obtain() throws IOException, InterruptedException {
return RemotingDiagnostics.getHeapDump(channel);
}
}
}
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
......@@ -24,13 +24,16 @@
package hudson.maven;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.Hudson;
import hudson.remoting.Channel;
import hudson.util.RemotingDiagnostics;
import hudson.util.RemotingDiagnostics.HeapDump;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.WebMethod;
import javax.servlet.ServletException;
import java.io.IOException;
......@@ -112,4 +115,11 @@ public final class MavenProbeAction implements Action {
req.getView(this,"_script.jelly").forward(req,rsp);
}
/**
* Obtains the heap dump.
*/
public HeapDump getHeapDump() throws IOException {
return new HeapDump(owner,channel);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册