Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ jobs:
fail-fast: false
matrix:
include:
- ruby: '2.3'
rails: '5.2'
bundler: '1'
- ruby: '2.4'
rails: '5.2'
bundler: '1'
- ruby: '2.5'
rails: '6.0'
- ruby: '3.3' # v1.x sqlite3 requires Ruby 3.3
rails: '7.0'
bundler: 'default'
- ruby: '2.6'
rails: '6.0'
- ruby: '3.4'
rails: '7.1'
bundler: 'default'
- ruby: '2.7'
rails: '6.1'
- ruby: '3.4'
rails: '7.2'
bundler: 'default'
- ruby: '3.4'
rails: '8.0'
bundler: 'default'
- ruby: '3.4'
rails: '8.1'
bundler: 'default'
env:
RAILS_VERSION: ${{ matrix.rails }}
Expand All @@ -39,14 +39,14 @@ jobs:
bundler: ${{ matrix.bundler }}
bundler-cache: true
- run: bundle exec rubocop
if: matrix.ruby == '2.7'
if: matrix.rails == '7.1'
- run: bundle exec rspec --format doc
- uses: codecov/codecov-action@v3
if: matrix.ruby == '2.7'
if: matrix.rails == '7.1'
with:
files: coverage/coverage.xml
- run: bin/yardoc --fail-on-warning
if: matrix.ruby == '2.7'
if: matrix.rails == '7.1'
- run: bin/check-version

release:
Expand Down
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ require:

AllCops:
SuggestExtensions: false
TargetRubyVersion: 2.3
TargetRubyVersion: 3.3

Gemspec/DeprecatedAttributeAssignment: { Enabled: true }
Gemspec/RequireMFA: { Enabled: true }
Expand Down
21 changes: 7 additions & 14 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,16 @@ source 'https://rubygems.org'
gemspec

not_jruby = %i[ruby mingw x64_mingw].freeze
ruby_version = Gem::Version.new(RUBY_VERSION)
rails_version = Gem::Version.new(ENV.fetch('RAILS_VERSION', '5.2'))
rails_version = Gem::Version.new(ENV.fetch('RAILS_VERSION', '7.1.0'))

gem 'byebug', platforms: not_jruby
gem 'rails', "~> #{rails_version}"
gem 'redcarpet', '~> 3.5', platforms: not_jruby
gem 'rubocop', '~> 1.36.0'
gem 'rubocop-rspec', '~> 2.12.0'
gem 'simplecov', '>= 0.17.1'
gem 'simplecov-cobertura', '~> 2.1'
gem 'yard', '~> 0.9.25', platforms: not_jruby

if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6')
gem 'rubocop', '~> 1.36.0'
gem 'rubocop-rspec', '~> 2.12.0'
gem 'simplecov', '>= 0.17.1'
gem 'simplecov-cobertura', '~> 2.1'
end

if ruby_version >= Gem::Version.new('2.6')
gem 'sqlite3', '~> 1.5'
else
gem 'sqlite3', '~> 1.4', '< 1.5'
end
# Rails 7.0's ActiveRecord adapter requires sqlite3 ~> 1.4; 7.1+ allows 2.x
gem 'sqlite3', rails_version < Gem::Version.new('7.1') ? '~> 1.4' : '>= 1.4'
8 changes: 4 additions & 4 deletions epilog.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ Gem::Specification.new do |spec|
spec.files = Dir['lib/**/*.rb', '*.md', '*.txt', '.yardopts']
spec.require_paths = ['lib']

spec.required_ruby_version = '>= 2.3'
spec.required_ruby_version = '>= 3.3'

spec.add_development_dependency 'combustion', '~> 1.3'
spec.add_development_dependency 'rails', '>= 4.2', '< 7'
spec.add_development_dependency 'rails', '>= 4.2'
spec.add_development_dependency 'rspec', '~> 3.11'
spec.add_development_dependency 'rspec-rails', '~> 5.1'
spec.add_development_dependency 'sqlite3', '~> 1.3'
spec.add_development_dependency 'rspec-rails', '>= 7.0'
spec.add_development_dependency 'sqlite3', '>= 1.4'
end
2 changes: 1 addition & 1 deletion lib/epilog/filter/blacklist.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Blacklist < HashKey
attr_reader :blacklist

