appsignal 4.0.4 → 4.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +151 -16
- data/CHANGELOG.md +42 -0
- data/build_matrix.yml +2 -1
- data/ext/agent.rb +27 -27
- data/gemfiles/que-1.gemfile +5 -0
- data/gemfiles/que-2.gemfile +5 -0
- data/lib/appsignal/check_in/scheduler.rb +3 -4
- data/lib/appsignal/config.rb +7 -0
- data/lib/appsignal/hooks/at_exit.rb +1 -0
- data/lib/appsignal/hooks/puma.rb +5 -1
- data/lib/appsignal/integrations/puma.rb +45 -0
- data/lib/appsignal/integrations/que.rb +8 -2
- data/lib/appsignal/rack/abstract_middleware.rb +3 -47
- data/lib/appsignal/rack/event_handler.rb +2 -0
- data/lib/appsignal/rack/hanami_middleware.rb +5 -1
- data/lib/appsignal/rack.rb +68 -0
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/check_in/cron_spec.rb +134 -134
- data/spec/lib/appsignal/check_in/scheduler_spec.rb +297 -224
- data/spec/lib/appsignal/config_spec.rb +13 -0
- data/spec/lib/appsignal/hooks/at_exit_spec.rb +11 -0
- data/spec/lib/appsignal/hooks/puma_spec.rb +31 -23
- data/spec/lib/appsignal/integrations/puma_spec.rb +150 -0
- data/spec/lib/appsignal/integrations/que_spec.rb +56 -21
- data/spec/lib/appsignal/probes_spec.rb +4 -6
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +41 -122
- data/spec/lib/appsignal/rack_spec.rb +180 -0
- data/spec/lib/appsignal/transaction_spec.rb +96 -92
- data/spec/spec_helper.rb +6 -7
- data/spec/support/helpers/api_request_helper.rb +40 -0
- data/spec/support/helpers/config_helpers.rb +2 -1
- data/spec/support/helpers/dependency_helper.rb +5 -0
- data/spec/support/matchers/contains_log.rb +10 -3
- data/spec/support/mocks/hash_like.rb +10 -0
- data/spec/support/mocks/puma_mock.rb +43 -0
- data/spec/support/testing.rb +9 -0
- metadata +8 -3
- data/gemfiles/que.gemfile +0 -5
| @@ -19,7 +19,6 @@ module Appsignal | |
| 19 19 | 
             
                    @app = app
         | 
| 20 20 | 
             
                    @options = options
         | 
| 21 21 | 
             
                    @request_class = options.fetch(:request_class, ::Rack::Request)
         | 
| 22 | 
            -
                    @params_method = options.fetch(:params_method, :params)
         | 
| 23 22 | 
             
                    @instrument_event_name = options.fetch(:instrument_event_name, nil)
         | 
| 24 23 | 
             
                    @report_errors = options.fetch(:report_errors, DEFAULT_ERROR_REPORTING)
         | 
| 25 24 | 
             
                  end
         | 
| @@ -136,52 +135,9 @@ module Appsignal | |
| 136 135 | 
             
                  # Override this method to set metadata after the app is called.
         | 
| 137 136 | 
             
                  # Call `super` to also include the default set metadata.
         | 
| 138 137 | 
             
                  def add_transaction_metadata_after(transaction, request)
         | 
| 139 | 
            -
                     | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 142 | 
            -
                    transaction.set_metadata("method", request_method) if request_method
         | 
| 143 | 
            -
             | 
| 144 | 
            -
                    transaction.add_params { params_for(request) }
         | 
| 145 | 
            -
                    transaction.add_session_data { session_data_for(request) }
         | 
| 146 | 
            -
                    transaction.add_headers do
         | 
| 147 | 
            -
                      request.env if request.respond_to?(:env)
         | 
| 148 | 
            -
                    end
         | 
| 149 | 
            -
             | 
| 150 | 
            -
                    queue_start = Appsignal::Rack::Utils.queue_start_from(request.env)
         | 
| 151 | 
            -
                    transaction.set_queue_start(queue_start) if queue_start
         | 
| 152 | 
            -
                  end
         | 
| 153 | 
            -
             | 
| 154 | 
            -
                  def params_for(request)
         | 
| 155 | 
            -
                    return unless request.respond_to?(@params_method)
         | 
