Skip to content
Merged
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ project(":logstash-core") {
tasks.getByPath(":logstash-core:" + tsk).configure {
dependsOn copyPluginTestAlias
dependsOn installDevelopmentGems
dependsOn installDefaultGems
}
}
}
Expand Down Expand Up @@ -1008,6 +1009,7 @@ if (System.getenv('OSS') != 'true') {
["rubyTests", "rubyIntegrationTests", "test"].each { tsk ->
tasks.getByPath(":logstash-xpack:" + tsk).configure {
dependsOn installDevelopmentGems
dependsOn installDefaultGems
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions lib/bootstrap/rspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@

require_relative "environment"
LogStash::Bundler.setup!({:without => [:build]})
Copy link
Member Author

@donoghuc donoghuc Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsvd this is a good summary of what I found out today after our conversation.

More context on this particular change...

I was debugging the following faiures:

2025-11-04 16:40:59 PST | Failed examples:
  | 2025-11-04 16:40:59 PST |  
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/plugin_manager/gem_installer_spec.rb:48 # LogStash::PluginManager::GemInstaller install the gem in the gems dir
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/plugin_manager/gem_installer_spec.rb:41 # LogStash::PluginManager::GemInstaller install the specifications in the spec dir
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/plugin_manager/gem_installer_spec.rb:75 # LogStash::PluginManager::GemInstaller post_install_message when not present when we don't want the message doesn't display the message
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/plugin_manager/gem_installer_spec.rb:67 # LogStash::PluginManager::GemInstaller post_install_message when present when we dont want the message doesn't display the message
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/plugin_manager/gem_installer_spec.rb:61 # LogStash::PluginManager::GemInstaller post_install_message when present when we want the message display the message
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/bootstrap/bundler_spec.rb:159 # LogStash::Bundler when generating bundler arguments when updating level: patch invokes bundler with --minor
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/bootstrap/bundler_spec.rb:145 # LogStash::Bundler when generating bundler arguments when updating level: major invokes bundler with --minor
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/bootstrap/bundler_spec.rb:131 # LogStash::Bundler when generating bundler arguments when updating with a specific plugin should call `bundle update plugin-name`
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/bootstrap/bundler_spec.rb:165 # LogStash::Bundler when generating bundler arguments when updating level: unspecified invokes bundler with --minor
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/bootstrap/bundler_spec.rb:137 # LogStash::Bundler when generating bundler arguments when updating with the cleaning option should ignore the clean option
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/bootstrap/bundler_spec.rb:152 # LogStash::Bundler when generating bundler arguments when updating level: minor invokes bundler with --minor
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/bootstrap/bundler_spec.rb:174 # LogStash::Bundler when generating bundler arguments when updating with ecs_compatibility also update dependencies
  | 2025-11-04 16:40:59 PST | rspec ./spec/unit/bootstrap/bundler_spec.rb:185 # LogStash::Bundler when generating bundler arguments when updating with ecs_compatibility do not include core lib
  | 2025-11-04 16:40:59 PST |  

Which all failed with a message similar to:

2025-11-04 16:40:59 PST |  
-- | --
  | 2025-11-04 16:40:59 PST | 13) LogStash::Bundler when generating bundler arguments when updating with ecs_compatibility do not include core lib
  | 2025-11-04 16:40:59 PST | Failure/Error: new_specs, errors = ::Gem::SpecFetcher.fetcher.spec_for_dependency(dep)
  | 2025-11-04 16:40:59 PST |  
  | 2025-11-04 16:40:59 PST | SyntaxError:
  | 2025-11-04 16:40:59 PST | /buildkite/builds/bk-agent-prod-k8s-1762302466884143578/elastic/logstash-pull-request-pipeline/vendor/bundle/jruby/3.1.0/gems/psych-5.2.6-java/lib/psych/class_loader.rb:41: syntax error, unexpected constant
  | 2025-11-04 16:40:59 PST | ...omplex, "Exception"=>Exception, "Object"=>Object, "Date"=>Da...
  | 2025-11-04 16:40:59 PST | ^~~~~~~~~
  | 2025-11-04 16:40:59 PST | # ./vendor/bundle/jruby/3.1.0/gems/psych-5.2.6-java/lib/psych/class_loader.rb:40:in `block in ClassLoader'
  | 2025-11-04 16:40:59 PST | # ./vendor/bundle/jruby/3.1.0/gems/psych-5.2.6-java/lib/psych/class_loader.rb:37:in `<class:ClassLoader>'
  | 2025-11-04 16:40:59 PST | # ./vendor/bundle/jruby/3.1.0/gems/psych-5.2.6-java/lib/psych/class_loader.rb:6:in `<module:Psych>'
  | 2025-11-04 16:40:59 PST | # ./vendor/bundle/jruby/3.1.0/gems/psych-5.2.6-java/lib/psych/class_loader.rb:5:in `<main>'
  | 2025-11-04 16:40:59 PST | # ./vendor/bundle/jruby/3.1.0/gems/psych-5.2.6-java/lib/psych/nodes/node.rb:2:in `<main>'
  | 2025-11-04 16:40:59 PST | # ./vendor/bundle/jruby/3.1.0/gems/psych-5.2.6-java/lib/psych/nodes.rb:2:in `<main>'
  | 2025-11-04 16:40:59 PST | # ./vendor/bundle/jruby/3.1.0/gems/psych-5.2.6-java/lib/psych.rb:17:in `<main>'
  | 2025-11-04 16:40:59 PST | # ./lib/bootstrap/bundler.rb:265:in `fetch_plugin_dependencies'
  | 2025-11-04 16:40:59 PST | # ./lib/bootstrap/bundler.rb:250:in `block in expand_logstash_mixin_dependencies'
  | 2025-11-04 16:40:59 PST | # ./lib/bootstrap/bundler.rb:250:in `expand_logstash_mixin_dependencies'
  | 2025-11-04 16:40:59 PST | # ./lib/bootstrap/bundler.rb:293:in `bundler_arguments'
  | 2025-11-04 16:40:59 PST | # ./spec/unit/bootstrap/bundler_spec.rb:109:in `block in <main>'
  | 2025-11-04 16:40:59 PST | # ./spec/unit/bootstrap/bundler_spec.rb:186:in `block in <main>'
  | 2025-11-04 16:40:59 PST | # ./vendor/bundle/jruby/3.1.0/gems/webmock-3.26.1/lib/webmock/rspec.rb:39:in `block in <main>'
  | 2025-11-04 16:40:59 PST | # ./spec/spec_helper.rb:84:in `block in <main>'
  | 2025-11-04 16:40:59 PST | # ./logstash-core/lib/logstash/util.rb:43:in `set_thread_name'
  | 2025-11-04 16:40:59 PST | # ./spec/spec_helper.rb:83:in `block in <main>'
  | 2025-11-04 16:40:59 PST | # ./spec/spec_helper.rb:76:in `block in <main>'
  | 2025-11-04 16:40:59 PST | # ./vendor/bundle/jruby/3.1.0/gems/logstash-devutils-2.6.3-java/lib/logstash/devutils/rspec/spec_helper.rb:47:in `block in <main>'
  | 2025-11-04 16:40:59 PST | # ./lib/bootstrap/rspec.rb:36:in `<main>'

Clearly indicating an issue with they pysch stdlib gemspec removal. I was very curious why this was not an issue in artifacts prepared with the gem cleanup. After investigating our complex set of manipulations of GEM_HOME and GEM_PATH across cli entrypoints and tests I finally just started printing out LOAD_PATH. In a container, when we do something like a logstash-plugin update we get a LOAD_PATH at execution time like:

/usr/share/logstash/logstash-core/lib
/usr/share/logstash/logstash-core-plugin-api/lib
/usr/share/logstash/lib
/usr/share/logstash/vendor/bundle/jruby/3.1.0/gems/clamp-1.3.3/lib
/usr/share/logstash/vendor/bundle/jruby/3.1.0/gems/rubyzip-1.3.0/lib
/usr/share/logstash/vendor/bundle/jruby/3.1.0/gems/stud-0.0.23/lib
/usr/share/logstash/vendor/bundle/jruby/3.1.0/gems/stud-0.0.23/lib
/usr/share/logstash/vendor/bundle/jruby/3.1.0/gems/ruby-progressbar-1.13.0/lib
/usr/share/logstash/vendor/bundle/jruby/3.1.0/gems/cgi-0.3.7-java/lib
/usr/share/logstash/vendor/bundle/jruby/3.1.0/gems/cgi-0.3.7-java/ext/java/org/jruby/ext/cgi/escape/lib
/usr/share/logstash/vendor/bundle/jruby/3.1.0/gems/date-3.3.3-java/lib
/usr/share/logstash/vendor/bundle/jruby/3.1.0/gems/gem_publisher-1.5.0/lib
/usr/share/logstash/vendor/jruby/lib/ruby/3.1/site_ruby
/usr/share/logstash/vendor/jruby/lib/ruby/stdlib

For that same bit in the ruby unit tests we get a LOAD_PATH like:

/Users/cas/elastic-repos/logstash/x-pack/lib
/Users/cas/elastic-repos/logstash/lib
/Users/cas/elastic-repos/logstash/logstash-core/spec
/Users/cas/elastic-repos/logstash/spec
/Users/cas/elastic-repos/logstash/logstash-core/lib
/Users/cas/elastic-repos/logstash/logstash-core-plugin-api/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/webmock-3.26.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/timecop-0.9.10/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/snappy-0.4.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/snappy-jars-1.1.0.1.2-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/simplecov-json-0.2.3/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/simplecov-0.22.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/simplecov_json_formatter-0.1.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/simplecov-html-0.13.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rumbster-1.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/ruby-kafka-1.5.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rubocop-1.74.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/unicode-display_width-3.2.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/unicode-emoji-4.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/ruby-progressbar-1.13.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rubocop-ast-1.42.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rspec-sequencing-0.1.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rspec-collection_matchers-1.2.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/regexp_parser-2.11.3/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/random-port-0.7.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/tago-0.4.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rainbow-3.1.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rackup-2.0.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/webrick-1.9.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rack-test-2.2.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/pleaserun-0.0.33/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/pleaserun-0.0.33/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/parser-3.3.10.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/parallel-1.27.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/paquet-0.2.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-webhdfs-3.1.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-webhdfs-3.1.0-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/webhdfs-0.11.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-udp-3.2.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-tcp-7.0.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-stdout-3.1.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-redis-5.2.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-pipe-3.0.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-null-3.0.5/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-nagios-3.0.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-lumberjack-3.1.9/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-http-6.0.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-graphite-3.1.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-email-4.1.3/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/mustache-0.99.8/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/mail-2.9.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/net-smtp-0.5.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/net-pop-0.1.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/net-imap-0.5.12/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/net-protocol-0.2.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/timeout-0.4.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/mini_mime-1.1.5/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-elasticsearch-12.1.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-csv-3.0.11/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-output-file-4.3.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-integration-snmp-4.2.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-integration-snmp-4.2.0-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-integration-rabbitmq-7.4.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/march_hare-4.8.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-integration-logstash-1.0.4-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-integration-logstash-1.0.4-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-integration-kafka-12.0.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-integration-kafka-12.0.1-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-integration-jdbc-5.6.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-integration-jdbc-5.6.1/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/sequel-5.98.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-integration-aws-7.2.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-integration-aws-7.2.1-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-unix-3.1.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-udp-3.5.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-twitter-4.1.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/twitter-6.2.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/simple_oauth-0.3.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/naught-1.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/multipart-post-2.4.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/memoizable-0.4.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-syslog-3.7.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-stdin-3.4.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-redis-3.7.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/redis-4.8.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-pipe-3.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-jms-3.3.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-http_poller-6.0.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-heartbeat-3.1.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-graphite-3.0.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-tcp-7.0.3-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-tcp-7.0.3-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-generator-3.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-gelf-3.3.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-ganglia-3.1.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-file-4.4.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-exec-3.6.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-elasticsearch-5.2.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-elastic_serverless_forwarder-2.0.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-elastic_serverless_forwarder-2.0.0-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-http-4.1.3-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-http-4.1.3-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-dead_letter_queue-2.0.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-dead_letter_queue-2.0.1/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-couchdb_changes-3.1.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-beats-7.0.4-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-beats-7.0.4-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-mixin-plugin_factory_support-1.0.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-azure_event_hubs-1.5.3/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-input-azure_event_hubs-1.5.3/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-xml-4.3.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/xml-simple-1.1.9/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/nokogiri-1.18.10-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/nokogiri-1.18.10-java/lib/nokogiri/jruby
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/racc-1.8.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-uuid-3.0.5/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-useragent-3.3.5-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-useragent-3.3.5-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-urldecode-3.0.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-truncate-1.0.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-translate-3.5.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/psych-5.2.6-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-mixin-scheduler-1.0.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rufus-scheduler-3.0.9/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-mixin-deprecation_logger_support-1.0.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-throttle-4.0.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-syslog_pri-3.2.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-split-3.1.8/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-sleep-3.0.7/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-ruby-3.1.8/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-prune-3.0.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-mutate-3.5.9/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-metrics-4.0.7/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/metriks-0.9.9.8/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-memcached-1.2.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-kv-4.7.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-json-3.2.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-http-2.0.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-mixin-http_client-7.5.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-mixin-normalize_config_support-1.0.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-grok-4.4.3/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-geoip-7.3.2-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-geoip-7.3.2-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-fingerprint-3.4.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-elasticsearch-4.3.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-mixin-ca_trusted_fingerprint_support-1.0.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-mixin-ca_trusted_fingerprint_support-1.0.1-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-elastic_integration-9.2.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-elastic_integration-9.2.0-java/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-drop-3.0.5/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-dns-3.2.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/lru_redux-1.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-dissect-1.2.5/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-dissect-1.2.5/vendor/jars
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-de_dot-1.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-date-3.1.15/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-date-3.1.15/vendor/jar-dependencies
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-csv-3.1.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-clone-4.2.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-cidr-3.2.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-anonymize-3.0.7/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/murmurhash3-0.1.6-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/murmurhash3-0.1.6-java/ext
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-filter-aggregate-2.10.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-devutils-2.6.3-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-devutils-2.6.3-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rspec-wait-1.0.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-rubydebug-3.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-plain-3.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-netflow-4.3.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-multiline-3.1.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-patterns-core-4.3.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-msgpack-3.1.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-json_lines-3.2.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-json-3.1.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-graphite-3.0.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-fluent-3.4.3-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/msgpack-1.8.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-es_bulk-3.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-edn_lines-3.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-line-3.1.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-edn-3.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-dots-3.0.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-collectd-3.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-cef-6.2.8-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-codec-avro-3.4.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-mixin-validator_support-1.1.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-mixin-event_support-1.0.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logstash-mixin-ecs_compatibility_support-1.3.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/tzinfo-data-1.2025.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/tzinfo-2.0.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/treetop-1.6.15/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/polyglot-0.3.5/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/thwait-0.2.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/thread_safe-0.3.6-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/stud-0.0.23/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/stud-0.0.23/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/sinatra-4.2.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/tilt-2.6.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rack-session-2.1.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rack-protection-4.2.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/mustermann-3.0.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/ruby2_keywords-0.0.5/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rubyzip-1.3.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rack-3.2.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/puma-6.6.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/nio4r-2.7.5-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/pry-0.15.2-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/spoon-0.0.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/method_source-1.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/minitar-1.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/manticore-0.9.2-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/openssl_pkcs8_pure-0.0.0.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/lint_roller-1.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/language_server-protocol-3.17.0.5/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/kramdown-2.5.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/json-schema-2.8.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/jruby-stdin-channel-0.2.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/jruby-openssl-0.15.5-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/jruby-jms-1.3.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/semantic_logger-3.4.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/jrjackson-0.4.20-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/jls-lumberjack-0.0.26/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/jls-grok-0.11.5/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/jls-grok-0.11.5/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/jar-dependencies-0.5.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/insist-1.0.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/insist-1.0.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/i18n-1.14.7/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/http-3.3.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/http-form_data-2.3.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/http-cookie-1.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/hitimes-1.3.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/hashdiff-1.2.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/gserver-0.0.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/gmetric-0.1.3/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/gene_pool-1.5.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/gems-1.3.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/gem_publisher-1.5.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/gelfd2-0.4.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/gelf-3.0.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/ftw-0.0.49/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/ftw-0.0.49/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/http_parser.rb-0.6.0-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/flores-0.0.8/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/flores-0.0.8/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/fivemat-1.3.7/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/fileutils-1.8.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/filesize-0.2.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/ffi-1.17.2-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/equalizer-0.0.11/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/elasticsearch-8.19.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/elasticsearch-api-8.19.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/elastic-transport-8.4.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/faraday-2.14.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/faraday-2.14.0/spec/external_adapters
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/json-2.15.2-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/faraday-net_http-3.4.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/net-http-0.7.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/uri-1.1.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/edn-1.1.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/e2mmap-0.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/down-5.2.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/dotenv-2.8.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/domain_name-0.6.20240107/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/docile-1.4.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/digest-crc-0.5.1/ext
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/digest-crc-0.5.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/date-3.3.3-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/dalli-3.2.8/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/crack-1.0.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/concurrent-ruby-1.1.9/lib/concurrent-ruby
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/coderay-1.1.3/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/clamp-1.3.3/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/ci_reporter_rspec-1.0.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rspec-3.13.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rspec-mocks-3.13.7/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rspec-expectations-3.13.5/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/diff-lcs-1.6.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rspec-core-3.13.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rspec-support-3.13.6/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/ci_reporter-2.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rexml-3.4.4/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/cgi-0.3.7-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/cgi-0.3.7-java/ext/java/org/jruby/ext/cgi/escape/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/cabin-0.9.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/cabin-0.9.1/lib
/Users/cas/elastic-repos/logstash/vendor/jruby/lib/ruby/gems/shared/gems/bundler-2.6.3/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/builder-3.3.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/buftok-0.2.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/bindata-2.5.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/benchmark-ips-2.14.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/belzebuth-0.2.3/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/childprocess-5.1.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/backports-3.25.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/back_pressure-1.0.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/aws-sdk-sqs-1.106.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/aws-sdk-sns-1.108.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/aws-sdk-s3-1.203.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/aws-sdk-resourcegroups-1.90.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/aws-sdk-kms-1.116.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/aws-sdk-cloudwatch-1.124.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/aws-sdk-cloudfront-1.133.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/aws-sdk-core-3.236.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/logger-1.7.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/jmespath-1.6.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/bigdecimal-3.3.1-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/base64-0.3.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/aws-sigv4-1.12.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/aws-partitions-1.1180.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/aws-eventstream-1.4.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/avro-1.10.2/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/multi_json-1.17.0/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/avl_tree-1.2.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/atomic-1.1.101-java/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/ast-2.4.3/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/amazing_print-1.8.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/addressable-2.8.7/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/public_suffix-5.1.1/lib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/rake-13.3.1/lib
/Users/cas/elastic-repos/logstash/vendor/jruby/lib/ruby/3.1/site_ruby
/Users/cas/elastic-repos/logstash/vendor/jruby/lib/ruby/stdlib
/Users/cas/elastic-repos/logstash/vendor/bundle/jruby/3.1.0/gems/ci_reporter_rspec-1.0.0/lib/ci/reporter/rake/../../..

As you can see the bundler setup! adds the full bundled gem env to the load path BEFORE stdlib.

Open questions/thoughts

  1. I'm not convinced the bundler.setup! state is appropriate for all unit tests. That said, i'm not sure if its worth the effort to go through and dial it in for every single part of the unit tests. The solution i've proposed here seems to get the tests passing, but i'm nervous it may paper over issues or be an indicator that this is actually a problem we should be worried about.
  2. I'de like to do some more manual testing around what the state of LOAD_PATH is at various times in logstash execution (i've been focused mainly on the pluginmanager because that is where the test failures are).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some additional testing affirms my initial observations. Essentially this boils down to the fact that logstash-plugin does not actually call LogStash::Boostrap#setup! in practice. So by invoking that directly before all unit tests we get a state that is inconsistent with the gem env in logstash run from artifacts. I'm tempted to try to localize this LOAD_PATH manipulation to just the tests where there are issues as there were only two test files where this was an issue and the majority of tests cover cases where the setup! method would have been invoked.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that i did do some testing where for example pipeline code would use yaml/psych:

echo -e "foo: 1\nbar: 1" | logstash -e "input { stdin { } } filter { ruby { code => \"require 'yaml'; event.set('parsed', YAML.load(event.get('message')))\" } } output { stdout { codec => rubydebug } }"

This did not result in any psych loading issues like the ones we saw in the unit tests. Similarly I printed the load path from a ruby filter context and it matched that of a result of calling the setup! method.

# Our use of LogStash::Bundler.setup! here leaves us in kind of a wonky state for *all* tests
# Essentially we end up with a load path that favors bundlers gem env over stdlib. This is
# not really the call stack in logstash itself, so while this does make the full bundled gem
# env available for tests, it also has a quirk where stdlib gems are not loaed correctly. The
# following patch ensures that stdlib gems are bumped to the front of the load path for unit
# tests.
## START PATCH ##
jruby_stdlib = $LOAD_PATH.find { |p| p.end_with?('vendor/jruby/lib/ruby/stdlib') }
$LOAD_PATH.unshift($LOAD_PATH.delete(jruby_stdlib)) if jruby_stdlib
## END PATCH ##
require "logstash-core"
require "logstash/environment"

Expand Down
10 changes: 5 additions & 5 deletions lib/pluginmanager/gem_installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# specific language governing permissions and limitations
# under the License.

require "bootstrap/environment"
require "pluginmanager/ui"
require "pathname"
require "rubygems/package"
Expand All @@ -26,17 +27,16 @@ module LogStash module PluginManager
# - Generate the specifications
# - Copy the data in the right folders
class GemInstaller
GEM_HOME = Pathname.new(::File.join(LogStash::Environment::BUNDLE_DIR, "jruby", "3.1.0"))
SPECIFICATIONS_DIR = "specifications"
GEMS_DIR = "gems"
CACHE_DIR = "cache"

attr_reader :gem_home

def initialize(gem_file, display_post_install_message = false, gem_home = GEM_HOME)
def initialize(gem_file, display_post_install_message = false)
@gem_file = gem_file
@gem = ::Gem::Package.new(@gem_file)
@gem_home = Pathname.new(gem_home)
@gem_home = Pathname.new(LogStash::Environment.logstash_gem_home)
@display_post_install_message = display_post_install_message
end

Expand All @@ -48,8 +48,8 @@ def install
post_install_message
end

def self.install(gem_file, display_post_install_message = false, gem_home = GEM_HOME)
self.new(gem_file, display_post_install_message, gem_home).install
def self.install(gem_file, display_post_install_message = false)
self.new(gem_file, display_post_install_message).install
end

private
Expand Down
12 changes: 0 additions & 12 deletions rakelib/artifacts.rake
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,6 @@ namespace "artifact" do
@exclude_paths << 'vendor/**/gems/**/Gemfile.lock'
@exclude_paths << 'vendor/**/gems/**/Gemfile'

@exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/gems/rake-*'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are no longer required as they are handled by the new plugin:clean-duplicate-gems task.

# exclude ruby-maven-libs 3.3.9 jars until JRuby ships with >= 3.8.9
@exclude_paths << 'vendor/bundle/jruby/**/gems/ruby-maven-libs-3.3.9/**/*'

# remove this after JRuby includes rexml 3.3.x
@exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/gems/rexml-3.2.5/**/*'
@exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/specifications/rexml-3.2.5.gemspec'

# remove this after JRuby includes net-imap-0.2.4+
@exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/specifications/net-imap-0.2.3.gemspec'
@exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/gems/net-imap-0.2.3/**/*'

# Exclude env2yaml source files - only compiled classes should be in tarball
@exclude_paths << 'docker/data/logstash/env2yaml/**/*.java'
@exclude_paths << 'docker/data/logstash/env2yaml/build.gradle'
Expand Down
53 changes: 53 additions & 0 deletions rakelib/plugin.rake
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,65 @@ namespace "plugin" do
task.reenable # Allow this task to be run again
end # task "install"


task "clean-duplicate-gems" do
shared_gems_path = File.join(LogStash::Environment::LOGSTASH_HOME,
'vendor/jruby/lib/ruby/gems/shared/gems')
default_gemspecs_path = File.join(LogStash::Environment::LOGSTASH_HOME,
'vendor/jruby/lib/ruby/gems/shared/specifications/default')
bundle_gems_path = File.join(LogStash::Environment::BUNDLE_DIR,
'jruby/*/gems')

# "bundled" gems in jruby
# https://github.com/jruby/jruby/blob/024123c29d73b672d50730117494f3e4336a0edb/lib/pom.rb#L108-L152
shared_gem_names = Dir.glob(File.join(shared_gems_path, '*')).map do |path|
match = File.basename(path).match(/^(.+?)-\d+/)
match ? match[1] : nil
end.compact

# "default" gems in jruby/ruby
# https://github.com/jruby/jruby/blob/024123c29d73b672d50730117494f3e4336a0edb/lib/pom.rb#L21-L106
default_gem_names = Dir.glob(File.join(default_gemspecs_path, '*.gemspec')).map do |path|
match = File.basename(path).match(/^(.+?)-\d+/)
match ? match[1] : nil
end.compact

# gems we explicitly manage with bundler (we always want these to take precedence)
bundle_gem_names = Dir.glob(File.join(bundle_gems_path, '*')).map do |path|
match = File.basename(path).match(/^(.+?)-\d+/)
match ? match[1] : nil
end.compact

shared_duplicates = shared_gem_names & bundle_gem_names
default_duplicates = default_gem_names & bundle_gem_names
all_duplicates = (shared_duplicates + default_duplicates).uniq

puts("[plugin:clean-duplicate-gems] Removing duplicate gems: #{all_duplicates.sort.join(', ')}")

# Remove shared/bundled gem duplicates
shared_duplicates.each do |gem_name|
FileUtils.rm_rf(Dir.glob("#{shared_gems_path}/#{gem_name}-*"))
FileUtils.rm_rf(Dir.glob("#{shared_gems_path}/../specifications/#{gem_name}-*.gemspec"))
end

# Remove default gem gemspecs only
default_duplicates.each do |gem_name|
# For stdlib default gems we only remove the gemspecs as removing the source code
# files results in code loading errors and ruby warnings
FileUtils.rm_rf(Dir.glob("#{default_gemspecs_path}/#{gem_name}-*.gemspec"))
end

task.reenable
end

task "install-default" => "bootstrap" do
puts("[plugin:install-default] Installing default plugins")

remove_lockfile # because we want to use the release lockfile
install_plugins("--no-verify", "--preserve", *LogStash::RakeLib::DEFAULT_PLUGINS)

# Clean duplicates after full gem resolution
Rake::Task["plugin:clean-duplicate-gems"].invoke
task.reenable # Allow this task to be run again
end

Expand Down
12 changes: 10 additions & 2 deletions rubyUtils.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,11 @@ tasks.register("installCustomJRuby", Copy) {
dependsOn buildCustomJRuby
description = "Install custom built JRuby in the vendor directory"
inputs.file(customJRubyTar)
outputs.dir("${projectDir}/vendor/jruby")
// Don't re-extract if core JRuby is already installed. This works around
// gem deduplication when rake calls back in to gradle.
onlyIf {
!file("${projectDir}/vendor/jruby/bin/jruby").exists()
}
from tarTree(customJRubyTar == "" ? jrubyTarPath : customJRubyTar)
eachFile { f ->
f.path = f.path.replaceFirst("^jruby-${customJRubyVersion}", '')
Expand All @@ -294,7 +298,11 @@ tasks.register("downloadAndInstallJRuby", Copy) {
dependsOn=[verifyFile, installCustomJRuby]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COREREVIEW: why is there a dep on installCustomJRuby here?

description = "Install JRuby in the vendor directory"
inputs.file(jrubyTarPath)
outputs.dir("${projectDir}/vendor/jruby")
// Don't re-extract if core JRuby is already installed. This works around
// gem deduplication when rake calls back in to gradle.
onlyIf {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the interplay between gradle/rake it is hard (IMO impossible) to define a sane dependency graph to ensure that gems are cleaned after jruby has been installed and bundler has been run. TO get around issues where gradle was being tricked in to thinking we need a fresh jruby install when gems have been cleaned up, only install jruby when the executable is not in the expected place. This is kind of a hack as i could see a workflow where this would cause an issue with an unexpectedly old or broken jruby but I cant think of a way around it without majorly refactoring how our gradle/rake tasks are organized.

!file("${projectDir}/vendor/jruby/bin/jruby").exists()
}
from tarTree(downloadJRuby.dest)
eachFile { f ->
f.path = f.path.replaceFirst("^jruby-${jRubyVersion}", '')
Expand Down
25 changes: 17 additions & 8 deletions spec/unit/plugin_manager/gem_installer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,27 @@
let(:simple_gem) { ::File.join(::File.dirname(__FILE__), "..", "..", "support", "pack", "valid-pack", "logstash", "valid-pack", "#{plugin_name}.gem") }

subject { described_class }
let(:temporary_gem_home) { p = Stud::Temporary.pathname; FileUtils.mkdir_p(p); p }
let(:gem_home) { LogStash::Environment.logstash_gem_home }
# Clean up installed gems after each test
after(:each) do
spec_file = ::File.join(gem_home, "specifications", "#{plugin_name}.gemspec")
FileUtils.rm_f(spec_file) if ::File.exist?(spec_file)
gem_dir = ::File.join(gem_home, "gems", plugin_name)
FileUtils.rm_rf(gem_dir) if Dir.exist?(gem_dir)
cache_file = ::File.join(gem_home, "cache", "#{plugin_name}.gem")
FileUtils.rm_f(cache_file) if ::File.exist?(cache_file)
end

it "install the specifications in the spec dir" do
subject.install(simple_gem, false, temporary_gem_home)
spec_file = ::File.join(temporary_gem_home, "specifications", "#{plugin_name}.gemspec")
subject.install(simple_gem, false)
spec_file = ::File.join(gem_home, "specifications", "#{plugin_name}.gemspec")
expect(::File.exist?(spec_file)).to be_truthy
expect(::File.size(spec_file)).to be > 0
end

it "install the gem in the gems dir" do
subject.install(simple_gem, false, temporary_gem_home)
gem_dir = ::File.join(temporary_gem_home, "gems", plugin_name)
subject.install(simple_gem, false)
gem_dir = ::File.join(gem_home, "gems", plugin_name)
expect(Dir.exist?(gem_dir)).to be_truthy
end

Expand All @@ -50,13 +59,13 @@

context "when we want the message" do
it "display the message" do
expect(subject.install(simple_gem, true, temporary_gem_home)).to eq(message)
expect(subject.install(simple_gem, true)).to eq(message)
end
end

context "when we dont want the message" do
it "doesn't display the message" do
expect(subject.install(simple_gem, false, temporary_gem_home)).to be_nil
expect(subject.install(simple_gem, false)).to be_nil
end
end
end
Expand All @@ -65,7 +74,7 @@
context "when we don't want the message" do
it "doesn't display the message" do
expect(LogStash::PluginManager.ui).not_to receive(:info).with(message)
subject.install(simple_gem, true, temporary_gem_home)
subject.install(simple_gem, true)
end
end
end
Expand Down