#!/usr/bin/perl while (<>) { if (/^Full thread dump/) { print "Found thread dump\n"; parse_thread_dump(); } } exit 0; sub parse_thread_dump { my $STATE_RUNNABLE = "runnable", $STATE_WAIT_MONITOR = "monitor wait", $STATE_WAIT_OBJECT = "object wait", $UNNAMED_THREAD="unnamed thread", $TIMER_THREAD="timer thread", $IDLE_THREAD="idle thread", $RESIN_THREAD="resin thread", $VM_THREAD="vm thread", $COMPILER_THREAD="compiler thread", $GC_THREAD="gc thread"; my %thread_state_count; $thread_state_count{$STATE_RUNNABLE} = 0; $thread_state_count{$STATE_WAIT_MONITOR} = 0; $thread_state_count{$STATE_WAIT_OBJECT} = 0; $thread_state_count{$UNNAMED_THREAD} = 0; $thread_state_count{$TIMER_THREAD} = 0; $thread_state_count{$IDLE_THREAD} = 0; $thread_state_count{$RESIN_THREAD} = 0; $thread_state_count{$VM_THREAD} = 0; $thread_state_count{$COMPILER_THREAD} = 0; $thread_state_count{$GC_THREAD} = 0; my $total_thread_count; my %runnable_method_count; my %monitor_method_count; my %object_method_count; my %unnamed_thread_count; my %timer_thread_count; my %idle_thread_count; my %resin_thread_count; my %vm_thread_count; my %compiler_thread_count; my %gc_thread_count; while (<>) { if (/^\"VM Periodic Task Thread/) { # print "found vm thread: $_"; $total_thread_count++; $thread_state = $VM_THREAD; $vm_thread_count{"vm thread"}++; $thread_state_count{$thread_state}++; last; } elsif (/^\"Thread-/) { # print "found unnamed thread: $_"; $total_thread_count++; $thread_state = $UNNAMED_THREAD; $unamed_thread_count{"unnamed thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"Timer-/) { # print "found timer thread: $_"; $total_thread_count++; $thread_state = $TIMER_THREAD; $timer_thread_count{"timer thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"resin-[0-9]/) { # print "found idle thread: $_"; $total_thread_count++; $thread_state = $IDLE_THREAD; $idle_thread_count{"idle thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"resin-[a-su-z]/) { # print "found resin thread: $_"; $total_thread_count++; $thread_state = $RESIN_THREAD; $resin_thread_count{"resin thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"resin-thread-/) { # print "found resin thread: $_"; $total_thread_count++; $thread_state = $RESIN_THREAD; $resin_thread_count{"resin thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"Low Memory Detector/) { # print "found vm thread: $_"; $total_thread_count++; $thread_state = $VM_THREAD; $resin_thread_count{"vm thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"AdapterThread/) { # print "found resin thread: $_"; $total_thread_count++; $thread_state = $RESIN_THREAD; $resin_thread_count{"resin thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"CompilerThread/) { # print "found compiler thread: $_"; $total_thread_count++; $thread_state = $COMPILER_THREAD; $compiler_thread_count{"compiler thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"main/) { # print "found resin thread: $_"; $total_thread_count++; $thread_state = $RESIN_THREAD; $resin_thread_count{"resin thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"Finalizer/) { # print "found vm thread: $_"; $total_thread_count++; $thread_state = $VM_THREAD; $vm_thread_count{"vm thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"Reference Handler/) { # print "found vm thread: $_"; $total_thread_count++; $thread_state = $VM_THREAD; $vm_thread_count{"vm thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"Signal Dispatcher/) { # print "found vm thread: $_"; $total_thread_count++; $thread_state = $VM_THREAD; $vm_thread_count{"vm thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"VM /) { # print "found vm thread: $_"; $total_thread_count++; $thread_state = $VM_THREAD; $vm_thread_count{"vm thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"GC /) { # print "found gc thread: $_"; $total_thread_count++; $thread_state = $GC_THREAD; $gc_thread_count{"gc thread"}++; $thread_state_count{$thread_state}++; } elsif (/^\"resin-tcp-/) { # print "found thread: $_"; $total_thread_count++; my $thread_state; # find thread state: running, waiting for monitor, or waiting for accept if (/in Object\.wait/) { $thread_state = $STATE_WAIT_OBJECT; while (<>) { if (!/Object\.wait/ && /at (.*$)/) { my $method_name = $1; $object_method_count{$method_name}++; } elsif (! /(at|waiting)/) { last; } } } elsif (/runnable/) { $thread_state = $STATE_RUNNABLE; while (<>) { if (/at (.*$)/) { my $method_name = $1; $runnable_method_count{$method_name}++; } last; } } elsif (/waiting for monitor entry/) { $thread_state = $STATE_WAIT_MONITOR; while (<>) { if (/at (.*$)/) { my $method_name = $1; $monitor_method_count{$method_name}++; } last; } } else { # unknown state next; } $thread_state_count{$thread_state}++; } elsif (/^\"/) { # print "found unnamed thread: $_"; $total_thread_count++; $thread_state = $UNNAMED_THREAD; $unamed_thread_count{"unnamed thread"}++; $thread_state_count{$thread_state}++; } } print " Total threads:\t" . $total_thread_count . "\n"; print " Thread status:\n"; foreach $key (keys(%thread_state_count)) { print "\t" . $key . "\t" . $thread_state_count{$key} . "\n"; } print " Methods blocked waiting for monitors:\n"; print_thread_list(\%monitor_method_count); print " Methods blocked in Object.wait():\n"; print_thread_list(\%object_method_count); print " Runnable methods:\n"; print_thread_list(\%runnable_method_count); print "\n"; } sub print_thread_list { my $map = shift; my %tmp_array = %$map; foreach $key (sort {$tmp_array{$b} <=> $tmp_array{$a}; } keys (%tmp_array)) { print "\t" . $map->{$key} . "\t" . $key . "\n"; } }