如何在heroku上为Java进程生成线程转储?

时间:2013-05-11 20:28:53

标签: java heroku

我希望能够为在heroku上运行的Java应用程序生成java线程转储吗?我看到heroku运行jstack但我无法弄清楚如何运行它来在我的进程上生成一个线程转储。我无法弄清楚如何让PID发送到jstack。一旦我有PID,我只需从我的开发机器运行“heroku jstack -l”(它安装了工具带)?

3 个答案:

答案 0 :(得分:4)

好的,这是最好的方法。这将为您提供JVM使用的格式,而不必以编程方式重新创建它。再次,这是针对heroku,其他环境将需要调整此代码。这将它暴露为休息界面。

@GET
@Transactional
@Path( "/threaddump" )
public Response threadDump() throws Exception {
    dumpThreads();
    return Response.ok().build();
}

public static void dumpThreads() throws Exception {
    ProcessBuilder processBuilder = new ProcessBuilder( "/bin/sh", "-c", "kill -3 $PPID" );
    processBuilder.redirectErrorStream( true );
    Process process = processBuilder.start();
    InputStream inputStream = process.getInputStream();
    StreamUtils.copy( inputStream, System.out );
}

答案 1 :(得分:0)

您可以尝试以下操作 - 将此功能放在某个类中并有办法调用它,将输出保存到文件或在页面上显示...

static StringBuilder allStack() {
    StringBuilder sb = new StringBuilder();
    Map<Thread, StackTraceElement[]> trace = Thread.getAllStackTraces();
    for(Thread t:trace.keySet()){
        StackTraceElement[]trc = trace.get(t);
        sb.append("\n");
        sb.append(t.getName());
        sb.append(" ");         
        sb.append(t.getId());

        sb.append(" |");            
        sb.append(t.getThreadGroup());

        sb.append("| ");            
        sb.append(t);
        sb.append(" :-\n");
        for(StackTraceElement e:trc){
            sb.append(e.toString());
            sb.append("\n");
        }
        sb.append(" -***-\n");
    }
    return sb;
}

答案 2 :(得分:0)

您还可以考虑将REST API嵌入到Java JMX中以执行此线程转储。 Jolokia似乎是一个很好的候选人。它还将支持内置身份验证,并且更灵活,因为您可以访问任何JMX mbean而无需实现新的REST端点

请参阅 http://www.jolokia.org,特别是使用ThreadMXBean.dumpAllThreads()

调用POST Exec request方法的REST协议