diff --git a/logstash-core/lib/logstash/util.rb b/logstash-core/lib/logstash/util.rb index e68ebb65a..614dcf1ea 100644 --- a/logstash-core/lib/logstash/util.rb +++ b/logstash-core/lib/logstash/util.rb @@ -35,14 +35,6 @@ module LogStash::Util Thread.current[:plugin] = plugin end - def self.get_thread_id(thread) - if RUBY_ENGINE == "jruby" - JRuby.reference(thread).native_thread.id - else - raise Exception.new("Native thread IDs aren't supported outside of JRuby") - end - end - def self.thread_info(thread) # When the `thread` is dead, `Thread#backtrace` returns `nil`; fall back to an empty array. backtrace = (thread.backtrace || []).map do |line| @@ -56,7 +48,7 @@ module LogStash::Util end { - "thread_id" => get_thread_id(thread), + "thread_id" => get_thread_id(thread), # might be nil for dead threads "name" => thread[:name], "plugin" => (thread[:plugin] ? thread[:plugin].debug_info : nil), "backtrace" => backtrace, diff --git a/logstash-core/src/main/java/org/logstash/RubyUtil.java b/logstash-core/src/main/java/org/logstash/RubyUtil.java index d760999a6..df207064f 100644 --- a/logstash-core/src/main/java/org/logstash/RubyUtil.java +++ b/logstash-core/src/main/java/org/logstash/RubyUtil.java @@ -55,6 +55,7 @@ import org.logstash.log.SlowLoggerExt; import org.logstash.plugins.HooksRegistryExt; import org.logstash.plugins.PluginFactoryExt; import org.logstash.plugins.UniversalPluginExt; +import org.logstash.util.UtilExt; import java.util.stream.Stream; @@ -308,6 +309,7 @@ public final class RubyUtil { NULL_TIMED_EXECUTION_CLASS.defineAnnotatedMethods(NullMetricExt.NullTimedExecution.class); NULL_COUNTER_CLASS.defineAnnotatedMethods(NullNamespacedMetricExt.NullCounter.class); UTIL_MODULE = LOGSTASH_MODULE.defineModuleUnder("Util"); + UTIL_MODULE.defineAnnotatedMethods(UtilExt.class); ABSTRACT_DLQ_WRITER_CLASS = UTIL_MODULE.defineClassUnder( "AbstractDeadLetterQueueWriterExt", RUBY.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR diff --git a/logstash-core/src/main/java/org/logstash/util/UtilExt.java b/logstash-core/src/main/java/org/logstash/util/UtilExt.java new file mode 100644 index 000000000..57bf0a310 --- /dev/null +++ b/logstash-core/src/main/java/org/logstash/util/UtilExt.java @@ -0,0 +1,23 @@ +package org.logstash.util; + +import org.jruby.RubyThread; +import org.jruby.anno.JRubyMethod; +import org.jruby.anno.JRubyModule; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; + +@JRubyModule(name = "Util") // LogStash::Util +public class UtilExt { + + @JRubyMethod(module = true) + public static IRubyObject get_thread_id(final ThreadContext context, IRubyObject self, IRubyObject thread) { + if (!(thread instanceof RubyThread)) { + throw context.runtime.newTypeError(thread, context.runtime.getThread()); + } + final Thread javaThread = ((RubyThread) thread).getNativeThread(); // weak-reference + // even if thread is dead the RubyThread instance might stick around while the Java thread + // instance already could have been garbage collected - let's return nil for dead meat : + return javaThread == null ? context.nil : context.runtime.newFixnum(javaThread.getId()); + } + +}