execute

in logstash-core/lib/logstash/runner.rb [251:433]


  def execute
    LogStash::Util::SettingsHelper.post_process

    require "logstash/util"
    require "logstash/util/java_version"
    require "stud/task"

    running_as_superuser

    if log_configuration_contains_javascript_usage?
      logger.error("Logging configuration uses Script log appender or filter with Javascript, which is no longer supported.")
      return 1
    end

    if setting("config.debug") && !logger.debug?
      logger.warn("--config.debug was specified, but log.level was not set to \'debug\'! No config info will be logged.")
    end
    if setting("pipeline.buffer.type") != nil
      configure_pipeline_buffer_type
    end

    while (msg = LogStash::DeprecationMessage.instance.shift)
      deprecation_logger.deprecated msg
    end

    if JavaVersion::CURRENT < JavaVersion::JAVA_17
      deprecation_logger.deprecated I18n.t("logstash.runner.java.version_17_minimum",
                                           :java_home => java.lang.System.getProperty("java.home"))
    end

    logger.warn I18n.t("logstash.runner.java.home") if ENV["JAVA_HOME"]
    
    if version?
      show_version
      return 0
    end

    logger.info("Starting Logstash", "logstash.version" => LOGSTASH_VERSION, "jruby.version" => RUBY_DESCRIPTION)
    jvmArgs = ManagementFactory.getRuntimeMXBean().getInputArguments()
    logger.info "JVM bootstrap flags: #{jvmArgs}"


    
    LogStash::Util::Jackson.verify_jackson_overrides

    @dispatcher = LogStash::EventDispatcher.new(self)
    LogStash::PLUGIN_REGISTRY.hooks.register_emitter(self.class, @dispatcher)

    validate_settings! or return 1
    @dispatcher.fire(:before_bootstrap_checks)

    field_reference_escape_style_setting = settings.get_setting('config.field_reference.escape_style')
    if field_reference_escape_style_setting.set?
      logger.warn(I18n.t("logstash.settings.technical_preview.set", :canonical_name => field_reference_escape_style_setting.name))
    end
    field_reference_escape_style = field_reference_escape_style_setting.value
    logger.debug("Setting global FieldReference escape style: #{field_reference_escape_style}")
    org.logstash.FieldReference::set_escape_style(field_reference_escape_style)

    return start_shell(setting("interactive"), binding) if setting("interactive")

    begin
      @bootstrap_checks.each { |bootstrap| bootstrap.check(@settings) }
    rescue LogStash::BootstrapCheckError => e
      signal_usage_error(e.message)
      return 1
    end
    @dispatcher.fire(:after_bootstrap_checks)

    LogStash::Util::set_thread_name(self.class.name)

    LogStash::ShutdownWatcher.unsafe_shutdown = setting("pipeline.unsafe_shutdown")

    configure_plugin_paths(setting("path.plugins"))

    @settings.format_settings.each {|line| logger.debug(line) }

    
    
    
    sources_without_conflict = []
    unmatched_sources_conflict_messages = []
    @source_loader.sources do |source|
      if source.config_conflict?
        if source.conflict_messages.any?
          unmatched_sources_conflict_messages << source.conflict_messages.join(", ")
        end
      else
        sources_without_conflict << source
      end
    end
    if unmatched_sources_conflict_messages.any?
      
      signal_usage_error(unmatched_sources_conflict_messages.join(" "))
      return 1
    elsif sources_without_conflict.empty?
      signal_usage_error(I18n.t("logstash.runner.missing-configuration"))
      return 1
    end

    if setting("config.test_and_exit")
      begin
        results = @source_loader.fetch

        
        if results.success?
          results.response.each { |pipeline_config| LogStash::JavaPipeline.new(pipeline_config) }
          puts "Configuration OK"
          logger.info "Using config.test_and_exit mode. Config Validation Result: OK. Exiting Logstash"
        else
          raise "Could not load the configuration file"
        end
        return 0
      rescue => e
        logger.fatal I18n.t("logstash.runner.invalid-configuration", :error => e.message)
        return 1
      end
    end

    
    @data_path_lock = FileLockFactory.obtainLock(java.nio.file.Paths.get(setting("path.data")).to_absolute_path, ".lock")

    @dispatcher.fire(:before_agent)
    @agent = create_agent(@settings, @source_loader)
    @dispatcher.fire(:after_agent)

    
    
    sigint_id = trap_sigint()
    sigterm_id = trap_sigterm()

    @agent_task = Stud::Task.new { @agent.execute }

    
    
    sighup_id = LogStash::Environment.windows? ? nil : trap_sighup()

    agent_return = @agent_task.wait

    @agent.shutdown

    logger.info("Logstash shut down.")

    
    org.apache.logging.log4j.LogManager.shutdown

    agent_return
  rescue org.logstash.LockException => e
    logger.fatal(I18n.t("logstash.runner.locked-data-path", :path => setting("path.data")))
    return 1
  rescue Clamp::UsageError => e
    $stderr.puts "ERROR: #{e.message}"
    show_short_help
    return 1
  rescue => e
    
    if LogStash::Logging::Logger.get_logging_context.nil?
      $stderr.puts "#{I18n.t("oops")} :error => #{e}, :backtrace => #{e.backtrace}"
    else
      logger.fatal(I18n.t("oops"), :error => e, :backtrace => e.backtrace)
    end
    return 1
  ensure
    Stud::untrap("INT", sigint_id) unless sigint_id.nil?
    Stud::untrap("TERM", sigterm_id) unless sigterm_id.nil?
    Stud::untrap("HUP", sighup_id) unless sighup_id.nil?
    FileLockFactory.releaseLock(@data_path_lock) if @data_path_lock
    @log_fd.close if @log_fd
  end 

  def running_as_superuser
    return if LogStash::Environment.windows? 

    if Process.euid() == 0
      if setting("allow_superuser")
        logger.warn("NOTICE: Allowing Logstash to run as superuser is heavily discouraged as it poses a security risk. " +
                      "It is strongly recommended to set 'allow_superuser' to false.")
      else
        raise(RuntimeError, "Logstash cannot be run as superuser.")
      end
    end
  end