| 156 | 
            -
             | 
| 157 | 
            -
                    request.send(@params_method)
         | 
| 158 | 
            -
                  rescue => error
         | 
| 159 | 
            -
                    Appsignal.internal_logger.error(
         | 
| 160 | 
            -
                      "Exception while fetching params from '#{@request_class}##{@params_method}': " \
         | 
| 161 | 
            -
                        "#{error.class} #{error}"
         | 
| 162 | 
            -
                    )
         | 
| 163 | 
            -
                    nil
         | 
| 164 | 
            -
                  end
         | 
| 165 | 
            -
             | 
| 166 | 
            -
                  def request_method_for(request)
         | 
| 167 | 
            -
                    request.request_method
         | 
| 168 | 
            -
                  rescue => error
         | 
| 169 | 
            -
                    Appsignal.internal_logger.error(
         | 
| 170 | 
            -
                      "Exception while fetching the HTTP request method: #{error.class}: #{error}"
         | 
| 171 | 
            -
                    )
         | 
| 172 | 
            -
                    nil
         | 
| 173 | 
            -
                  end
         | 
| 174 | 
            -
             | 
| 175 | 
            -
                  def session_data_for(request)
         | 
| 176 | 
            -
                    return unless request.respond_to?(:session)
         | 
| 177 | 
            -
             | 
| 178 | 
            -
                    request.session.to_h
         | 
| 179 | 
            -
                  rescue => error
         | 
| 180 | 
            -
                    Appsignal.internal_logger.error(
         | 
| 181 | 
            -
                      "Exception while fetching session data from '#{@request_class}': " \
         | 
| 182 | 
            -
                        "#{error.class} #{error}"
         | 
| 183 | 
            -
                    )
         | 
| 184 | 
            -
                    nil
         | 
| 138 | 
            +
                    Appsignal::Rack::ApplyRackRequest
         | 
| 139 | 
            +
                      .new(request, @options)
         | 
| 140 | 
            +
                      .apply_to(transaction)
         | 
| 185 141 | 
             
                  end
         | 
| 186 142 |  | 
| 187 143 | 
             
                  def request_for(env)
         | 
| @@ -79,6 +79,8 @@ module Appsignal | |
| 79 79 | 
             
                        #
         | 
| 80 80 | 
             
                        # The EventHandler.on_finish callback should be called first, this is
         | 
| 81 81 | 
             
                        # just a fallback if that doesn't get called.
         | 
| 82 | 
            +
                        #
         | 
| 83 | 
            +
                        # One such scenario is when a Puma "lowlevel_error" occurs.
         | 
| 82 84 | 
             
                        Appsignal::Transaction.complete_current!
         | 
| 83 85 | 
             
                      end
         | 
| 84 86 | 
             
                      transaction.start_event
         | 
| @@ -5,13 +5,17 @@ module Appsignal | |
| 5 5 | 
             
                # @api private
         | 
| 6 6 | 
             
                class HanamiMiddleware < AbstractMiddleware
         | 
| 7 7 | 
             
                  def initialize(app, options = {})
         | 
| 8 | 
            -
                    options[:params_method]  | 
| 8 | 
            +
                    options[:params_method] = nil
         | 
| 9 9 | 
             
                    options[:instrument_event_name] ||= "process_action.hanami"
         | 
| 10 10 | 
             
                    super
         | 
| 11 11 | 
             
                  end
         | 
| 12 12 |  | 
| 13 13 | 
             
                  private
         | 
| 14 14 |  | 
| 15 | 
            +
                  def add_transaction_metadata_after(transaction, request)
         | 
| 16 | 
            +
                    transaction.add_params { params_for(request) }
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 15 19 | 
             
                  def params_for(request)
         | 
| 16 20 | 
             
                    ::Hanami::Action.params_class.new(request.env).to_h
         | 
| 17 21 | 
             
                  end
         | 
    
        data/lib/appsignal/rack.rb
    CHANGED
    
    | @@ -37,5 +37,73 @@ module Appsignal | |
| 37 37 | 
             
                    end
         | 
| 38 38 | 
             
                  end
         | 
| 39 39 | 
             
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                class ApplyRackRequest
         | 
| 42 | 
            +
                  attr_reader :request, :options
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  def initialize(request, options = {})
         | 
| 45 | 
            +
                    @request = request
         | 
