-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Created `org.logstash.Logstash` as entrypoint * Safely handle `Ruby` runtime (which sadly is still a singleton, moving away from that will require a few iterations on top of this) * Adjusted `bat` and `sh` entry point wrappers * Verified manually that performance is unchanged (i.e. all Java opts are still loaded properly) * Flattened `.jar` path to make it a little less bothersome to build the `-cp` string * Retained ability to load jars from Ruby via the global `$LS_JARS_LOADED` variable hack, to keep plugin specs that load LS as a `.gem` functional (like e.g. the ITs in LS itself) * No need for the gem jars magic anymore, the downloading and moving into place of jars is now all handled by Gradle
- Loading branch information
1 parent
19b7f77
commit 166c88c
Showing
12 changed files
with
191 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package org.logstash; | ||
|
||
import java.io.InputStream; | ||
import java.io.PrintStream; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.jruby.Ruby; | ||
import org.jruby.RubyException; | ||
import org.jruby.RubyInstanceConfig; | ||
import org.jruby.RubyNumeric; | ||
import org.jruby.exceptions.RaiseException; | ||
import org.jruby.runtime.builtin.IRubyObject; | ||
|
||
/** | ||
* Logstash Main Entrypoint. | ||
*/ | ||
public final class Logstash implements Runnable, AutoCloseable { | ||
|
||
private static final Logger LOGGER = LogManager.getLogger(Logstash.class); | ||
|
||
/** | ||
* Configuration for {@link #ruby}. | ||
*/ | ||
private final RubyInstanceConfig config; | ||
|
||
/** | ||
* JRuby Runtime Environment. | ||
*/ | ||
private final Ruby ruby; | ||
|
||
/** | ||
* Ruby Entrypoint Script. | ||
*/ | ||
private final InputStream script; | ||
|
||
/** | ||
* Main Entrypoint. | ||
* Requires environment {@code "LS_HOME"} to be set to the Logstash root directory. | ||
* @param args Logstash CLI Arguments | ||
*/ | ||
public static void main(final String... args) { | ||
final String lsHome = System.getenv("LS_HOME"); | ||
if (lsHome == null) { | ||
throw new IllegalStateException( | ||
"LS_HOME environment variable must be set. This is likely a bug that should be reported." | ||
); | ||
} | ||
final Path home = Paths.get(lsHome).toAbsolutePath(); | ||
try ( | ||
final Logstash logstash = new Logstash(home, args, System.out, System.err, System.in) | ||
) { | ||
logstash.run(); | ||
} catch (final Throwable t) { | ||
LOGGER.error(t); | ||
System.exit(1); | ||
} | ||
System.exit(0); | ||
} | ||
|
||
/** | ||
* Ctor. | ||
* @param home Logstash Root Directory | ||
* @param args Commandline Arguments | ||
* @param output Output Stream Capturing StdOut | ||
* @param error Output Stream Capturing StdErr | ||
* @param input Input Stream Capturing StdIn | ||
*/ | ||
Logstash(final Path home, final String[] args, final PrintStream output, | ||
final PrintStream error, final InputStream input) { | ||
config = buildConfig(home, args); | ||
config.setOutput(output); | ||
config.setError(error); | ||
config.setInput(input); | ||
script = config.getScriptSource(); | ||
ruby = Ruby.newInstance(config); | ||
} | ||
|
||
@Override | ||
public void run() { | ||
// @todo: Refactor codebase to not rely on global constant for Ruby Runtime | ||
if (RubyUtil.RUBY != ruby) { | ||
throw new IllegalStateException( | ||
"More than one JRuby Runtime detected in the current JVM!" | ||
); | ||
} | ||
try { | ||
Thread.currentThread().setContextClassLoader(ruby.getJRubyClassLoader()); | ||
ruby.runFromMain(script, config.displayedFileName()); | ||
} catch (final RaiseException ex) { | ||
final RubyException rexep = ex.getException(); | ||
if (ruby.getSystemExit().isInstance(rexep)) { | ||
final IRubyObject status = | ||
rexep.callMethod(ruby.getCurrentContext(), "status"); | ||
if (status != null && !status.isNil() && RubyNumeric.fix2int(status) != 0) { | ||
throw new IllegalStateException(ex); | ||
} | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void close() throws Exception { | ||
ruby.tearDown(false); | ||
script.close(); | ||
} | ||
|
||
/** | ||
* Sets up the correct {@link RubyInstanceConfig} for a given Logstash installation and set of | ||
* CLI arguments. | ||
* @param home Logstash Root Path | ||
* @param args Commandline Arguments Passed to Logstash | ||
* @return RubyInstanceConfig | ||
*/ | ||
private static RubyInstanceConfig buildConfig(final Path home, final String[] args) { | ||
final String[] arguments = new String[args.length + 2]; | ||
System.arraycopy(args, 0, arguments, 2, args.length); | ||
arguments[0] = safePath(home, "lib", "bootstrap", "environment.rb"); | ||
arguments[1] = safePath(home, "logstash-core", "lib", "logstash", "runner.rb"); | ||
final RubyInstanceConfig config = new RubyInstanceConfig(); | ||
config.processArguments(arguments); | ||
return config; | ||
} | ||
|
||
/** | ||
* Builds the correct path for a file under the given Logstash root and defined by its sub path | ||
* elements relative to the Logstash root. | ||
* Ensures that the file exists and throws an exception of it's missing. | ||
* This is done to avoid hard to interpret errors thrown by JRuby that could result from missing | ||
* Ruby bootstrap scripts. | ||
* @param home Logstash Root Path | ||
* @param subs Path elements relative to {@code home} | ||
* @return Absolute Path a File under the Logstash Root. | ||
*/ | ||
private static String safePath(final Path home, final String... subs) { | ||
Path resolved = home; | ||
for (final String element : subs) { | ||
resolved = resolved.resolve(element); | ||
} | ||
if (!resolved.toFile().exists()) { | ||
throw new IllegalArgumentException(String.format("Missing: %s.", resolved)); | ||
} | ||
return resolved.toString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters