aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cholakian <andrew@andrewvc.com>2017-07-07 17:24:42 -0500
committerAndrew Cholakian <andrew@andrewvc.com>2017-07-24 16:38:18 +0000
commit18112832508dc8abf771806f08dfba9cf4c7b8a3 (patch)
tree3449ca6accd373d0e163d78d2191abf591b774b2
parentbff61d59feff97fac6e111dfa04765bc689d580a (diff)
Fix bug where hot threads did not work with duplicate names / add thread_id
The hot threads endpoint used to require thread names to be unique in a map and would crash otherwise. This patch fixes this by internally using a List instead of a Map to store these thread ids. Additionally, this patch adds the `thread_id` to the response to allow for disambiguation of of threads for any client applications. Fixes https://github.com/elastic/logstash/issues/7608 Fixes #7617
-rw-r--r--logstash-core/lib/logstash/api/commands/hot_threads_reporter.rb10
-rw-r--r--logstash-core/lib/logstash/util/thread_dump.rb7
-rw-r--r--logstash-core/locales/en.yml2
-rw-r--r--logstash-core/src/main/java/org/logstash/instrument/monitors/HotThreadsMonitor.java6
-rw-r--r--logstash-core/src/main/java/org/logstash/instrument/reports/ThreadsReport.java9
5 files changed, 23 insertions, 11 deletions
diff --git a/logstash-core/lib/logstash/api/commands/hot_threads_reporter.rb b/logstash-core/lib/logstash/api/commands/hot_threads_reporter.rb
index bd28e60a..384280b2 100644
--- a/logstash-core/lib/logstash/api/commands/hot_threads_reporter.rb
+++ b/logstash-core/lib/logstash/api/commands/hot_threads_reporter.rb
@@ -17,7 +17,12 @@ class HotThreadsReport
report << '=' * STRING_SEPARATOR_LENGTH
report << "\n"
hash[:threads].each do |thread|
- thread_report = "#{I18n.t("logstash.web_api.hot_threads.thread_title", :percent_of_cpu_time => thread[:percent_of_cpu_time], :thread_state => thread[:state], :thread_name => thread[:name])} \n"
+ line_str = I18n.t("logstash.web_api.hot_threads.thread_title",
+ :percent_of_cpu_time => thread[:percent_of_cpu_time],
+ :thread_state => thread[:state],
+ :thread_name => thread[:name],
+ :thread_id => thread[:thread_id])
+ thread_report = "#{line_str} \n"
thread_report << "#{thread[:path]}\n" if thread[:path]
thread[:traces].each do |trace|
thread_report << "\t#{trace}\n"
@@ -31,9 +36,10 @@ class HotThreadsReport
def to_hash
hash = { :time => Time.now.iso8601, :busiest_threads => @thread_dump.top_count, :threads => [] }
- @thread_dump.each do |thread_name, _hash|
+ @thread_dump.each do |_hash|
thread_name, thread_path = _hash["thread.name"].split(": ")
thread = { :name => thread_name,
+ :thread_id => _hash["thread.id"],
:percent_of_cpu_time => cpu_time_as_percent(_hash),
:state => _hash["thread.state"]
}
diff --git a/logstash-core/lib/logstash/util/thread_dump.rb b/logstash-core/lib/logstash/util/thread_dump.rb
index 800e6c06..b504f3a9 100644
--- a/logstash-core/lib/logstash/util/thread_dump.rb
+++ b/logstash-core/lib/logstash/util/thread_dump.rb
@@ -19,12 +19,13 @@ module LogStash
def each(&block)
i=0
- dump.each_pair do |thread_name, _hash|
+ dump.each do |hash|
+ thread_name = hash["thread.name"]
break if i >= top_count
if ignore
- next if idle_thread?(thread_name, _hash)
+ next if idle_thread?(thread_name, hash)
end
- block.call(thread_name, _hash)
+ block.call(hash)
i += 1
end
end
diff --git a/logstash-core/locales/en.yml b/logstash-core/locales/en.yml
index 3703c8e1..1f2a214f 100644
--- a/logstash-core/locales/en.yml
+++ b/logstash-core/locales/en.yml
@@ -81,7 +81,7 @@ en:
::: {%{hostname}}
Hot threads at %{time}, busiestThreads=%{top_count}:
thread_title: |-
- %{percent_of_cpu_time} % of cpu usage, state: %{thread_state}, thread name: '%{thread_name}'
+ %{percent_of_cpu_time} % of cpu usage, state: %{thread_state}, thread name: '%{thread_name}', thread id: %{thread_id}
logging:
unrecognized_option: |-
unrecognized option [%{option}]
diff --git a/logstash-core/src/main/java/org/logstash/instrument/monitors/HotThreadsMonitor.java b/logstash-core/src/main/java/org/logstash/instrument/monitors/HotThreadsMonitor.java
index d580239b..9e2572de 100644
--- a/logstash-core/src/main/java/org/logstash/instrument/monitors/HotThreadsMonitor.java
+++ b/logstash-core/src/main/java/org/logstash/instrument/monitors/HotThreadsMonitor.java
@@ -43,6 +43,7 @@ public final class HotThreadsMonitor {
private static final String THREAD_NAME = "thread.name";
private static final String THREAD_STATE = "thread.state";
private static final String THREAD_STACKTRACE = "thread.stacktrace";
+ private static final String THREAD_ID = "thread.id";
private Map<String, Object> map = new HashMap<>();
@@ -53,6 +54,7 @@ public final class HotThreadsMonitor {
map.put(WAITED_COUNT, info.getWaitedCount());
map.put(WAITED_TIME, info.getWaitedTime());
map.put(THREAD_NAME, info.getThreadName());
+ map.put(THREAD_ID, info.getThreadId());
map.put(THREAD_STATE, info.getThreadState().name().toLowerCase());
map.put(THREAD_STACKTRACE, stackTraceAsString(info.getStackTrace()));
}
@@ -71,6 +73,10 @@ public final class HotThreadsMonitor {
return (String) map.get(THREAD_NAME);
}
+ public long getThreadId() {
+ return (long) map.get(THREAD_ID);
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/logstash-core/src/main/java/org/logstash/instrument/reports/ThreadsReport.java b/logstash-core/src/main/java/org/logstash/instrument/reports/ThreadsReport.java
index 0d72a66d..25eac46e 100644
--- a/logstash-core/src/main/java/org/logstash/instrument/reports/ThreadsReport.java
+++ b/logstash-core/src/main/java/org/logstash/instrument/reports/ThreadsReport.java
@@ -21,13 +21,12 @@ public class ThreadsReport {
* stacktrace_size - max depth of stack trace
* @return A Map containing hot threads information
*/
- public static Map<String, Object> generate(Map<String, String> options) {
+ public static List<Map<String, Object>> generate(Map<String, String> options) {
List<HotThreadsMonitor.ThreadReport> reports = HotThreadsMonitor.detect(options);
return reports
.stream()
- .collect(Collectors
- .toMap(HotThreadsMonitor.ThreadReport::getThreadName,
- HotThreadsMonitor.ThreadReport::toMap));
+ .map(HotThreadsMonitor.ThreadReport::toMap)
+ .collect(Collectors.toList());
}
@@ -35,7 +34,7 @@ public class ThreadsReport {
* Generate a report with current Thread information
* @return A Map containing the hot threads information
*/
- public static Map<String, Object> generate() {
+ public static List<Map<String, Object>> generate() {
Map<String, String> options = new HashMap<>();
options.put("order_by", "cpu");
return generate(options);