| 46 | 
            +
                    @options = options
         | 
| 47 | 
            +
                    @params_method = options.fetch(:params_method, :params)
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  def apply_to(transaction)
         | 
| 51 | 
            +
                    request_path = request.path
         | 
| 52 | 
            +
                    transaction.set_metadata("request_path", request_path)
         | 
| 53 | 
            +
                    # TODO: Remove in next major/minor version
         | 
| 54 | 
            +
                    transaction.set_metadata("path", request_path)
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    request_method = request_method_for(request)
         | 
| 57 | 
            +
                    if request_method
         | 
| 58 | 
            +
                      transaction.set_metadata("request_method", request_method)
         | 
| 59 | 
            +
                      # TODO: Remove in next major/minor version
         | 
| 60 | 
            +
                      transaction.set_metadata("method", request_method)
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                    transaction.add_params { params_for(request) }
         | 
| 64 | 
            +
                    transaction.add_session_data { session_data_for(request) }
         | 
| 65 | 
            +
                    transaction.add_headers do
         | 
| 66 | 
            +
                      request.env if request.respond_to?(:env)
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                    queue_start = Appsignal::Rack::Utils.queue_start_from(request.env)
         | 
| 70 | 
            +
                    transaction.set_queue_start(queue_start) if queue_start
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  private
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  def params_for(request)
         | 
| 76 | 
            +
                    return if !@params_method || !request.respond_to?(@params_method)
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                    request.send(@params_method)
         | 
| 79 | 
            +
                  rescue => error
         | 
| 80 | 
            +
                    Appsignal.internal_logger.error(
         | 
| 81 | 
            +
                      "Exception while fetching params from '#{request.class}##{@params_method}': " \
         | 
| 82 | 
            +
                        "#{error.class} #{error}"
         | 
| 83 | 
            +
                    )
         | 
| 84 | 
            +
                    nil
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  def request_method_for(request)
         | 
| 88 | 
            +
                    request.request_method
         | 
| 89 | 
            +
                  rescue => error
         | 
| 90 | 
            +
                    Appsignal.internal_logger.error(
         | 
| 91 | 
            +
                      "Exception while fetching the HTTP request method: #{error.class}: #{error}"
         | 
| 92 | 
            +
                    )
         | 
| 93 | 
            +
                    nil
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                  def session_data_for(request)
         | 
| 97 | 
            +
                    return unless request.respond_to?(:session)
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                    request.session.to_h
         | 
| 100 | 
            +
                  rescue => error
         | 
| 101 | 
            +
                    Appsignal.internal_logger.error(
         | 
| 102 | 
            +
                      "Exception while fetching session data from '#{request.class}': " \
         | 
| 103 | 
            +
                        "#{error.class} #{error}"
         | 
| 104 | 
            +
                    )
         | 
| 105 | 
            +
                    nil
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
                end
         | 
| 40 108 | 
             
              end
         | 
| 41 109 | 
             
            end
         | 
    
        data/lib/appsignal/version.rb
    CHANGED
    
    
| @@ -1,193 +1,191 @@ | |
| 1 1 | 
             
            describe Appsignal::CheckIn::Cron do
         | 
| 2 | 
            +
              let(:log_stream) { std_stream }
         | 
| 3 | 
            +
              let(:logs) { log_contents(log_stream) }
         | 
| 4 | 
            +
              let(:appsignal_options) { {} }
         | 
| 2 5 | 
             
              let(:config) { project_fixture_config }
         | 
| 3 6 | 
             
              let(:cron_checkin) { described_class.new(:identifier => "cron-checkin-name") }
         | 
| 4 | 
            -
              let(: | 
| 5 | 
            -
              let(:scheduler) { Appsignal::CheckIn::Scheduler.new }
         | 
| 7 | 
            +
              let(:scheduler) { Appsignal::CheckIn.scheduler }
         | 
| 6 8 |  | 
| 7 9 | 
             
              before do
         | 
| 8 | 
            -
                 | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
                 | 
| 10 | 
            +
                start_agent(
         | 
| 11 | 
            +
                  :options => appsignal_options,
         | 
| 12 | 
            +
                  :internal_logger => test_logger(log_stream)
         | 
| 13 | 
            +
                )
         | 
| 12 14 | 
             
              end
         | 
| 15 | 
            +
              after { stop_scheduler }
         | 
| 13 16 |  | 
| 14 | 
            -
               | 
| 17 | 
            +
              def stop_scheduler
         | 
| 15 18 | 
             
                scheduler.stop
         | 
| 16 19 | 
             
              end
         | 
| 17 20 |  | 
| 18 21 | 
             
              describe "when Appsignal is not active" do
         | 
| 19 | 
            -
                 | 
| 20 | 
            -
                  allow(Appsignal).to receive(:active?).and_return(false)
         | 
| 22 | 
            +
                let(:appsignal_options) { { :active => false } }
         | 
| 21 23 |  | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
                    message.include?("AppSignal is not active")
         | 
| 25 | 
            -
                  end)
         | 
| 24 | 
            +
                it "does not transmit any events" do
         | 
| 25 | 
            +
                  expect(Appsignal).to_not be_started
         | 
| 26 26 |  | 
| 27 27 | 
             
                  cron_checkin.start
         | 
| 28 | 
            -
             | 
| 29 | 
            -
                  expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
         | 
| 30 | 
            -
                    message.include?("Cannot transmit cron check-in `cron-checkin-name` finish event") &&
         | 
| 31 | 
            -
                    message.include?("AppSignal is not active")
         | 
| 32 | 
            -
                  end)
         | 
| 33 | 
            -
             | 
| 34 28 | 
             
                  cron_checkin.finish
         | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 29 | 
            +
                  stop_scheduler
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  expect(logs).to contains_log(
         | 
| 32 | 
            +
                    :debug,
         | 
| 33 | 
            +
                    /Cannot transmit cron check-in `cron-checkin-name` start event .+: AppSignal is not active/
         | 
| 34 | 
            +
                  )
         | 
| 35 | 
            +
                  expect(logs).to contains_log(
         | 
| 36 | 
            +
                    :debug,
         | 
| 37 | 
            +
                    /Cannot transmit cron check-in `cron-checkin-name` finish event .+: AppSignal is not active/
         | 
| 38 | 
            +
                  )
         | 
| 39 39 | 
             
                end
         | 
| 40 40 | 
             
              end
         | 
| 41 41 |  | 
| 42 42 | 
             
              describe "when AppSignal is stopped" do
         | 
| 43 | 
            -
                it " | 
| 44 | 
            -
                  expect(transmitter).not_to receive(:transmit)
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                  expect(Appsignal.internal_logger).to receive(:debug).with("Stopping AppSignal")
         | 
| 47 | 
            -
             | 
| 43 | 
            +
                it "does not transmit any events" do
         | 
| 48 44 | 
             
                  Appsignal.stop
         | 
| 49 45 |  | 
| 50 | 
            -
                  expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
         | 
| 51 | 
            -
                    message.include?("Cannot transmit cron check-in `cron-checkin-name` start event") &&
         | 
| 52 | 
            -
                    message.include?("AppSignal is stopped")
         | 
| 53 | 
            -
                  end)
         | 
| 54 | 
            -
             | 
| 55 46 | 
             
                  cron_checkin.start
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                  expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
         | 
| 58 | 
            -
                    message.include?("Cannot transmit cron check-in `cron-checkin-name` finish event") &&
         | 
| 59 | 
            -
                    message.include?("AppSignal is stopped")
         | 
| 60 | 
            -
                  end)
         | 
| 61 | 
            -
             | 
| 62 47 | 
             
                  cron_checkin.finish
         | 
| 63 48 |  | 
| 64 | 
            -
                  expect( | 
| 65 | 
            -
             | 
| 66 | 
            -
             | 
| 49 | 
            +
                  expect(logs).to contains_log(
         | 
| 50 | 
            +
                    :debug,
         | 
| 51 | 
            +
                    "Cannot transmit cron check-in `cron-checkin-name` start event"
         | 
| 52 | 
            +
                  )
         | 
| 53 | 
            +
                  expect(logs).to contains_log(
         | 
| 54 | 
            +
                    :debug,
         | 
| 55 | 
            +
                    "Cannot transmit cron check-in `cron-checkin-name` finish event"
         | 
| 56 | 
            +
                  )
         | 
| 67 57 | 
             
                end
         | 
| 68 58 | 
             
              end
         | 
| 69 59 |  | 
| 70 60 | 
             
              describe "#start" do
         | 
| 71 | 
            -
                it " | 
| 72 | 
            -
                  expect(Appsignal.internal_logger).not_to receive(:error)
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                  expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
         | 
| 75 | 
            -
                    message.include?("Scheduling cron check-in `cron-checkin-name` start event")
         | 
| 76 | 
            -
                  end)
         | 
