Module: RubyRunCommander__
- Included in:
- RubyRunMonitor__
- Defined in:
- lib/rubyrun/rubyrun_commander__.rb
Overview
—————————————————————–#
#
(C) Copyright Rubysophic Inc. 2007-2008 #
All rights reserved. #
#
Use, duplication or disclosure of the code is not permitted #
unless licensed. #
#
Last Updated: 7/18/08 #
—————————————————————–#
#
RubyRunCommander__ is a module which handles the commands # cmd_status, cmd_object_map, cmd_soft_kill and cmd_hard_kill #
#
—————————————————————–#
Instance Method Summary collapse
-
#dump_object_map ⇒ Object
Show the top 20 Ruby classes which have the largest no.
-
#dump_reports(dump_all_reports = false) ⇒ Object
Dump Controller/Actions response time metrics metrics structure metrics Thread ID metrics Timestamp of the request metrics URL metrics Controller name metrics Action name metrics Response time metrics Action time metrics Database IO time metrics View time metrics Uncaptured time metrics Dispatch wait time.
-
#dump_thread_status ⇒ Object
Use Thread.list to list show thread status, and native code to display the last line # and function of the threads.
-
#exit_monitor? ⇒ Boolean
If exists, indicate to the monitor thread to exit.
-
#hard_kill? ⇒ Boolean
If exists, indicate to the monitor thread that a hard kill (kill all threads including the main thread) command is sent.
-
#kill_threads(monitor_thr) ⇒ Object
The way to do soft/hard kill is to performa a thr.raise on the thread from the thread monitor.
-
#object_map? ⇒ Boolean
If exists, indicate to the montior thread that a object map is requested.
-
#remove_cmd_folder ⇒ Object
Remove the cmd_kill-3 folder or file if any.
-
#return_joined_thread(th_data_hash) ⇒ Object
If a thread is joined this method returns the joining thread ID.
-
#soft_kill? ⇒ Boolean
If exists, indicate to the monitor thread that a soft kill (kill all threads except the main thread) command is sent.
-
#thread_status? ⇒ Boolean
If exists, indicate to the monitor thread that a thread status report is requested.
-
#unsupport_function ⇒ Object
Log if native library can’t be loaded or not found.
-
#update_perf_metrics(controller, action_metrics_hash) ⇒ Object
metrics hash is a global collection point for all metrics (averaged) for all actions by controller Use serialization before updating this global hash Structure of $rubyrun_metrics_hash: controller_name => => [response_time, action_time, db_io_time, view_time, uncaptured_time, dispatch_wait_time, request_count].
Instance Method Details
#dump_object_map ⇒ Object
Show the top 20 Ruby classes which have the largest no. of instances in memory The snapshot is taken after a gc call is made
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 105 def dump_object_map start_time = Time.now $rubyrun_obj_map_reporter = RubyRunHTMLWriter.new($rubyrun_report_folder + '/' + $rubyrun_file_basename + '_' + $rubyrun_startup_id + '_object_map.html', nil, shift_age = 10, shift_size = 4096000) unless $rubyrun_obj_map_reporter object_map = Hash.new ttl_object = 0 ObjectSpace.garbage_collect ObjectSpace.each_object { |obj| ttl_object += 1 object_map.has_key?(obj.class) ? object_map[obj.class] += 1 : object_map[obj.class] = 1 } results = object_map.sort{|a,b| a[1]<=>b[1]}.reverse! table_content = '' odd_row ||=true 20.times {|i| table_content += sprintf("#{odd_row ? OBJ_MAP_ODD_ROW : OBJ_MAP_EVEN_ROW}", results[i][0], results[i][1].to_s) odd_row = !odd_row } html_content = OBJ_MAP_HTML.sub(/%START_TIMESTAMP%/,start_time.strftime("%H:%M:%S %m/%d/%Y")) html_content.sub!(/%OBJ_MAP_ROW%/,table_content) $rubyrun_obj_map_reporter.info(html_content) end |
#dump_reports(dump_all_reports = false) ⇒ Object
Dump Controller/Actions response time metrics metrics structure metrics Thread ID metrics Timestamp of the request metrics URL metrics Controller name metrics Action name metrics Response time metrics Action time metrics Database IO time metrics View time metrics Uncaptured time metrics Dispatch wait time
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 46 def dump_reports(dump_all_reports = false) buffer = return_and_switch_buffer buffer.each { |metrics| # Last element is 1, representing a request count of 1, used for calculating average response time for this controller/action update_perf_metrics(metrics[3], {metrics[4] => [metrics[5],metrics[6],metrics[7],metrics[8],metrics[9],metrics[10],1]}) } @rubyrun_req_count ||= 0 @rubyrun_req_count += buffer.length if $rubyrun_config['OUTPUT'].include?(RUBYRUN_OUTPUT_PERF_SUMMARY) create_rss_channels if (!$rubyrun_perf_summary_rss && $rubyrun_rails_env) if dump_all_reports add_perf_summary_rss_item(@rubyrun_req_count) @rubyrun_req_count = 0 end end if $rubyrun_config['OUTPUT'].include?(RUBYRUN_OUTPUT_TXN_LOG) create_csv_files unless $rubyrun_txn_log_reporter add_txn_log_csv_item(buffer) end buffer.clear # Clear the buffer so that the main thread will push the data into a blank bucket end |
#dump_thread_status ⇒ Object
Use Thread.list to list show thread status, and native code to display the last line # and function of the threads
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 20 def dump_thread_status (unsupport_function; return) unless $rubyrun_native $rubyrun_thread_status_reporter = RubyRunHTMLWriter.new($rubyrun_report_folder + '/' + $rubyrun_file_basename + '_' + $rubyrun_startup_id + '_thread_status.html', nil, shift_age = 10, shift_size = 4096000) unless $rubyrun_thread_status_reporter start_time = Time.now th_data_hash = RubyRunNative__.get_all_top_stacks odd_row ||= true table_content = '' Thread.list.each {|th| thread_id = get_thread_id(th) table_content += sprintf("#{odd_row ? THREAD_STATUS_ODD_ROW : THREAD_STATUS_EVEN_ROW}", thread_id, th.status, get_top_stack(th_data_hash, thread_id)) odd_row = !odd_row } html_content = THREAD_STATUS_HTML.sub(/%START_TIMESTAMP%/,start_time.strftime("%H:%M:%S %m/%d/%Y")) html_content.sub!(/%THREAD_STATUS_ROW%/,table_content) $rubyrun_thread_status_reporter.info(html_content) end |
#exit_monitor? ⇒ Boolean
If exists, indicate to the monitor thread to exit
189 190 191 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 189 def exit_monitor? File.exists?($rubyrun_working_dir + RUBYRUN_CMD_EXIT) end |
#hard_kill? ⇒ Boolean
If exists, indicate to the monitor thread that a hard kill (kill all threads including the main thread) command is sent
179 180 181 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 179 def hard_kill? File.exists?($rubyrun_working_dir + RUBYRUN_CMD_HARD_KILL + '_' + Process.pid.to_s) end |
#kill_threads(monitor_thr) ⇒ Object
The way to do soft/hard kill is to performa a thr.raise on the thread from the thread monitor. Using the begin/rescue created around the block in Thread.new by RubyRunInstrumentor__, the raise will be rescued and $@ is then extracted to a global hash. Softkill only kills non-main threads. Hardkill kills the main thread also but as the last step.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 74 def kill_threads(monitor_thr) (unsupport_function; return) unless $rubyrun_native if !$rubyrun_thread_dump_reporter $rubyrun_thread_dump_reporter = Logger.new($rubyrun_report_folder + '/' + $rubyrun_file_basename + '_' + $rubyrun_startup_id + '_thread_dump.txt', shift_age = 10, shift_size = 4096000) $rubyrun_thread_dump_reporter.level = Logger::INFO class << $rubyrun_thread_dump_reporter include RubyRunUtils__ def (severity, , progname, msg) "[#{.strftime("%Y-%m-%d %H:%M:%S")}.#{("%.3f" % .to_f).split('.')[1]}] #{get_thread_id} #{msg}\n" end end end th_data_hash = RubyRunNative__.get_all_top_stacks j_th_id = return_joined_thread(th_data_hash) Thread.list.each {|th| th_id = get_thread_id(th) if th.status == 'sleep' && th_id != get_thread_id && th_id != get_thread_id(monitor_thr) && th_id != get_thread_id(Thread.main) && th_id != j_th_id $rubyrun_thread_dump_reporter.info "*** Raising exception #{RUBYRUN_KILL_3_STRING} to #{get_thread_id(th)} ***" th.raise ThreadError, RUBYRUN_KILL_3_STRING end } sleep 3 back_trace_all(th_data_hash) hard_kill = hard_kill? remove_cmd_folder Thread.main.raise ThreadError, RUBYRUN_KILL_3_STRING if hard_kill end |
#object_map? ⇒ Boolean
If exists, indicate to the montior thread that a object map is requested
184 185 186 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 184 def object_map? File.exists?($rubyrun_working_dir + RUBYRUN_CMD_OBJECT_MAP) end |
#remove_cmd_folder ⇒ Object
Remove the cmd_kill-3 folder or file if any
157 158 159 160 161 162 163 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 157 def remove_cmd_folder [RUBYRUN_CMD_SOFT_KILL, RUBYRUN_CMD_HARD_KILL].each { |cmd| path = $rubyrun_working_dir + cmd + '_' + Process.pid.to_s next unless File.exist?(path) File.directory?(path) ? Dir.delete(path) : File.delete(path) } end |
#return_joined_thread(th_data_hash) ⇒ Object
If a thread is joined this method returns the joining thread ID
147 148 149 150 151 152 153 154 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 147 def return_joined_thread(th_data_hash) th_data_hash.each {|th, top_stack| if th.to_s.include?(get_thread_id(Thread.main)) top_stack[0] =~ /\*\*(.+?)\*\*/ return $1 end } end |
#soft_kill? ⇒ Boolean
If exists, indicate to the monitor thread that a soft kill (kill all threads except the main thread) command is sent
173 174 175 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 173 def soft_kill? File.exists?($rubyrun_working_dir + RUBYRUN_CMD_SOFT_KILL + '_' + Process.pid.to_s) end |
#thread_status? ⇒ Boolean
If exists, indicate to the monitor thread that a thread status report is requested
167 168 169 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 167 def thread_status? File.exists?($rubyrun_working_dir + RUBYRUN_CMD_STATUS) end |
#unsupport_function ⇒ Object
Log if native library can’t be loaded or not found
194 195 196 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 194 def unsupport_function $rubyrun_logger.info "Native library not available. Function not supported." end |
#update_perf_metrics(controller, action_metrics_hash) ⇒ Object
metrics hash is a global collection point for all metrics (averaged) for all actions by controller Use serialization before updating this global hash Structure of $rubyrun_metrics_hash: controller_name => => [response_time, action_time,
db_io_time, view_time,
uncaptured_time, dispatch_wait_time,
request_count]
136 137 138 139 140 141 142 143 144 |
# File 'lib/rubyrun/rubyrun_commander__.rb', line 136 def update_perf_metrics(controller, action_metrics_hash) $rubyrun_metrics_hash[controller].merge!(action_metrics_hash) {|action, o_metrics, new_metrics| o_metrics.each_index { |x| (o_metrics[x] += new_metrics[x]; break) if x == (o_metrics.length-1) # Calculate the total request count for this controller/action o_metrics[x] = (o_metrics[x] * o_metrics.last + new_metrics[x])/(o_metrics.last + new_metrics.last).to_f } o_metrics } end |