def initialize(blacklist = DEFAULT_BLACKLIST)
@blacklist = blacklist.map { |b| [b.to_s.downcase, nil] }.to_h
@blacklist = blacklist.to_h { |b| [b.to_s.downcase, nil] }
super()
end

Expand Down
4 changes: 2 additions & 2 deletions lib/epilog/filter/filter_parameters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ class FilterParameters < Blacklist
def filter_parameters
return @filter_parameters if @filter_parameters

filtered = ::Rails.application.config.filter_parameters.map do |p|
filtered = ::Rails.application.config.filter_parameters.to_h do |p|
[p.to_s.downcase, true]
end.to_h
end

@filter_parameters = filtered if ::Rails.initialized?
filtered
Expand Down
4 changes: 2 additions & 2 deletions lib/epilog/rails/action_controller_subscriber.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def log_end(event)
info do
{
message: response_string(event),
request: request,
request:,
response: response_hash(event),
metrics: process_metrics(event.payload[:metrics]
.merge(request_runtime: event.duration.round(2)))
Expand Down Expand Up @@ -158,7 +158,7 @@ def normalize_status(event)

def basic_message(event, message)
{
message: message,
message:,
metrics: process_metrics(duration: event.duration)
}
end
Expand Down
2 changes: 1 addition & 1 deletion lib/epilog/rails/action_view_subscriber.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def render_collection(event)

def hash(event, message)
{
message: message,
message:,
template: fix_path(event.payload[:identifier]),
layout: fix_path(event.payload[:layout]),
metrics: {
Expand Down
2 changes: 1 addition & 1 deletion lib/epilog/rails/active_job_subscriber.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def perform(event)

def event_hash(message, event)
{
message: message,
message:,
job: job_hash(event.payload[:job]),
adapter: adapter_name(event.payload[:adapter])
}
Expand Down
2 changes: 1 addition & 1 deletion lib/epilog/rails/active_record_subscriber.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class ActiveRecordSubscriber < LogSubscriber
IGNORE_PAYLOAD_NAMES = %w[SCHEMA EXPLAIN].freeze

def sql(event)
ActiveRecord::LogSubscriber.runtime += event.duration
ActiveRecord::RuntimeRegistry.sql_runtime += event.duration

return unless logger.debug?

Expand Down
20 changes: 9 additions & 11 deletions lib/epilog/rails/ext/action_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,27 @@ module ActionControllerExt
def process_action(*)
epilog_instrument('request_received')
epilog_instrument('process_request') do |payload|
begin
super
ensure
payload[:response] = response
payload[:metrics] = epilog_metrics
end
super
ensure
payload[:response] = response
payload[:metrics] = epilog_metrics
end
end

private

def epilog_instrument(name, &block)
def epilog_instrument(name, &)
ActiveSupport::Notifications.instrument(
"#{name}.action_controller",
epilog_payload,
&block
&
)
end

def epilog_payload
{
request: request,
response: response,
request:,
response:,
controller: self.class.name,
action: action_name,
context: epilog_context
Expand All @@ -37,7 +35,7 @@ def epilog_payload
def epilog_metrics
{
db_runtime: try(:db_runtime),
view_runtime: view_runtime
view_runtime:
}
end

Expand Down
11 changes: 7 additions & 4 deletions lib/epilog/rails/ext/event_delegate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
module Epilog
module EventDelegateExt
# Rails has no public API to determine the delegate for an event
# object. Add this method to allow checking if the delegate matches
# a given object.
def delegates_to?(delegate)
@delegate == delegate
# object. Add these methods to allow checking the delegate.
def delegate
@delegate
end

def delegates_to?(other)
@delegate == other
end
end
end
Expand Down
59 changes: 42 additions & 17 deletions lib/epilog/rails/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ def self.rails_6_1_higher?
]

initializer 'epilog.configure' do |app|
disable_rails_defaults

::Rails.logger ||= Logger.new($stdout)

app.config.epilog.subscriptions.each do |namespace|
Expand All @@ -57,28 +55,55 @@ def self.rails_6_1_higher?
end
end

private
# In Rails 7.1+, ActionView::LogSubscriber::Start are attached late
# in the initialization process, so we need to disable them after
# initialization completes
config.after_initialize do
disable_rails_defaults
end

def disable_rails_defaults
blacklisted_subscribers.each do |subscriber|
subscriber.patterns.each do |pattern|
unsubscribe_listeners(subscriber, pattern)
class << self
private

def disable_rails_defaults
blacklisted_subscribers.each do |subscriber|
subscriber.patterns.each do |pattern|
unsubscribe_listeners(subscriber, pattern)
end
end

# Rails 7.1 adds ActionView::LogSubscriber::Start which subscribes
# separately and logs "Rendering..." messages at the start of rendering
# see https://github.com/rails/rails/commit/9c58a54702b038b9acebdb3efa85c26156ff1987#diff-fd389a9f74e2259b56015e3f8d15a5ce33c093045dd4cb354e82d6d81fe9b06aR98-R99
unsubscribe_action_view_start_listeners
end
end

def unsubscribe_listeners(subscriber, pattern)
notifier = ActiveSupport::Notifications.notifier
notifier.listeners_for(Array.wrap(pattern).first).each do |listener|
if listener.delegates_to?(subscriber)
ActiveSupport::Notifications.unsubscribe(listener)
def unsubscribe_listeners(subscriber, pattern)
notifier = ActiveSupport::Notifications.notifier
notifier.listeners_for(Array.wrap(pattern).first).each do |listener|
if listener.delegates_to?(subscriber)
ActiveSupport::Notifications.unsubscribe(listener)
end
end
end

def unsubscribe_action_view_start_listeners
return unless defined?(ActionView::LogSubscriber::Start)

notifier = ActiveSupport::Notifications.notifier
%w[render_template.action_view render_layout.action_view].each do |pattern|
notifier.listeners_for(pattern).each do |listener|
if listener.delegate.is_a?(ActionView::LogSubscriber::Start)
ActiveSupport::Notifications.unsubscribe(listener)
end
end
end
end
end

def blacklisted_subscribers
ActiveSupport::LogSubscriber.log_subscribers.select do |subscriber|
SUBSCRIBER_BLACKLIST.include?(subscriber.class)
def blacklisted_subscribers
ActiveSupport::LogSubscriber.log_subscribers.select do |subscriber|
SUBSCRIBER_BLACKLIST.include?(subscriber.class)
end
end
end
end
Expand Down
18 changes: 9 additions & 9 deletions spec/rails/action_controller_subscriber_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def params(values)
}

expect(Rails.logger[0][0]).to eq('INFO')
expect(Rails.logger[0][3]).to match(
expect(Rails.logger[0][3]).to eq(
message: 'GET /empty started',
request: {
id: nil,
Expand Down Expand Up @@ -54,7 +54,7 @@ def params(values)
status: 200
},
metrics: {
db_runtime: 0,
db_runtime: 0.0,
view_runtime: be_within(10).of(10),
request_runtime: be_between(0, 20)
}
Expand All @@ -63,7 +63,7 @@ def params(values)
end

it 'logs a request with unpermitted parameters' do
get(:index, params(foo: 'bar'))
get(:index, **params(foo: 'bar'))

expect(Rails.logger[1][0]).to eq('DEBUG')
expect(Rails.logger[1][3]).to match(
Expand All @@ -75,15 +75,15 @@ def params(values)
end

it 'removes default Rails params' do
get(:index, params(foo: 'bar', password: 'secret'))
get(:index, **params(foo: 'bar', password: 'secret'))

expect(Rails.logger[0][3]).to match(hash_including(
expect(Rails.logger[0][3]).to include(
message: 'GET /empty started',
request: hash_including(
request: include(
path: '/empty',
params: { 'foo' => 'bar', 'password' => '[FILTERED]' }
)
))
)
end

context 'with double_request_logs = false' do
Expand All @@ -95,9 +95,9 @@ def params(values)

it 'skips start log' do
get(:index)
expect(Rails.logger[2][3]).to match(hash_including(
expect(Rails.logger[2][3]).to include(
message: 'GET /empty > 200 OK'
))
)
end
end
end
Expand Down
Loading
Loading