| 77 | 
            -
             | 
| 61 | 
            +
                it "sends a cron check-in start" do
         | 
| 78 62 | 
             
                  cron_checkin.start
         | 
| 79 63 |  | 
| 80 | 
            -
                   | 
| 81 | 
            -
                     | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
                     | 
| 86 | 
            -
             | 
| 87 | 
            -
                    :check_in_type => "cron"
         | 
| 88 | 
            -
                  )], :format => :ndjson).and_return(Net::HTTPResponse.new(nil, "200", nil))
         | 
| 64 | 
            +
                  stub_check_in_request(
         | 
| 65 | 
            +
                    :events => [
         | 
| 66 | 
            +
                      "identifier" => "cron-checkin-name",
         | 
| 67 | 
            +
                      "kind" => "start",
         | 
| 68 | 
            +
                      "check_in_type" => "cron"
         | 
| 69 | 
            +
                    ]
         | 
| 70 | 
            +
                  )
         | 
| 89 71 |  | 
| 90 72 | 
             
                  scheduler.stop
         | 
| 91 | 
            -
                end
         | 
| 92 73 |  | 
| 93 | 
            -
             | 
| 94 | 
            -
                  expect( | 
| 95 | 
            -
                     | 
| 96 | 
            -
             | 
| 74 | 
            +
                  expect(logs).to_not contains_log(:error)
         | 
| 75 | 
            +
                  expect(logs).to contains_log(
         | 
| 76 | 
            +
                    :debug,
         | 
| 77 | 
            +
                    "Scheduling cron check-in `cron-checkin-name` start event"
         | 
| 78 | 
            +
                  )
         | 
| 79 | 
            +
                  expect(logs).to contains_log(
         | 
| 80 | 
            +
                    :debug,
         | 
| 81 | 
            +
                    "Transmitted cron check-in `cron-checkin-name` start event"
         | 
| 82 | 
            +
                  )
         | 
| 83 | 
            +
                end
         | 
| 97 84 |  | 
| 85 | 
            +
                it "logs an error if it fails" do
         | 
| 98 86 | 
             
                  cron_checkin.start
         | 
| 99 87 |  | 
| 100 | 
            -
                   | 
| 101 | 
            -
                     | 
| 102 | 
            -
                       | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 106 | 
            -
                    : | 
| 107 | 
            -
             | 
| 108 | 
            -
                    :check_in_type => "cron"
         | 
| 109 | 
            -
                  )], :format => :ndjson).and_return(Net::HTTPResponse.new(nil, "499", nil))
         | 
| 88 | 
            +
                  stub_check_in_request(
         | 
| 89 | 
            +
                    :events => [
         | 
| 90 | 
            +
                      "identifier" => "cron-checkin-name",
         | 
| 91 | 
            +
                      "kind" => "start",
         | 
| 92 | 
            +
                      "check_in_type" => "cron"
         | 
| 93 | 
            +
                    ],
         | 
| 94 | 
            +
                    :response => { :status => 499 }
         | 
| 95 | 
            +
                  )
         | 
| 110 96 |  | 
| 111 97 | 
             
                  scheduler.stop
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                  expect(logs).to contains_log(
         | 
| 100 | 
            +
                    :debug,
         | 
| 101 | 
            +
                    "Scheduling cron check-in `cron-checkin-name` start event"
         | 
| 102 | 
            +
                  )
         | 
| 103 | 
            +
                  expect(logs).to contains_log(
         | 
| 104 | 
            +
                    :error,
         | 
| 105 | 
            +
                    /Failed to transmit cron check-in `cron-checkin-name` start event .+: 499 status code/
         | 
| 106 | 
            +
                  )
         | 
| 112 107 | 
             
                end
         | 
| 113 108 | 
             
              end
         | 
| 114 109 |  | 
| 115 110 | 
             
              describe "#finish" do
         | 
| 116 | 
            -
                it " | 
| 117 | 
            -
                  expect(Appsignal.internal_logger).not_to receive(:error)
         | 
