mirror of
https://github.com/samsonjs/grape_logging.git
synced 2026-03-25 08:55:47 +00:00
Add rubocop with a todo list (#90)
* Add rubocop with a todo list * Run rubocop as part of the CI workflow * Autofix for RuboCop: Layout/ElseAlignment * Regen autogen, removing all claude-scratchpad/* * Autofix RuboCop Layout/EmptyLine * AutoFix RuboCop Style/ZeroLengthPredicate * AutoFix RuboCop Layout/EmptyLinesAroundAccessModifier * AutoFix RuboCop Layout/EmptyLinesAroundMethodBody * AutoFix RuboCop Layout/EmptyLinesAroundBlockBody * AutoFix RuboCop Layout/EmptyLinesAroundClassBody * AutoFix RuboCop Layout/EndAlignment * AutoFix RuboCop Layout/ExtraSpacing * AutoFix RuboCop Layout/FirstHashElementIndentation * AutoFix RuboCop Layout/HashAlignment * AutoFix RuboCop Layout/IndentationWidth * Regenerate todo * AutoFix RuboCop Layout/SpaceBeforeBlockBraces * AutoFix RuboCop Layout/SpaceBeforeComma * AutoFix RuboCop Layout/SpaceInsideBlockBraces * AutoFix RuboCop Layout/SpaceInsideHashLiteralBraces * AutoFix RuboCop Layout/TrailingEmptyLines * Update ci.yml Co-authored-by: Pieter Oliver <68863060+pieterocp@users.noreply.github.com> * WIP: Remove claude-scratchpad cruft from rubocop todo * Specify files explicity in rubocop rake task * Pin rubocop version to 1.77.0 * AutoFix RuboCop Style/TrailingCommaInHashLiteral * AutoFix RuboCop Style/StringLiteralsInInterpolation * AutoFix RuboCop Style/StringLiterals * AutoFix RuboCop Style/RescueStandardError * AutoFix RuboCop Style/RedundantPercentQ * AutoFix RuboCop Style/RedundantConstantBase * AutoFix RuboCop Style/QuotedSymbols * AutoFix RuboCop Style/PercentLiteralDelimiters * AutoFix RuboCop Style/ParallelAssignment * AutoFix RuboCop Style/MultilineIfModifier * AutoFix RuboCop Style/Lambda * AutoFix RuboCop Style/IfUnlessModifier * AutoFix RuboCop Style/HashSyntax * AutoFix RuboCop Style/GuardClause * AutoFix RuboCop Style/ExpandPathArguments * AutoFix RuboCop Style/BlockDelimiters * AutoFix RuboCop Style/BlockComments * AutoFix RuboCop Lint/UnusedMethodArgument * AutoFix RuboCop Lint/SymbolConversion * Fix auto-gen formatting + RuboCop AutoFix Style/ModuleFunction * Code style --------- Co-authored-by: Pieter Oliver <pieter.oliver@nourishcare.com> Co-authored-by: Pieter Oliver <68863060+pieterocp@users.noreply.github.com>
This commit is contained in:
parent
ca80cfef6c
commit
5a9ef5d801
26 changed files with 402 additions and 208 deletions
15
.github/workflows/ci.yml
vendored
15
.github/workflows/ci.yml
vendored
|
|
@ -20,4 +20,17 @@ jobs:
|
|||
- name: Install dependencies
|
||||
run: bundle install
|
||||
- name: Run tests
|
||||
run: bundle exec rspec spec/
|
||||
run: bundle exec rake spec
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: "3.4"
|
||||
bundler-cache: true
|
||||
- name: Install dependencies
|
||||
run: bundle install
|
||||
- name: Run RuboCop
|
||||
run: bundle exec rake rubocop
|
||||
|
|
|
|||
14
.rubocop.yml
Normal file
14
.rubocop.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
inherit_from: .rubocop_todo.yml
|
||||
|
||||
AllCops:
|
||||
NewCops: enable
|
||||
|
||||
Metrics/BlockLength:
|
||||
CountAsOne: [array, hash, heredoc, method_call]
|
||||
|
||||
Metrics/ClassLength:
|
||||
CountAsOne: [array, hash, heredoc, method_call]
|
||||
|
||||
Metrics/MethodLength:
|
||||
CountAsOne: [array, hash, heredoc, method_call]
|
||||
Max: 20
|
||||
160
.rubocop_todo.yml
Normal file
160
.rubocop_todo.yml
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config`
|
||||
# on 2025-07-10 10:25:51 UTC using RuboCop version 1.77.0.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
# versions of RuboCop, may require this file to be generated again.
|
||||
|
||||
# Offense count: 3
|
||||
# Configuration parameters: EnforcedStyle, AllowedGems, Include.
|
||||
# SupportedStyles: Gemfile, gems.rb, gemspec
|
||||
# Include: **/*.gemspec, **/Gemfile, **/gems.rb
|
||||
Gemspec/DevelopmentDependencies:
|
||||
Exclude:
|
||||
- "grape_logging.gemspec"
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: Severity, Include.
|
||||
# Include: **/*.gemspec
|
||||
Gemspec/RequireMFA:
|
||||
Exclude:
|
||||
- "grape_logging.gemspec"
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: Severity, Include.
|
||||
# Include: **/*.gemspec
|
||||
Gemspec/RequiredRubyVersion:
|
||||
Exclude:
|
||||
- "grape_logging.gemspec"
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
|
||||
Lint/DuplicateBranch:
|
||||
Exclude:
|
||||
- "lib/grape_logging/util/parameter_filter.rb"
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: AllowedParentClasses.
|
||||
Lint/MissingSuper:
|
||||
Exclude:
|
||||
- "lib/grape_logging/loggers/filter_parameters.rb"
|
||||
|
||||
# Offense count: 3
|
||||
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
||||
Metrics/AbcSize:
|
||||
Max: 38
|
||||
|
||||
# Offense count: 8
|
||||
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
||||
# AllowedMethods: refine
|
||||
Metrics/BlockLength:
|
||||
Max: 90
|
||||
|
||||
# Offense count: 3
|
||||
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 18
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
||||
Metrics/PerceivedComplexity:
|
||||
Max: 19
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
|
||||
# SupportedStyles: snake_case, normalcase, non_integer
|
||||
# AllowedIdentifiers: TLS1_1, TLS1_2, capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64
|
||||
Naming/VariableNumber:
|
||||
Exclude:
|
||||
- "spec/lib/grape_logging/formatters/rails_spec.rb"
|
||||
|
||||
# Offense count: 3
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: MinBranchesCount.
|
||||
Style/CaseLikeIf:
|
||||
Exclude:
|
||||
- "lib/grape_logging/formatters/default.rb"
|
||||
- "lib/grape_logging/formatters/logstash.rb"
|
||||
- "lib/grape_logging/formatters/rails.rb"
|
||||
|
||||
# Offense count: 17
|
||||
# Configuration parameters: AllowedConstants.
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 29
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: always, always_true, never
|
||||
Style/FrozenStringLiteralComment:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/GlobalStdStream:
|
||||
Exclude:
|
||||
- "lib/grape_logging/reporters/logger_reporter.rb"
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: literals, strict
|
||||
Style/MutableConstant:
|
||||
Exclude:
|
||||
- "lib/grape_logging/version.rb"
|
||||
|
||||
# Offense count: 10
|
||||
Style/OpenStructUse:
|
||||
Exclude:
|
||||
- "spec/lib/grape_logging/loggers/client_env_spec.rb"
|
||||
- "spec/lib/grape_logging/loggers/filter_parameters_spec.rb"
|
||||
- "spec/lib/grape_logging/loggers/request_headers_spec.rb"
|
||||
- "spec/lib/grape_logging/loggers/response_spec.rb"
|
||||
|
||||
# Offense count: 3
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
|
||||
# AllowedMethods: present?, blank?, presence, try, try!
|
||||
Style/SafeNavigation:
|
||||
Exclude:
|
||||
- "lib/grape_logging/formatters/rails.rb"
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/SlicingWithRange:
|
||||
Exclude:
|
||||
- "lib/grape_logging/loggers/request_headers.rb"
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: RequireEnglish, EnforcedStyle.
|
||||
# SupportedStyles: use_perl_names, use_english_names, use_builtin_english_names
|
||||
Style/SpecialGlobalVars:
|
||||
Exclude:
|
||||
- "spec/spec_helper.rb"
|
||||
|
||||
# Offense count: 3
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: Mode.
|
||||
Style/StringConcatenation:
|
||||
Exclude:
|
||||
- "lib/grape_logging/formatters/json.rb"
|
||||
- "lib/grape_logging/formatters/lograge.rb"
|
||||
- "lib/grape_logging/formatters/logstash.rb"
|
||||
|
||||
# Offense count: 1
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments.
|
||||
# AllowedMethods: define_method
|
||||
Style/SymbolProc:
|
||||
Exclude:
|
||||
- "lib/grape_logging/util/parameter_filter.rb"
|
||||
|
||||
# Offense count: 11
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
||||
# URISchemes: http, https
|
||||
Layout/LineLength:
|
||||
Max: 203
|
||||
22
Rakefile
22
Rakefile
|
|
@ -1,9 +1,17 @@
|
|||
require 'bundler/gem_tasks'
|
||||
require 'rspec/core/rake_task'
|
||||
require 'rubocop/rake_task'
|
||||
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
RSpec::Core::RakeTask.new(:spec) do |spec|
|
||||
spec.rspec_opts = ['-fd -c']
|
||||
spec.pattern = FileList['spec/**/*_spec.rb']
|
||||
end
|
||||
|
||||
task default: :spec
|
||||
RuboCop::RakeTask.new(:rubocop) do |t|
|
||||
t.patterns = ['lib/**/*.rb', 'spec/**/*.rb', 'Rakefile', 'Gemfile', 'grape_logging.gemspec']
|
||||
end
|
||||
|
||||
task default: %i[spec rubocop]
|
||||
|
||||
desc 'Release gem and create GitHub release'
|
||||
task github_release: :release do
|
||||
|
|
@ -14,9 +22,9 @@ task github_release: :release do
|
|||
# Check if gh CLI is available
|
||||
unless system('which gh > /dev/null 2>&1')
|
||||
puts "\n⚠️ GitHub CLI (gh) not found"
|
||||
puts "To create a GitHub release with auto-generated changelog, install gh:"
|
||||
puts " brew install gh # macOS with Homebrew"
|
||||
puts " # or visit: https://github.com/cli/cli#installation"
|
||||
puts 'To create a GitHub release with auto-generated changelog, install gh:'
|
||||
puts ' brew install gh # macOS with Homebrew'
|
||||
puts ' # or visit: https://github.com/cli/cli#installation'
|
||||
puts "\nYou can manually create the release with:"
|
||||
puts " gh release create v#{GrapeLogging::VERSION} --generate-notes"
|
||||
next
|
||||
|
|
@ -28,8 +36,8 @@ task github_release: :release do
|
|||
if system('gh', 'release', 'create', version, '--generate-notes', '--verify-tag')
|
||||
puts "✅ GitHub release #{version} created successfully"
|
||||
else
|
||||
puts "❌ Failed to create GitHub release"
|
||||
puts "You can manually create it with:"
|
||||
puts '❌ Failed to create GitHub release'
|
||||
puts 'You can manually create it with:'
|
||||
puts " gh release create '#{version}' --generate-notes --verify-tag"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
lib = File.expand_path('../lib', __FILE__)
|
||||
lib = File.expand_path('lib', __dir__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
require 'grape_logging/version'
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
|
|||
spec.license = 'MIT'
|
||||
|
||||
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
||||
spec.bindir = "exe"
|
||||
spec.bindir = 'exe'
|
||||
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
||||
spec.require_paths = ['lib']
|
||||
|
||||
|
|
@ -25,4 +25,8 @@ Gem::Specification.new do |spec|
|
|||
|
||||
spec.add_development_dependency 'rake', '~> 13.3'
|
||||
spec.add_development_dependency 'rspec', '~> 3.5'
|
||||
|
||||
# This is pinned to an exact version otherwise we can't know which rules
|
||||
# are in play at any given time in different environments.
|
||||
spec.add_development_dependency 'rubocop', '1.77.0'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ module GrapeLogging
|
|||
end
|
||||
|
||||
private
|
||||
|
||||
def format_hash(hash)
|
||||
hash.keys.sort.map { |key| "#{key}=#{hash[key]}" }.join(' ')
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ module GrapeLogging
|
|||
class Logstash
|
||||
def call(severity, datetime, _, data)
|
||||
{
|
||||
:'@timestamp' => datetime.iso8601,
|
||||
:'@version' => '1',
|
||||
:severity => severity
|
||||
'@timestamp': datetime.iso8601,
|
||||
'@version': '1',
|
||||
severity: severity
|
||||
}.merge!(format(data)).to_json + "\n"
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ require 'rack/utils'
|
|||
module GrapeLogging
|
||||
module Formatters
|
||||
class Rails
|
||||
|
||||
def call(severity, datetime, _, data)
|
||||
if data.is_a?(String)
|
||||
"#{severity[0..0]} [#{datetime}] #{severity} -- : #{data}\n"
|
||||
|
|
@ -24,7 +23,7 @@ module GrapeLogging
|
|||
[
|
||||
"#{exception.message} (#{exception.class})",
|
||||
backtrace_array.join("\n")
|
||||
].reject{|line| line == ""}.join("\n")
|
||||
].reject { |line| line == '' }.join("\n")
|
||||
end
|
||||
|
||||
def format_hash(hash)
|
||||
|
|
@ -32,7 +31,7 @@ module GrapeLogging
|
|||
# Completed 200 OK in 958ms (Views: 951.1ms | ActiveRecord: 3.8ms)
|
||||
# See: actionpack/lib/action_controller/log_subscriber.rb
|
||||
|
||||
message = ""
|
||||
message = ''
|
||||
additions = []
|
||||
status = hash.delete(:status)
|
||||
params = hash.delete(:params)
|
||||
|
|
@ -47,13 +46,12 @@ module GrapeLogging
|
|||
message << " Parameters: #{params.inspect}\n" if params
|
||||
|
||||
message << "Completed #{status} #{::Rack::Utils::HTTP_STATUS_CODES[status]} in #{total_time}ms"
|
||||
message << " (#{additions.join(" | ".freeze)})" if additions.size > 0
|
||||
message << " (#{additions.join(' | '.freeze)})" unless additions.empty?
|
||||
message << "\n"
|
||||
message << "\n" if defined?(::Rails.env) && ::Rails.env.development?
|
||||
|
||||
message
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
module GrapeLogging
|
||||
module Loggers
|
||||
class Base
|
||||
def parameters(request, response)
|
||||
def parameters(_request, _response)
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ module GrapeLogging
|
|||
module Loggers
|
||||
class ClientEnv < GrapeLogging::Loggers::Base
|
||||
def parameters(request, _)
|
||||
{ ip: request.env["HTTP_X_FORWARDED_FOR"] || request.env["REMOTE_ADDR"], ua: request.env["HTTP_USER_AGENT"] }
|
||||
{ ip: request.env['HTTP_X_FORWARDED_FOR'] || request.env['REMOTE_ADDR'], ua: request.env['HTTP_USER_AGENT'] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ module GrapeLogging
|
|||
class FilterParameters < GrapeLogging::Loggers::Base
|
||||
AD_PARAMS = 'action_dispatch.request.parameters'.freeze
|
||||
|
||||
def initialize(filter_parameters = nil, replacement = nil, exceptions = %w(controller action format))
|
||||
def initialize(filter_parameters = nil, replacement = nil, exceptions = %w[controller action format])
|
||||
@filter_parameters = filter_parameters || (defined?(::Rails.application) ? ::Rails.application.config.filter_parameters : [])
|
||||
@replacement = replacement || '[FILTERED]'
|
||||
@exceptions = exceptions
|
||||
|
|
@ -30,8 +30,8 @@ module GrapeLogging
|
|||
|
||||
def clean_parameters(parameters)
|
||||
original_encoding_map = build_encoding_map(parameters)
|
||||
params = transform_key_encoding(parameters, Hash.new{ |h, _| [Encoding::ASCII_8BIT, h] })
|
||||
cleaned_params = parameter_filter.filter(params).reject{ |key, _value| @exceptions.include?(key) }
|
||||
params = transform_key_encoding(parameters, Hash.new { |h, _| [Encoding::ASCII_8BIT, h] })
|
||||
cleaned_params = parameter_filter.filter(params).reject { |key, _value| @exceptions.include?(key) }
|
||||
transform_key_encoding(cleaned_params, original_encoding_map)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
module GrapeLogging
|
||||
module Loggers
|
||||
class RequestHeaders < GrapeLogging::Loggers::Base
|
||||
|
||||
HTTP_PREFIX = 'HTTP_'.freeze
|
||||
|
||||
def parameters(request, _)
|
||||
|
|
@ -16,7 +15,6 @@ module GrapeLogging
|
|||
|
||||
{ headers: headers }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,12 +11,11 @@ module GrapeLogging
|
|||
# For example, if you POST on a PUT endpoint, response.body is egal to """".
|
||||
# It's strange, but it's the Grape behavior...
|
||||
def serialized_response_body(response)
|
||||
|
||||
if response.respond_to?(:body)
|
||||
# Rack responses
|
||||
begin
|
||||
response.body.map{ |body| JSON.parse(body.to_s) }
|
||||
rescue # No reason to have "=> e" here when we don't use it..
|
||||
response.body.map { |body| JSON.parse(body.to_s) }
|
||||
rescue StandardError # No reason to have "=> e" here when we don't use it..
|
||||
response.body
|
||||
end
|
||||
else
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ require 'grape'
|
|||
module GrapeLogging
|
||||
module Middleware
|
||||
class RequestLogger < Grape::Middleware::Base
|
||||
|
||||
if defined?(ActiveRecord)
|
||||
ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
|
||||
event = ActiveSupport::Notifications::Event.new(*args)
|
||||
GrapeLogging::Timings.append_db_runtime(event)
|
||||
end if defined?(ActiveRecord)
|
||||
end
|
||||
end
|
||||
|
||||
# Persist response status & response (body)
|
||||
# to use int in parameters
|
||||
|
|
@ -17,7 +18,8 @@ module GrapeLogging
|
|||
super
|
||||
|
||||
@included_loggers = @options[:include] || []
|
||||
@reporter = if options[:instrumentation_key]
|
||||
@reporter =
|
||||
if options[:instrumentation_key]
|
||||
Reporters::ActiveSupportReporter.new(@options[:instrumentation_key])
|
||||
else
|
||||
Reporters::LoggerReporter.new(@options[:logger], @options[:formatter], @options[:log_level])
|
||||
|
|
@ -99,7 +101,7 @@ module GrapeLogging
|
|||
path: request.path,
|
||||
params: request.params,
|
||||
host: request.host,
|
||||
request_id: env['action_dispatch.request_id'],
|
||||
request_id: env['action_dispatch.request_id']
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ module GrapeLogging
|
|||
end
|
||||
|
||||
def write(*args)
|
||||
@targets.each {|t| t.write(*args)}
|
||||
@targets.each { |t| t.write(*args) }
|
||||
end
|
||||
|
||||
def close
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@ module Reporters
|
|||
def initialize(logger, formatter, log_level)
|
||||
@logger = logger.clone || Logger.new(STDOUT)
|
||||
@log_level = log_level || :info
|
||||
if @logger.respond_to?(:formatter=)
|
||||
@logger.formatter = formatter || @logger.formatter || GrapeLogging::Formatters::Default.new
|
||||
end
|
||||
@logger.formatter = formatter || @logger.formatter || GrapeLogging::Formatters::Default.new if @logger.respond_to?(:formatter=)
|
||||
end
|
||||
|
||||
def perform(params)
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
module GrapeLogging
|
||||
module Timings
|
||||
extend self
|
||||
|
||||
def db_runtime=(value)
|
||||
def self.db_runtime=(value)
|
||||
Thread.current[:grape_db_runtime] = value
|
||||
end
|
||||
|
||||
def db_runtime
|
||||
def self.db_runtime
|
||||
Thread.current[:grape_db_runtime] ||= 0
|
||||
end
|
||||
|
||||
def reset_db_runtime
|
||||
def self.reset_db_runtime
|
||||
self.db_runtime = 0
|
||||
end
|
||||
|
||||
def append_db_runtime(event)
|
||||
def self.append_db_runtime(event)
|
||||
self.db_runtime += event.duration
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
if defined?(::Rails.application)
|
||||
if defined?(Rails.application)
|
||||
if Gem::Version.new(Rails.version) < Gem::Version.new('6.0.0')
|
||||
class ParameterFilter < ActionDispatch::Http::ParameterFilter
|
||||
def initialize(_replacement, filter_parameters)
|
||||
|
|
@ -6,7 +6,7 @@ if defined?(::Rails.application)
|
|||
end
|
||||
end
|
||||
else
|
||||
require "active_support/parameter_filter"
|
||||
require 'active_support/parameter_filter'
|
||||
|
||||
class ParameterFilter < ActiveSupport::ParameterFilter
|
||||
def initialize(_replacement, filter_parameters)
|
||||
|
|
@ -37,9 +37,11 @@ else
|
|||
|
||||
class CompiledFilter # :nodoc:
|
||||
def self.compile(replacement, filters)
|
||||
return lambda { |params| params.dup } if filters.empty?
|
||||
return ->(params) { params.dup } if filters.empty?
|
||||
|
||||
strings, regexps, blocks = [], [], []
|
||||
strings = []
|
||||
regexps = []
|
||||
blocks = []
|
||||
|
||||
filters.each do |item|
|
||||
case item
|
||||
|
|
@ -52,8 +54,8 @@ else
|
|||
end
|
||||
end
|
||||
|
||||
deep_regexps, regexps = regexps.partition { |r| r.to_s.include?("\\.".freeze) }
|
||||
deep_strings, strings = strings.partition { |s| s.include?("\\.".freeze) }
|
||||
deep_regexps, regexps = regexps.partition { |r| r.to_s.include?('\\.'.freeze) }
|
||||
deep_strings, strings = strings.partition { |s| s.include?('\\.'.freeze) }
|
||||
|
||||
regexps << Regexp.new(strings.join('|'.freeze), true) unless strings.empty?
|
||||
deep_regexps << Regexp.new(deep_strings.join('|'.freeze), true) unless deep_strings.empty?
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ require 'spec_helper'
|
|||
|
||||
describe GrapeLogging::Formatters::Rails do
|
||||
let(:formatter) { described_class.new }
|
||||
let(:severity) { "INFO" }
|
||||
let(:severity) { 'INFO' }
|
||||
let(:datetime) { Time.new('2018', '03', '02', '10', '35', '04', '+13:00') }
|
||||
|
||||
let(:exception_data) { ArgumentError.new('Message') }
|
||||
let(:hash_data) {
|
||||
let(:hash_data) do
|
||||
{
|
||||
status: 200,
|
||||
time: {
|
||||
|
|
@ -14,11 +14,11 @@ describe GrapeLogging::Formatters::Rails do
|
|||
db: 40.63,
|
||||
view: 231.76999999999998
|
||||
},
|
||||
method: "GET",
|
||||
path: "/api/endpoint",
|
||||
host: "localhost"
|
||||
}
|
||||
method: 'GET',
|
||||
path: '/api/endpoint',
|
||||
host: 'localhost'
|
||||
}
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
context 'string data' do
|
||||
|
|
@ -36,7 +36,7 @@ describe GrapeLogging::Formatters::Rails do
|
|||
message = formatter.call(severity, datetime, nil, exception_data)
|
||||
lines = message.split("\n")
|
||||
|
||||
expect(lines[0]).to eq "I [2018-03-02 10:35:04 +1300] INFO -- : Message (ArgumentError)"
|
||||
expect(lines[0]).to eq 'I [2018-03-02 10:35:04 +1300] INFO -- : Message (ArgumentError)'
|
||||
expect(lines[1]).to include '.rb'
|
||||
expect(lines.size).to be > 1
|
||||
end
|
||||
|
|
@ -52,9 +52,9 @@ describe GrapeLogging::Formatters::Rails do
|
|||
it 'includes params if included (from GrapeLogging::Loggers::FilterParameters)' do
|
||||
hash_data.merge!(
|
||||
params: {
|
||||
"some_param" => {
|
||||
value_1: "123",
|
||||
value_2: "456"
|
||||
'some_param' => {
|
||||
value_1: '123',
|
||||
value_2: '456'
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
@ -62,17 +62,18 @@ describe GrapeLogging::Formatters::Rails do
|
|||
message = formatter.call(severity, datetime, nil, hash_data)
|
||||
lines = message.split("\n")
|
||||
|
||||
expected_output = if RUBY_VERSION >= '3.4'
|
||||
expected_output =
|
||||
if RUBY_VERSION >= '3.4'
|
||||
' Parameters: {"some_param" => {value_1: "123", value_2: "456"}}'
|
||||
else
|
||||
' Parameters: {"some_param"=>{:value_1=>"123", :value_2=>"456"}}'
|
||||
end
|
||||
expect(lines.first).to eq expected_output
|
||||
expect(lines.last).to eq "Completed 200 OK in 272.4ms (Views: 231.77ms | DB: 40.63ms)"
|
||||
expect(lines.last).to eq 'Completed 200 OK in 272.4ms (Views: 231.77ms | DB: 40.63ms)'
|
||||
end
|
||||
end
|
||||
|
||||
context "unhandled data" do
|
||||
context 'unhandled data' do
|
||||
it 'returns the #inspect string representation' do
|
||||
message = formatter.call(severity, datetime, nil, [1, 2, 3])
|
||||
|
||||
|
|
@ -80,5 +81,4 @@ describe GrapeLogging::Formatters::Rails do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ require 'ostruct'
|
|||
describe GrapeLogging::Loggers::ClientEnv do
|
||||
let(:ip) { '10.0.0.1' }
|
||||
let(:user_agent) { 'user agent' }
|
||||
let(:forwarded_for) { "forwarded for" }
|
||||
let(:remote_addr) { "remote address" }
|
||||
let(:forwarded_for) { 'forwarded for' }
|
||||
let(:remote_addr) { 'remote address' }
|
||||
|
||||
context 'forwarded for' do
|
||||
let(:mock_request) do
|
||||
OpenStruct.new(env: {
|
||||
"HTTP_X_FORWARDED_FOR" => forwarded_for
|
||||
'HTTP_X_FORWARDED_FOR' => forwarded_for
|
||||
})
|
||||
end
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ describe GrapeLogging::Loggers::ClientEnv do
|
|||
context 'remote address' do
|
||||
let(:mock_request) do
|
||||
OpenStruct.new(env: {
|
||||
"REMOTE_ADDR" => remote_addr
|
||||
'REMOTE_ADDR' => remote_addr
|
||||
})
|
||||
end
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ describe GrapeLogging::Loggers::ClientEnv do
|
|||
context 'user agent' do
|
||||
let(:mock_request) do
|
||||
OpenStruct.new(env: {
|
||||
"HTTP_USER_AGENT" => user_agent
|
||||
'HTTP_USER_AGENT' => user_agent
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
require 'spec_helper'
|
||||
require 'ostruct'
|
||||
|
||||
|
||||
describe GrapeLogging::Loggers::FilterParameters do
|
||||
let(:filtered_parameters) { %w[one four] }
|
||||
|
||||
|
|
@ -12,16 +11,16 @@ describe GrapeLogging::Loggers::FilterParameters do
|
|||
'two' => 'two',
|
||||
'three' => 'three',
|
||||
'four' => 'four',
|
||||
"\xff" => 'invalid utf8',
|
||||
"\xff" => 'invalid utf8'
|
||||
})
|
||||
end
|
||||
|
||||
let(:mock_request_with_deep_nesting) do
|
||||
deep_clone = lambda { Marshal.load Marshal.dump mock_request.params }
|
||||
deep_clone = -> { Marshal.load Marshal.dump mock_request.params }
|
||||
OpenStruct.new(
|
||||
params: deep_clone.call.merge(
|
||||
'five' => deep_clone.call.merge(
|
||||
deep_clone.call.merge({'six' => {'seven' => 'seven', 'eight' => 'eight', 'one' => 'another one'}})
|
||||
deep_clone.call.merge({ 'six' => { 'seven' => 'seven', 'eight' => 'eight', 'one' => 'another one' } })
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
@ -41,7 +40,7 @@ describe GrapeLogging::Loggers::FilterParameters do
|
|||
'two' => 'two',
|
||||
'three' => 'three',
|
||||
'four' => subject.instance_variable_get('@replacement'),
|
||||
"\xff" => 'invalid utf8',
|
||||
"\xff" => 'invalid utf8'
|
||||
})
|
||||
end
|
||||
|
||||
|
|
@ -63,9 +62,9 @@ describe GrapeLogging::Loggers::FilterParameters do
|
|||
'six' => {
|
||||
'seven' => 'seven',
|
||||
'eight' => 'eight',
|
||||
'one' => subject.instance_variable_get('@replacement'),
|
||||
},
|
||||
},
|
||||
'one' => subject.instance_variable_get('@replacement')
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
@ -84,7 +83,7 @@ describe GrapeLogging::Loggers::FilterParameters do
|
|||
|
||||
it 'converts keys to strings' do
|
||||
expect(subject.parameters(mock_request, nil)).to eq(params: {
|
||||
'sneaky_symbol' => 'hey!',
|
||||
'sneaky_symbol' => 'hey!'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,38 +3,44 @@ require 'ostruct'
|
|||
|
||||
describe GrapeLogging::Loggers::RequestHeaders do
|
||||
let(:mock_request) do
|
||||
OpenStruct.new(env: {HTTP_REFERER: 'http://example.com', HTTP_ACCEPT: 'text/plain'})
|
||||
OpenStruct.new(env: { HTTP_REFERER: 'http://example.com', HTTP_ACCEPT: 'text/plain' })
|
||||
end
|
||||
|
||||
let(:mock_request_with_unhandled_headers) do
|
||||
OpenStruct.new(env: {
|
||||
HTTP_REFERER: 'http://example.com',
|
||||
"PATH_INFO"=>"/api/v1/users"
|
||||
'PATH_INFO' => '/api/v1/users'
|
||||
})
|
||||
end
|
||||
|
||||
let(:mock_request_with_long_headers) do
|
||||
OpenStruct.new(env: {
|
||||
HTTP_REFERER: 'http://example.com',
|
||||
HTTP_USER_AGENT: "Mozilla/5.0"
|
||||
HTTP_USER_AGENT: 'Mozilla/5.0'
|
||||
})
|
||||
end
|
||||
|
||||
it 'strips HTTP_ from the parameter' do
|
||||
expect(subject.parameters(mock_request, nil)).to eq({
|
||||
headers: {'Referer' => 'http://example.com', 'Accept' => 'text/plain'}
|
||||
})
|
||||
expect(subject.parameters(mock_request, nil)).to eq(
|
||||
{
|
||||
headers: { 'Referer' => 'http://example.com', 'Accept' => 'text/plain' }
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
it 'only handle things which start with HTTP_' do
|
||||
expect(subject.parameters(mock_request_with_unhandled_headers, nil)).to eq({
|
||||
headers: {'Referer' => 'http://example.com' }
|
||||
})
|
||||
expect(subject.parameters(mock_request_with_unhandled_headers, nil)).to eq(
|
||||
{
|
||||
headers: { 'Referer' => 'http://example.com' }
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
it 'substitutes _ with -' do
|
||||
expect(subject.parameters(mock_request_with_long_headers, nil)).to eq({
|
||||
headers: {'Referer' => 'http://example.com', 'User-Agent' => 'Mozilla/5.0' }
|
||||
})
|
||||
expect(subject.parameters(mock_request_with_long_headers, nil)).to eq(
|
||||
{
|
||||
headers: { 'Referer' => 'http://example.com', 'User-Agent' => 'Mozilla/5.0' }
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,25 +4,21 @@ require 'ostruct'
|
|||
describe GrapeLogging::Loggers::Response do
|
||||
context 'with a parseable JSON body' do
|
||||
let(:response) do
|
||||
OpenStruct.new(body: [{"one": "two", "three": {"four": 5}}])
|
||||
OpenStruct.new(body: [{ one: 'two', three: { four: 5 } }])
|
||||
end
|
||||
|
||||
it 'returns an array of parsed JSON objects' do
|
||||
expect(subject.parameters(nil, response)).to eq({
|
||||
response: [response.body.first],
|
||||
})
|
||||
expect(subject.parameters(nil, response)).to eq({ response: [response.body.first] })
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a body that is not parseable JSON' do
|
||||
let(:response) do
|
||||
OpenStruct.new(body: "this is a body")
|
||||
OpenStruct.new(body: 'this is a body')
|
||||
end
|
||||
|
||||
it 'just returns the body' do
|
||||
expect(subject.parameters(nil, response)).to eq({
|
||||
response: response.body,
|
||||
})
|
||||
expect(subject.parameters(nil, response)).to eq({ response: response.body })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ require 'rack'
|
|||
describe GrapeLogging::Middleware::RequestLogger do
|
||||
let(:env) { { 'action_dispatch.request_id' => 'request-abc123' } }
|
||||
let(:subject) { request.send(request_method, path, env) }
|
||||
let(:app) { proc{ [status, {} , ['response body']] } }
|
||||
let(:app) { proc { [status, {}, ['response body']] } }
|
||||
let(:stack) { described_class.new app, options }
|
||||
let(:request) { Rack::MockRequest.new(stack) }
|
||||
let(:options) { {include: [], logger: logger} }
|
||||
let(:options) { { include: [], logger: logger } }
|
||||
let(:logger) { double('logger') }
|
||||
let(:path) { '/' }
|
||||
let(:request_method) { 'get' }
|
||||
|
|
@ -51,7 +51,7 @@ describe GrapeLogging::Middleware::RequestLogger do
|
|||
end
|
||||
|
||||
context 'with a nil response' do
|
||||
let(:app) { proc{ [500, {} , nil] } }
|
||||
let(:app) { proc { [500, {}, nil] } }
|
||||
it 'should log "fail" instead of a status' do
|
||||
expect(Rack::MockResponse).to receive(:new) { nil }
|
||||
expect(logger).to receive('info') do |arguments|
|
||||
|
|
@ -66,7 +66,7 @@ describe GrapeLogging::Middleware::RequestLogger do
|
|||
options[:include] << GrapeLogging::Loggers::RequestHeaders.new
|
||||
options[:include] << GrapeLogging::Loggers::ClientEnv.new
|
||||
options[:include] << GrapeLogging::Loggers::Response.new
|
||||
options[:include] << GrapeLogging::Loggers::FilterParameters.new(["replace_me"])
|
||||
options[:include] << GrapeLogging::Loggers::FilterParameters.new(['replace_me'])
|
||||
end
|
||||
|
||||
%w[get put post delete options head patch].each do |the_method|
|
||||
|
|
@ -86,9 +86,9 @@ describe GrapeLogging::Middleware::RequestLogger do
|
|||
it 'should filter parameters in the log' do
|
||||
expect(logger).to receive('info') do |arguments|
|
||||
expect(arguments[:params]).to eq(
|
||||
"replace_me" => '[FILTERED]',
|
||||
"replace_me_too" => '[FILTERED]',
|
||||
"cant_touch_this" => 'should see'
|
||||
'replace_me' => '[FILTERED]',
|
||||
'replace_me_too' => '[FILTERED]',
|
||||
'cant_touch_this' => 'should see'
|
||||
)
|
||||
end
|
||||
parameters = {
|
||||
|
|
|
|||
|
|
@ -33,57 +33,55 @@ RSpec.configure do |config|
|
|||
# triggering implicit auto-inclusion in groups with matching metadata.
|
||||
config.shared_context_metadata_behavior = :apply_to_host_groups
|
||||
|
||||
# The settings below are suggested to provide a good initial experience
|
||||
# with RSpec, but feel free to customize to your heart's content.
|
||||
=begin
|
||||
# This allows you to limit a spec run to individual examples or groups
|
||||
# you care about by tagging them with `:focus` metadata. When nothing
|
||||
# is tagged with `:focus`, all examples get run. RSpec also provides
|
||||
# aliases for `it`, `describe`, and `context` that include `:focus`
|
||||
# metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
||||
config.filter_run_when_matching :focus
|
||||
|
||||
# Allows RSpec to persist some state between runs in order to support
|
||||
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
||||
# you configure your source control system to ignore this file.
|
||||
config.example_status_persistence_file_path = "spec/examples.txt"
|
||||
|
||||
# Limits the available syntax to the non-monkey patched syntax that is
|
||||
# recommended. For more details, see:
|
||||
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
||||
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
||||
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
||||
config.disable_monkey_patching!
|
||||
|
||||
# This setting enables warnings. It's recommended, but in some cases may
|
||||
# be too noisy due to issues in dependencies.
|
||||
config.warnings = true
|
||||
|
||||
# Many RSpec users commonly either run the entire suite or an individual
|
||||
# file, and it's useful to allow more verbose output when running an
|
||||
# individual spec file.
|
||||
if config.files_to_run.one?
|
||||
# Use the documentation formatter for detailed output,
|
||||
# unless a formatter has already been configured
|
||||
# (e.g. via a command-line flag).
|
||||
config.default_formatter = 'doc'
|
||||
end
|
||||
|
||||
# Print the 10 slowest examples and example groups at the
|
||||
# end of the spec run, to help surface which specs are running
|
||||
# particularly slow.
|
||||
config.profile_examples = 10
|
||||
|
||||
# Run specs in random order to surface order dependencies. If you find an
|
||||
# order dependency and want to debug it, you can fix the order by providing
|
||||
# the seed, which is printed after each run.
|
||||
# --seed 1234
|
||||
config.order = :random
|
||||
|
||||
# Seed global randomization in this process using the `--seed` CLI option.
|
||||
# Setting this allows you to use `--seed` to deterministically reproduce
|
||||
# test failures related to randomization by passing the same `--seed` value
|
||||
# as the one that triggered the failure.
|
||||
Kernel.srand config.seed
|
||||
=end
|
||||
# The settings below are suggested to provide a good initial experience
|
||||
# with RSpec, but feel free to customize to your heart's content.
|
||||
# # This allows you to limit a spec run to individual examples or groups
|
||||
# # you care about by tagging them with `:focus` metadata. When nothing
|
||||
# # is tagged with `:focus`, all examples get run. RSpec also provides
|
||||
# # aliases for `it`, `describe`, and `context` that include `:focus`
|
||||
# # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
|
||||
# config.filter_run_when_matching :focus
|
||||
#
|
||||
# # Allows RSpec to persist some state between runs in order to support
|
||||
# # the `--only-failures` and `--next-failure` CLI options. We recommend
|
||||
# # you configure your source control system to ignore this file.
|
||||
# config.example_status_persistence_file_path = "spec/examples.txt"
|
||||
#
|
||||
# # Limits the available syntax to the non-monkey patched syntax that is
|
||||
# # recommended. For more details, see:
|
||||
# # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
||||
# # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
||||
# # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
||||
# config.disable_monkey_patching!
|
||||
#
|
||||
# # This setting enables warnings. It's recommended, but in some cases may
|
||||
# # be too noisy due to issues in dependencies.
|
||||
# config.warnings = true
|
||||
#
|
||||
# # Many RSpec users commonly either run the entire suite or an individual
|
||||
# # file, and it's useful to allow more verbose output when running an
|
||||
# # individual spec file.
|
||||
# if config.files_to_run.one?
|
||||
# # Use the documentation formatter for detailed output,
|
||||
# # unless a formatter has already been configured
|
||||
# # (e.g. via a command-line flag).
|
||||
# config.default_formatter = 'doc'
|
||||
# end
|
||||
#
|
||||
# # Print the 10 slowest examples and example groups at the
|
||||
# # end of the spec run, to help surface which specs are running
|
||||
# # particularly slow.
|
||||
# config.profile_examples = 10
|
||||
#
|
||||
# # Run specs in random order to surface order dependencies. If you find an
|
||||
# # order dependency and want to debug it, you can fix the order by providing
|
||||
# # the seed, which is printed after each run.
|
||||
# # --seed 1234
|
||||
# config.order = :random
|
||||
#
|
||||
# # Seed global randomization in this process using the `--seed` CLI option.
|
||||
# # Setting this allows you to use `--seed` to deterministically reproduce
|
||||
# # test failures related to randomization by passing the same `--seed` value
|
||||
# # as the one that triggered the failure.
|
||||
# Kernel.srand config.seed
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue