reidmorrison/rails_semantic_logger

Rails 7: Could not log "sql.active_record" event. NoMethodError: undefined method `type' for 1:Integer

atruskie opened this issue · 1 comments

Environment

Provide at least:

  • Ruby Version: ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [x86_64-linux]
  • Rails Version: Rails 7.0.1
  • Semantic Logger Version: 4.10.0
  • Rails Semantic Logger Version: 4.10.0
  • Other Application/framework names and versions: Passenger
  • Rails configuration: N/A
  • Full Stack Trace, if an exception is being raised: see below

Note:

Expected Behavior

Upgrading from Rails 6.1 to 7 to work.

Actual Behavior

When standard active record instrumentation lines are logged in Rails 7, this occurs:

 ActiveRecord -- Could not log "sql.active_record" event. NoMethodError: undefined method `type' for 1:Integer

        elsif attr.type.binary? && attr.value
                  ^^^^^ ["/usr/local/bundle/gems/rails_semantic_logger-4.10.0/lib/rails_semantic_logger/active_record/log_subscriber.rb:162:in `render_bind_v5_0_3'", "/usr/local/bundle/gems/rails_semantic_logger-4.10.0/lib/rails_semantic_logger/active_record/log_subscriber.rb:114:in `block in bind_values_v5_1_5'", "/usr/local/bundle/gems/rails_semantic_logger-4.10.0/lib/rails_semantic_logger/active_record/log_subscriber.rb:113:in `map'", "/usr/local/bundle/gems/rails_semantic_logger-4.10.0/lib/rails_semantic_logger/active_record/log_subscriber.rb:113:in `bind_values_v5_1_5'", "/usr/local/bundle/gems/rails_semantic_logger-4.10.0/lib/rails_semantic_logger/active_record/log_subscriber.rb:33:in `sql'", "/usr/local/bundle/gems/activesupport-7.0.1/lib/active_support/subscriber.rb:149:in `finish'", "/usr/local/bundle/gems/activesupport-7.0.1/lib/active_support/log_subscriber.rb:115:in `finish'", "/usr/local/bundle/gems/activesupport-7.0.1/lib/active_support/notifications/fanout.rb:211:in `finish'", "/usr/local/bundle/gems/activesupport-7.0.1/lib/active_support/notifications/fanout.rb:76:in
<snip>

The query that generated this is:

ActiveRecord -- Site Load -- { sql: "SELECT \"sites\".* FROM \"sites\" WHERE (\"sites\".\"deleted_at\" IS NULL) AND (\"sites\".\"id\" = $1) LIMIT $2", binds: { id: 1, limit: 1 }, allocations: 8, cached: nil }

The root cause here I think is the version selection in the subscriber bins Rails 7 into the Rails 5 buckets:

elsif Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR > 0 # ~> 6.1.0
alias bind_values bind_values_v6_1
alias render_bind render_bind_v6_1
alias type_casted_binds type_casted_binds_v5_1_5
elsif Rails::VERSION::MAJOR >= 5 # ~> 5.1.5 && ~> 5.0.7 && 6.x.x
alias bind_values bind_values_v5_1_5
alias render_bind render_bind_v5_0_3
alias type_casted_binds type_casted_binds_v5_1_5

Pull Request

I'm not quite sure of the intent with the version selection, but if you can confirm that I should widen the version selection I could attempt a PR.

Yes, these monkey patches definitely rely on the version of rails being patched. The place to start is the Rails code itself. Search for the above code in the stock rails subscriber and add it to the above code along with the version number of Rails being patched.
A PR would be very welcome.