| 118 | 
            -
             | 
| 119 | 
            -
                  expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
         | 
| 120 | 
            -
                    message.include?("Scheduling cron check-in `cron-checkin-name` finish event")
         | 
| 121 | 
            -
                  end)
         | 
| 122 | 
            -
             | 
| 111 | 
            +
                it "sends a cron check-in finish" do
         | 
| 123 112 | 
             
                  cron_checkin.finish
         | 
| 124 113 |  | 
| 125 | 
            -
                   | 
| 126 | 
            -
                     | 
| 127 | 
            -
             | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 130 | 
            -
                     | 
| 131 | 
            -
             | 
| 132 | 
            -
                    :check_in_type => "cron"
         | 
| 133 | 
            -
                  )], :format => :ndjson).and_return(Net::HTTPResponse.new(nil, "200", nil))
         | 
| 114 | 
            +
                  stub_check_in_request(
         | 
| 115 | 
            +
                    :events => [
         | 
| 116 | 
            +
                      "identifier" => "cron-checkin-name",
         | 
| 117 | 
            +
                      "kind" => "finish",
         | 
| 118 | 
            +
                      "check_in_type" => "cron"
         | 
| 119 | 
            +
                    ]
         | 
| 120 | 
            +
                  )
         | 
| 134 121 |  | 
| 135 122 | 
             
                  scheduler.stop
         | 
| 123 | 
            +
                  expect(logs).to_not contains_log(:error)
         | 
| 124 | 
            +
                  expect(logs).to contains_log(
         | 
| 125 | 
            +
                    :debug,
         | 
| 126 | 
            +
                    "Scheduling cron check-in `cron-checkin-name` finish event"
         | 
| 127 | 
            +
                  )
         | 
| 128 | 
            +
                  expect(logs).to contains_log(
         | 
| 129 | 
            +
                    :debug,
         | 
| 130 | 
            +
                    "Transmitted cron check-in `cron-checkin-name` finish event"
         | 
| 131 | 
            +
                  )
         | 
| 136 132 | 
             
                end
         | 
| 137 133 |  | 
| 138 | 
            -
                it " | 
| 139 | 
            -
                  expect(Appsignal.internal_logger).to receive(:debug).with(satisfy do |message|
         | 
| 140 | 
            -
                    message.include?("Scheduling cron check-in `cron-checkin-name` finish event")
         | 
| 141 | 
            -
                  end)
         | 
| 142 | 
            -
             | 
| 134 | 
            +
                it "logs an error if it fails" do
         | 
| 143 135 | 
             
                  cron_checkin.finish
         | 
| 144 136 |  | 
| 145 | 
            -
                   | 
| 146 | 
            -
                     | 
| 147 | 
            -
                       | 
| 148 | 
            -
             | 
| 149 | 
            -
             | 
| 150 | 
            -
             | 
| 151 | 
            -
                    : | 
| 152 | 
            -
             | 
| 153 | 
            -
                    :check_in_type => "cron"
         | 
| 154 | 
            -
                  )], :format => :ndjson).and_return(Net::HTTPResponse.new(nil, "499", nil))
         | 
| 137 | 
            +
                  stub_check_in_request(
         | 
| 138 | 
            +
                    :events => [
         | 
| 139 | 
            +
                      "identifier" => "cron-checkin-name",
         | 
| 140 | 
            +
                      "kind" => "finish",
         | 
| 141 | 
            +
                      "check_in_type" => "cron"
         | 
| 142 | 
            +
                    ],
         | 
| 143 | 
            +
                    :response => { :status => 499 }
         | 
| 144 | 
            +
                  )
         | 
| 155 145 |  | 
| 156 146 | 
             
                  scheduler.stop
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                  expect(logs).to contains_log(
         | 
| 149 | 
            +
                    :debug,
         | 
| 150 | 
            +
                    "Scheduling cron check-in `cron-checkin-name` finish event"
         | 
| 151 | 
            +
                  )
         | 
| 152 | 
            +
                  expect(logs).to contains_log(
         | 
| 153 | 
            +
                    :error,
         | 
| 154 | 
            +
                    /Failed to transmit cron check-in `cron-checkin-name` finish event .+: 499 status code/
         | 
| 155 | 
            +
                  )
         | 
| 157 156 | 
             
                end
         | 
| 158 157 | 
             
              end
         | 
| 159 158 |  | 
| 160 159 | 
             
              describe ".cron" do
         | 
| 161 160 | 
             
                describe "when a block is given" do
         | 
| 162 | 
            -
                  it " | 
| 163 | 
            -
                     | 
| 164 | 
            -
                      : | 
| 165 | 
            -
             | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 168 | 
            -
             | 
| 169 | 
            -
                     | 
| 170 | 
            -
             | 
| 171 | 
            -
                      : | 
| 172 | 
            -
             | 
| 173 | 
            -
             | 
| 161 | 
            +
                  it "sends a cron check-in start and finish and return the block output" do
         | 
| 162 | 
            +
                    stub_check_in_request(
         | 
| 163 | 
            +
                      :events => [
         | 
| 164 | 
            +
                        "identifier" => "cron-checkin-with-block",
         | 
| 165 | 
            +
                        "kind" => "start",
         | 
| 166 | 
            +
                        "check_in_type" => "cron"
         | 
| 167 | 
            +
                      ]
         | 
| 168 | 
            +
                    )
         | 
| 169 | 
            +
                    stub_check_in_request(
         | 
| 170 | 
            +
                      :events => [
         | 
| 171 | 
            +
                        "identifier" => "cron-checkin-with-block",
         | 
| 172 | 
            +
                        "kind" => "finish",
         | 
| 173 | 
            +
                        "check_in_type" => "cron"
         | 
| 174 | 
            +
                      ]
         | 
| 175 | 
            +
                    )
         | 
| 174 176 |  | 
| 175 177 | 
             
                    output = Appsignal::CheckIn.cron("cron-checkin-with-block") { "output" }
         | 
| 176 178 | 
             
                    expect(output).to eq("output")
         | 
| 177 179 | 
             
                  end
         | 
| 178 180 |  | 
| 179 | 
            -
                  it " | 
| 180 | 
            -
                     | 
| 181 | 
            -
                      : | 
| 182 | 
            -
             | 
| 183 | 
            -
             | 
| 184 | 
            -
             | 
| 185 | 
            -
             | 
| 186 | 
            -
                     | 
| 187 | 
            -
                      :kind => "finish",
         | 
| 188 | 
            -
                      :identifier => "cron-checkin-with-block",
         | 
| 189 | 
            -
                      :check_in_type => "cron"
         | 
| 190 | 
            -
                    ))
         | 
| 181 | 
            +
                  it "does not send a cron check-in finish event when an error is raised" do
         | 
| 182 | 
            +
                    stub_check_in_request(
         | 
| 183 | 
            +
                      :events => [
         | 
| 184 | 
            +
                        "identifier" => "cron-checkin-with-block",
         | 
| 185 | 
            +
                        "kind" => "start",
         | 
| 186 | 
            +
                        "check_in_type" => "cron"
         | 
| 187 | 
            +
                      ]
         | 
| 188 | 
            +
                    )
         | 
| 191 189 |  | 
| 192 190 | 
             
                    expect do
         | 
| 193 191 | 
             
                      Appsignal::CheckIn.cron("cron-checkin-with-block") { raise "error" }
         | 
| @@ -196,12 +194,14 @@ describe Appsignal::CheckIn::Cron do | |
| 196 194 | 
             
                end
         | 
| 197 195 |  | 
| 198 196 | 
             
                describe "when no block is given" do
         | 
| 199 | 
            -
                  it " | 
| 200 | 
            -
                     | 
| 201 | 
            -
                      : | 
| 202 | 
            -
             | 
| 203 | 
            -
             | 
| 204 | 
            -
             | 
| 197 | 
            +
                  it "only sends a cron check-in finish event" do
         | 
| 198 | 
            +
                    stub_check_in_request(
         | 
| 199 | 
            +
                      :events => [
         | 
| 200 | 
            +
                        "identifier" => "cron-checkin-without-block",
         | 
| 201 | 
            +
                        "kind" => "finish",
         | 
| 202 | 
            +
                        "check_in_type" => "cron"
         | 
| 203 | 
            +
                      ]
         | 
| 204 | 
            +
                    )
         | 
| 205 205 |  | 
| 206 206 | 
             
                    Appsignal::CheckIn.cron("cron-checkin-without-block")
         | 
| 207 207 | 
             
                  end
         |