diff -Nru ruby-grape-logging-1.3.0/debian/changelog ruby-grape-logging-1.7.0/debian/changelog --- ruby-grape-logging-1.3.0/debian/changelog 2016-06-21 18:41:31.000000000 +0000 +++ ruby-grape-logging-1.7.0/debian/changelog 2017-11-02 06:46:58.000000000 +0000 @@ -1,3 +1,11 @@ +ruby-grape-logging (1.7.0-1) unstable; urgency=medium + + * Team upload + * Upstream update + * Bump Standards-Version to 4.1.1 (no changes needed) + + -- Balasankar C Thu, 02 Nov 2017 12:16:58 +0530 + ruby-grape-logging (1.3.0-1) unstable; urgency=medium * Imported Upstream version 1.3.0 diff -Nru ruby-grape-logging-1.3.0/debian/control ruby-grape-logging-1.7.0/debian/control --- ruby-grape-logging-1.3.0/debian/control 2016-06-21 18:41:31.000000000 +0000 +++ ruby-grape-logging-1.7.0/debian/control 2017-11-02 06:46:58.000000000 +0000 @@ -2,12 +2,13 @@ Section: ruby Priority: optional Maintainer: Debian Ruby Extras Maintainers -Uploaders: Antonio Terceiro , - Lucas Kanashiro +Uploaders: Lucas Kanashiro Build-Depends: debhelper (>= 9~), gem2deb, - ruby-grape -Standards-Version: 3.9.8 + rake, + ruby-grape, + ruby-rspec +Standards-Version: 4.1.1 Vcs-Git: https://anonscm.debian.org/git/pkg-ruby-extras/ruby-grape-logging.git Vcs-Browser: https://anonscm.debian.org/cgit/pkg-ruby-extras/ruby-grape-logging.git Homepage: http://github.com/aserafin/grape_logging diff -Nru ruby-grape-logging-1.3.0/debian/patches/fix-relative-path.patch ruby-grape-logging-1.7.0/debian/patches/fix-relative-path.patch --- ruby-grape-logging-1.3.0/debian/patches/fix-relative-path.patch 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/debian/patches/fix-relative-path.patch 2017-11-02 06:46:58.000000000 +0000 @@ -0,0 +1,10 @@ +--- a/spec/spec_helper.rb ++++ b/spec/spec_helper.rb +@@ -1,6 +1,6 @@ + $:.unshift '.' + +-require 'lib/grape_logging' ++require 'grape_logging' + + RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate diff -Nru ruby-grape-logging-1.3.0/debian/patches/series ruby-grape-logging-1.7.0/debian/patches/series --- ruby-grape-logging-1.3.0/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/debian/patches/series 2017-11-02 06:46:58.000000000 +0000 @@ -0,0 +1 @@ +fix-relative-path.patch diff -Nru ruby-grape-logging-1.3.0/debian/ruby-tests.rake ruby-grape-logging-1.7.0/debian/ruby-tests.rake --- ruby-grape-logging-1.3.0/debian/ruby-tests.rake 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/debian/ruby-tests.rake 2017-11-02 06:46:58.000000000 +0000 @@ -0,0 +1,5 @@ +require 'gem2deb/rake/spectask' + +Gem2Deb::Rake::RSpecTask.new do |spec| + spec.pattern = './spec/**/*_spec.rb' +end diff -Nru ruby-grape-logging-1.3.0/debian/ruby-tests.rb ruby-grape-logging-1.7.0/debian/ruby-tests.rb --- ruby-grape-logging-1.3.0/debian/ruby-tests.rb 2016-06-21 18:41:31.000000000 +0000 +++ ruby-grape-logging-1.7.0/debian/ruby-tests.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -require 'grape_logging' -puts "Loaded grape_logging version #{GrapeLogging::VERSION}: OK" diff -Nru ruby-grape-logging-1.3.0/debian/watch ruby-grape-logging-1.7.0/debian/watch --- ruby-grape-logging-1.3.0/debian/watch 2016-06-21 18:41:31.000000000 +0000 +++ ruby-grape-logging-1.7.0/debian/watch 2017-11-02 06:46:58.000000000 +0000 @@ -1,2 +1,3 @@ version=3 -http://pkg-ruby-extras.alioth.debian.org/cgi-bin/gemwatch/grape_logging .*/grape_logging-(.*).tar.gz +opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/grape_logging-$1\.tar\.gz/ \ + https://github.com/aserafin/grape_logging/tags .*/v?(\d\S+)\.tar\.gz diff -Nru ruby-grape-logging-1.3.0/.gitignore ruby-grape-logging-1.7.0/.gitignore --- ruby-grape-logging-1.3.0/.gitignore 2016-05-20 02:59:49.000000000 +0000 +++ ruby-grape-logging-1.7.0/.gitignore 2017-11-02 06:46:00.000000000 +0000 @@ -7,3 +7,4 @@ /pkg/ /spec/reports/ /tmp/ +.rspec diff -Nru ruby-grape-logging-1.3.0/grape_logging.gemspec ruby-grape-logging-1.7.0/grape_logging.gemspec --- ruby-grape-logging-1.3.0/grape_logging.gemspec 2016-05-20 02:59:49.000000000 +0000 +++ ruby-grape-logging-1.7.0/grape_logging.gemspec 2017-11-02 06:46:00.000000000 +0000 @@ -23,4 +23,6 @@ spec.add_development_dependency 'bundler', '~> 1.8' spec.add_development_dependency 'rake', '~> 10.0' -end \ No newline at end of file + spec.add_development_dependency 'rspec', '~> 3.5' + spec.add_development_dependency 'pry-byebug', '~> 3.4.2' +end diff -Nru ruby-grape-logging-1.3.0/lib/grape_logging/formatters/lograge.rb ruby-grape-logging-1.7.0/lib/grape_logging/formatters/lograge.rb --- ruby-grape-logging-1.3.0/lib/grape_logging/formatters/lograge.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/lib/grape_logging/formatters/lograge.rb 2017-11-02 06:46:00.000000000 +0000 @@ -0,0 +1,17 @@ +module GrapeLogging + module Formatters + class Lograge + def call(severity, datetime, _, data) + time = data.delete :time + attributes = { + severity: severity, + duration: time[:total], + db: time[:db], + view: time[:view], + datetime: datetime.iso8601 + }.merge(data) + ::Lograge.formatter.call(attributes) + "\n" + end + end + end +end diff -Nru ruby-grape-logging-1.3.0/lib/grape_logging/formatters/logstash.rb ruby-grape-logging-1.7.0/lib/grape_logging/formatters/logstash.rb --- ruby-grape-logging-1.3.0/lib/grape_logging/formatters/logstash.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/lib/grape_logging/formatters/logstash.rb 2017-11-02 06:46:00.000000000 +0000 @@ -0,0 +1,35 @@ +module GrapeLogging + module Formatters + class Logstash + def call(severity, datetime, _, data) + { + :'@timestamp' => datetime.iso8601, + :'@version' => '1', + :severity => severity + }.merge!(format(data)).to_json + end + + private + + def format(data) + if data.is_a?(Hash) + data + elsif data.is_a?(String) + { message: data } + elsif data.is_a?(Exception) + format_exception(data) + else + { message: data.inspect } + end + end + + def format_exception(exception) + { + exception: { + message: exception.message + } + } + end + end + end +end diff -Nru ruby-grape-logging-1.3.0/lib/grape_logging/loggers/filter_parameters.rb ruby-grape-logging-1.7.0/lib/grape_logging/loggers/filter_parameters.rb --- ruby-grape-logging-1.3.0/lib/grape_logging/loggers/filter_parameters.rb 2016-05-20 02:59:49.000000000 +0000 +++ ruby-grape-logging-1.7.0/lib/grape_logging/loggers/filter_parameters.rb 2017-11-02 06:46:00.000000000 +0000 @@ -1,23 +1,35 @@ module GrapeLogging module Loggers class FilterParameters < GrapeLogging::Loggers::Base - def initialize(filter_parameters = nil, replacement = '[FILTERED]') + AD_PARAMS = 'action_dispatch.request.parameters'.freeze + + 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 + @replacement = replacement || '[FILTERED]' + @exceptions = exceptions end def parameters(request, _) - { params: replace_parameters(request.params.clone) } + { params: safe_parameters(request) } end private - def replace_parameters(parameters) - @filter_parameters.each do |parameter_name| - if parameters.key?(parameter_name.to_s) - parameters[parameter_name.to_s] = @replacement - end + + def parameter_filter + @parameter_filter ||= ParameterFilter.new(@replacement, @filter_parameters) + end + + def safe_parameters(request) + # Now this logger can work also over Rails requests + if request.params.empty? + clean_parameters(request.env[AD_PARAMS] || {}) + else + clean_parameters(request.params) end - parameters + end + + def clean_parameters(parameters) + parameter_filter.filter(parameters).reject{ |key, _value| @exceptions.include?(key) } end end end diff -Nru ruby-grape-logging-1.3.0/lib/grape_logging/loggers/response.rb ruby-grape-logging-1.7.0/lib/grape_logging/loggers/response.rb --- ruby-grape-logging-1.3.0/lib/grape_logging/loggers/response.rb 2016-05-20 02:59:49.000000000 +0000 +++ ruby-grape-logging-1.7.0/lib/grape_logging/loggers/response.rb 2017-11-02 06:46:00.000000000 +0000 @@ -6,14 +6,22 @@ end private + # In some cases, response.body is not parseable by JSON. # 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) - begin - response.body.map{ |body| JSON.parse(body.to_s) } - rescue => e - response.body + + 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 + end + else + # Error & Exception responses + response end end end diff -Nru ruby-grape-logging-1.3.0/lib/grape_logging/middleware/request_logger.rb ruby-grape-logging-1.7.0/lib/grape_logging/middleware/request_logger.rb --- ruby-grape-logging-1.3.0/lib/grape_logging/middleware/request_logger.rb 2016-05-20 02:59:49.000000000 +0000 +++ ruby-grape-logging-1.7.0/lib/grape_logging/middleware/request_logger.rb 2017-11-02 06:46:00.000000000 +0000 @@ -9,6 +9,10 @@ GrapeLogging::Timings.append_db_runtime(event) end if defined?(ActiveRecord) + # Persist response status & response (body) + # to use int in parameters + attr_accessor :response_status, :response_body + def initialize(app, options = {}) super @@ -16,41 +20,78 @@ @reporter = if options[:instrumentation_key] Reporters::ActiveSupportReporter.new(@options[:instrumentation_key]) else - Reporters::LoggerReporter.new(@options[:logger], @options[:formatter]) + Reporters::LoggerReporter.new(@options[:logger], @options[:formatter], @options[:log_level]) end end def before reset_db_runtime start_time - invoke_included_loggers(:before) end - def after + def after(status, response) stop_time + + # Response status + @response_status = status + @response_body = response + + # Perform repotters @reporter.perform(collect_parameters) + + # Invoke loggers invoke_included_loggers(:after) nil end + # Call stack and parse responses & status. + # + # @note Exceptions are logged as 500 status & re-raised. def call!(env) - super - end + @env = env - protected + # Before hook + before - def response - begin - super - rescue + # Catch error + error = catch(:error) do + begin + @app_response = @app.call(@env) + rescue => e + # Log as 500 + message + after(e.respond_to?(:status) ? e.status : 500, e.message) + + # Re-raise exception + raise e + end nil end + + # Get status & response from app_response + # when no error occures. + if error + # Call with error & response + after(error[:status], error[:message]) + + # Throw again + throw(:error, error) + else + status, _, resp = *@app_response + + # Call after hook properly + after(status, resp) + end + + # Otherwise return original response + @app_response end + protected + def parameters { - status: response.nil? ? 'fail' : response.status, + status: response_status, time: { total: total_runtime, db: db_runtime, @@ -58,13 +99,15 @@ }, method: request.request_method, path: request.path, - params: request.params + params: request.params, + host: request.host } end private + def request - @request ||= ::Rack::Request.new(env) + @request ||= ::Rack::Request.new(@env) end def total_runtime @@ -94,7 +137,7 @@ def collect_parameters parameters.tap do |params| @included_loggers.each do |logger| - params.merge! logger.parameters(request, response) do |_, oldval, newval| + params.merge! logger.parameters(request, response_body) do |_, oldval, newval| oldval.respond_to?(:merge) ? oldval.merge(newval) : newval end end diff -Nru ruby-grape-logging-1.3.0/lib/grape_logging/reporters/logger_reporter.rb ruby-grape-logging-1.7.0/lib/grape_logging/reporters/logger_reporter.rb --- ruby-grape-logging-1.3.0/lib/grape_logging/reporters/logger_reporter.rb 2016-05-20 02:59:49.000000000 +0000 +++ ruby-grape-logging-1.7.0/lib/grape_logging/reporters/logger_reporter.rb 2017-11-02 06:46:00.000000000 +0000 @@ -1,12 +1,15 @@ module Reporters class LoggerReporter - def initialize(logger, formatter) + def initialize(logger, formatter, log_level) @logger = logger || Logger.new(STDOUT) - @logger.formatter = formatter || GrapeLogging::Formatters::Default.new if @logger.respond_to?(:formatter=) + @log_level = log_level || :info + if @logger.respond_to?(:formatter=) + @logger.formatter = formatter || @logger.formatter || GrapeLogging::Formatters::Default.new + end end def perform(params) - @logger.info params + @logger.send(@log_level, params) end end -end \ No newline at end of file +end diff -Nru ruby-grape-logging-1.3.0/lib/grape_logging/util/parameter_filter.rb ruby-grape-logging-1.7.0/lib/grape_logging/util/parameter_filter.rb --- ruby-grape-logging-1.3.0/lib/grape_logging/util/parameter_filter.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/lib/grape_logging/util/parameter_filter.rb 2017-11-02 06:46:00.000000000 +0000 @@ -0,0 +1,90 @@ +if defined?(Rails.application) + class ParameterFilter < ActionDispatch::Http::ParameterFilter + def initialize(_replacement, filter_parameters) + super(filter_parameters) + end + end +else + # + # lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/parameter_filter.rb + # we could depend on Rails specifically, but that would us way to hefty! + # + class ParameterFilter + def initialize(replacement, filters = []) + @replacement = replacement + @filters = filters + end + + def filter(params) + compiled_filter.call(params) + end + + private + + def compiled_filter + @compiled_filter ||= CompiledFilter.compile(@replacement, @filters) + end + + class CompiledFilter # :nodoc: + def self.compile(replacement, filters) + return lambda { |params| params.dup } if filters.empty? + + strings, regexps, blocks = [], [], [] + + filters.each do |item| + case item + when Proc + blocks << item + when Regexp + regexps << item + else + strings << Regexp.escape(item.to_s) + end + end + + 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? + + new replacement, regexps, deep_regexps, blocks + end + + attr_reader :regexps, :deep_regexps, :blocks + + def initialize(replacement, regexps, deep_regexps, blocks) + @replacement = replacement + @regexps = regexps + @deep_regexps = deep_regexps.any? ? deep_regexps : nil + @blocks = blocks + end + + def call(original_params, parents = []) + filtered_params = {} + + original_params.each do |key, value| + parents.push(key) if deep_regexps + if regexps.any? { |r| key =~ r } + value = @replacement + elsif deep_regexps && (joined = parents.join('.')) && deep_regexps.any? { |r| joined =~ r } + value = @replacement + elsif value.is_a?(Hash) + value = call(value, parents) + elsif value.is_a?(Array) + value = value.map { |v| v.is_a?(Hash) ? call(v, parents) : v } + elsif blocks.any? + key = key.dup if key.duplicable? + value = value.dup if value.duplicable? + blocks.each { |b| b.call(key, value) } + end + parents.pop if deep_regexps + + filtered_params[key] = value + end + + filtered_params + end + end + end +end diff -Nru ruby-grape-logging-1.3.0/lib/grape_logging/version.rb ruby-grape-logging-1.7.0/lib/grape_logging/version.rb --- ruby-grape-logging-1.3.0/lib/grape_logging/version.rb 2016-05-20 02:59:49.000000000 +0000 +++ ruby-grape-logging-1.7.0/lib/grape_logging/version.rb 2017-11-02 06:46:00.000000000 +0000 @@ -1,3 +1,3 @@ module GrapeLogging - VERSION = '1.3.0' + VERSION = '1.7.0' end diff -Nru ruby-grape-logging-1.3.0/lib/grape_logging.rb ruby-grape-logging-1.7.0/lib/grape_logging.rb --- ruby-grape-logging-1.3.0/lib/grape_logging.rb 2016-05-20 02:59:49.000000000 +0000 +++ ruby-grape-logging-1.7.0/lib/grape_logging.rb 2017-11-02 06:46:00.000000000 +0000 @@ -2,6 +2,8 @@ require 'grape_logging/version' require 'grape_logging/formatters/default' require 'grape_logging/formatters/json' +require 'grape_logging/formatters/lograge' +require 'grape_logging/formatters/logstash' require 'grape_logging/loggers/base' require 'grape_logging/loggers/response' require 'grape_logging/loggers/filter_parameters' @@ -11,3 +13,4 @@ require 'grape_logging/reporters/logger_reporter' require 'grape_logging/timings' require 'grape_logging/middleware/request_logger' +require 'grape_logging/util/parameter_filter' diff -Nru ruby-grape-logging-1.3.0/README.md ruby-grape-logging-1.7.0/README.md --- ruby-grape-logging-1.3.0/README.md 2016-05-20 02:59:49.000000000 +0000 +++ ruby-grape-logging-1.7.0/README.md 2017-11-02 06:46:00.000000000 +0000 @@ -1,6 +1,7 @@ # grape_logging [![Code Climate](https://codeclimate.com/github/aserafin/grape_logging/badges/gpa.svg)](https://codeclimate.com/github/aserafin/grape_logging) +[![Build Status](https://travis-ci.org/aserafin/grape_logging.svg?branch=master)](https://travis-ci.org/aserafin/grape_logging) ## Installation @@ -20,9 +21,11 @@ In your api file (somewhere on the top) - require 'grape_logging' - logger.formatter = GrapeLogging::Formatters::Default.new - use GrapeLogging::Middleware::RequestLogger, { logger: logger } +```ruby +require 'grape_logging' +logger.formatter = GrapeLogging::Formatters::Default.new +use GrapeLogging::Middleware::RequestLogger, { logger: logger } +``` **ProTip:** If your logger doesn't support setting formatter you can remove this line - it's optional @@ -37,23 +40,25 @@ If you prefer some other format I strongly encourage you to do pull request with new formatter class ;) You can change the formatter like so - - class MyAPI < Grape::API - use GrapeLogging::Middleware::RequestLogger, logger: logger, format: MyFormatter.new - end +```ruby +class MyAPI < Grape::API + use GrapeLogging::Middleware::RequestLogger, logger: logger, formatter: MyFormatter.new +end +``` ### Customising What Is Logged You can include logging of other parts of the request / response cycle by including subclasses of `GrapeLogging::Loggers::Base` - - class MyAPI < Grape::API - use GrapeLogging::Middleware::RequestLogger, - logger: logger, - include: [ GrapeLogging::Loggers::Response.new, - GrapeLogging::Loggers::FilterParameters.new, - GrapeLogging::Loggers::ClientEnv.new, - GrapeLogging::Loggers::RequestHeaders.new ] - end +```ruby +class MyAPI < Grape::API + use GrapeLogging::Middleware::RequestLogger, + logger: logger, + include: [ GrapeLogging::Loggers::Response.new, + GrapeLogging::Loggers::FilterParameters.new, + GrapeLogging::Loggers::ClientEnv.new, + GrapeLogging::Loggers::RequestHeaders.new ] +end +``` #### FilterParameters The `FilterParameters` logger will filter out sensitive parameters from your logs. If mounted inside rails, will use the `Rails.application.config.filter_parameters` by default. Otherwise, you must specify a list of keys to filter out. @@ -67,45 +72,60 @@ ### Logging to file and STDOUT You can log to file and STDOUT at the same time, you just need to assign new logger - - log_file = File.open('path/to/your/logfile.log', 'a') - log_file.sync = true - logger Logger.new GrapeLogging::MultiIO.new(STDOUT, log_file) +```ruby +log_file = File.open('path/to/your/logfile.log', 'a') +log_file.sync = true +logger Logger.new GrapeLogging::MultiIO.new(STDOUT, log_file) +``` + +### Set the log level + +You can control the level used to log. The default is `info`. + +```ruby +class MyAPI < Grape::API + use GrapeLogging::Middleware::RequestLogger, + logger: logger, + log_level: 'debug' +end +``` ### Logging via Rails instrumentation You can choose to not pass the logger to ```grape_logging``` but instead send logs to Rails instrumentation in order to let Rails and its configured Logger do the log job, for example. First, config ```grape_logging```, like that: - - class MyAPI < Grape::API - use GrapeLogging::Middleware::RequestLogger, - instrumentation_key: 'grape_key', - include: [ GrapeLogging::Loggers::Response.new, - GrapeLogging::Loggers::FilterParameters.new ] - end +```ruby +class MyAPI < Grape::API + use GrapeLogging::Middleware::RequestLogger, + instrumentation_key: 'grape_key', + include: [ GrapeLogging::Loggers::Response.new, + GrapeLogging::Loggers::FilterParameters.new ] +end +``` and then add an initializer in your Rails project: +```ruby +# config/initializers/instrumentation.rb - # config/initializers/instrumentation.rb - - # Subscribe to grape request and log with Rails.logger - ActiveSupport::Notifications.subscribe('grape_key') do |name, starts, ends, notification_id, payload| - Rails.logger.info payload - end +# Subscribe to grape request and log with Rails.logger +ActiveSupport::Notifications.subscribe('grape_key') do |name, starts, ends, notification_id, payload| + Rails.logger.info payload +end +``` The idea come from here: https://gist.github.com/teamon/e8ae16ffb0cb447e5b49 ### Logging exceptions If you want to log exceptions you can do it like this - - class MyAPI < Grape::API - rescue_from :all do |e| - MyAPI.logger.error e - #do here whatever you originally planned to do :) - end - end - +```ruby +class MyAPI < Grape::API + rescue_from :all do |e| + MyAPI.logger.error e + #do here whatever you originally planned to do :) + end +end +``` ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment. diff -Nru ruby-grape-logging-1.3.0/spec/lib/grape_logging/loggers/client_env_spec.rb ruby-grape-logging-1.7.0/spec/lib/grape_logging/loggers/client_env_spec.rb --- ruby-grape-logging-1.3.0/spec/lib/grape_logging/loggers/client_env_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/spec/lib/grape_logging/loggers/client_env_spec.rb 2017-11-02 06:46:00.000000000 +0000 @@ -0,0 +1,50 @@ +require 'spec_helper' +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" } + + context 'forwarded for' do + let(:mock_request) do + OpenStruct.new(env: { + "HTTP_X_FORWARDED_FOR" => forwarded_for + }) + end + + it 'sets the ip key' do + expect(subject.parameters(mock_request, nil)).to eq(ip: forwarded_for, ua: nil) + end + + it 'prefers the forwarded_for over the remote_addr' do + mock_request.env['REMOTE_ADDR'] = remote_addr + expect(subject.parameters(mock_request, nil)).to eq(ip: forwarded_for, ua: nil) + end + end + + context 'remote address' do + let(:mock_request) do + OpenStruct.new(env: { + "REMOTE_ADDR" => remote_addr + }) + end + + it 'sets the ip key' do + expect(subject.parameters(mock_request, nil)).to eq(ip: remote_addr, ua: nil) + end + end + + context 'user agent' do + let(:mock_request) do + OpenStruct.new(env: { + "HTTP_USER_AGENT" => user_agent + }) + end + + it 'sets the ua key' do + expect(subject.parameters(mock_request, nil)).to eq(ip: nil, ua: user_agent) + end + end +end diff -Nru ruby-grape-logging-1.3.0/spec/lib/grape_logging/loggers/filter_parameters_spec.rb ruby-grape-logging-1.7.0/spec/lib/grape_logging/loggers/filter_parameters_spec.rb --- ruby-grape-logging-1.3.0/spec/lib/grape_logging/loggers/filter_parameters_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/spec/lib/grape_logging/loggers/filter_parameters_spec.rb 2017-11-02 06:46:00.000000000 +0000 @@ -0,0 +1,77 @@ +require 'spec_helper' +require 'ostruct' + + +describe GrapeLogging::Loggers::FilterParameters do + let(:filtered_parameters) { %w[one four] } + + let(:mock_request) do + OpenStruct.new(params: { + this_one: 'this one', + that_one: 'one', + two: 'two', + three: 'three', + four: 'four' + }) + end + + let(:mock_request_with_deep_nesting) do + deep_clone = lambda { 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'}}) + ) + ) + ) + end + + let(:subject) do + GrapeLogging::Loggers::FilterParameters.new filtered_parameters, replacement + end + + let(:replacement) { nil } + + shared_examples 'filtering' do + it 'filters out sensitive parameters' do + expect(subject.parameters(mock_request, nil)).to eq(params: { + this_one: subject.instance_variable_get('@replacement'), + that_one: subject.instance_variable_get('@replacement'), + two: 'two', + three: 'three', + four: subject.instance_variable_get('@replacement'), + }) + end + + it 'deeply filters out sensitive parameters' do + expect(subject.parameters(mock_request_with_deep_nesting, nil)).to eq(params: { + this_one: subject.instance_variable_get('@replacement'), + that_one: subject.instance_variable_get('@replacement'), + two: 'two', + three: 'three', + four: subject.instance_variable_get('@replacement'), + five: { + this_one: subject.instance_variable_get('@replacement'), + that_one: subject.instance_variable_get('@replacement'), + two: 'two', + three: 'three', + four: subject.instance_variable_get('@replacement'), + six: { + seven: 'seven', + eight: 'eight', + one: subject.instance_variable_get('@replacement'), + }, + }, + }) + end + end + + context 'with default replacement' do + it_behaves_like 'filtering' + end + + context 'with custom replacement' do + let(:replacement) { 'CUSTOM_REPLACEMENT' } + it_behaves_like 'filtering' + end +end diff -Nru ruby-grape-logging-1.3.0/spec/lib/grape_logging/loggers/request_headers_spec.rb ruby-grape-logging-1.7.0/spec/lib/grape_logging/loggers/request_headers_spec.rb --- ruby-grape-logging-1.3.0/spec/lib/grape_logging/loggers/request_headers_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/spec/lib/grape_logging/loggers/request_headers_spec.rb 2017-11-02 06:46:00.000000000 +0000 @@ -0,0 +1,14 @@ +require 'spec_helper' +require 'ostruct' + +describe GrapeLogging::Loggers::RequestHeaders do + let(:mock_request) do + OpenStruct.new(env: {HTTP_REFERER: 'http://example.com', HTTP_ACCEPT: 'text/plain'}) + end + + it 'strips HTTP_ from the parameter' do + expect(subject.parameters(mock_request, nil)).to eq({ + headers: {'Referer' => 'http://example.com', 'Accept' => 'text/plain'} + }) + end +end diff -Nru ruby-grape-logging-1.3.0/spec/lib/grape_logging/loggers/response_spec.rb ruby-grape-logging-1.7.0/spec/lib/grape_logging/loggers/response_spec.rb --- ruby-grape-logging-1.3.0/spec/lib/grape_logging/loggers/response_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/spec/lib/grape_logging/loggers/response_spec.rb 2017-11-02 06:46:00.000000000 +0000 @@ -0,0 +1,28 @@ +require 'spec_helper' +require 'ostruct' + +describe GrapeLogging::Loggers::Response do + context 'with a parseable JSON body' do + let(:response) do + OpenStruct.new(body: [%q{{"one": "two", "three": {"four": 5}}}]) + end + + it 'returns an array of parseable JSON objects' do + expect(subject.parameters(nil, response)).to eq({ + response: [response.body.first.dup] + }) + end + end + + context 'with a body that is not parseable JSON' do + let(:response) do + OpenStruct.new(body: "this is a body") + end + + it 'just returns the body' do + expect(subject.parameters(nil, response)).to eq({ + response: response.body.dup + }) + end + end +end diff -Nru ruby-grape-logging-1.3.0/spec/lib/grape_logging/middleware/request_logger_spec.rb ruby-grape-logging-1.7.0/spec/lib/grape_logging/middleware/request_logger_spec.rb --- ruby-grape-logging-1.3.0/spec/lib/grape_logging/middleware/request_logger_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/spec/lib/grape_logging/middleware/request_logger_spec.rb 2017-11-02 06:46:00.000000000 +0000 @@ -0,0 +1,100 @@ +require 'spec_helper' +require 'rack' + +describe GrapeLogging::Middleware::RequestLogger do + let(:subject) { request.send(request_method, path) } + 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(:logger) { double('logger') } + let(:path) { '/' } + let(:request_method) { 'get' } + let(:status) { 200 } + + it 'logs to the logger' do + expect(logger).to receive('info') do |arguments| + expect(arguments[:status]).to eq 200 + expect(arguments[:method]).to eq 'GET' + expect(arguments[:params]).to be_empty + expect(arguments[:host]).to eq 'example.org' + expect(arguments).to have_key :time + expect(arguments[:time]).to have_key :total + expect(arguments[:time]).to have_key :db + expect(arguments[:time]).to have_key :view + end + subject + end + + [301, 404, 500].each do |the_status| + context "when the respnse status is #{the_status}" do + let(:status) { the_status } + it 'should log the correct status code' do + expect(logger).to receive('info') do |arguments| + expect(arguments[:status]).to eq the_status + end + subject + end + end + end + + %w[info error debug].each do |level| + context "with level #{level}" do + it 'should log at correct level' do + options[:log_level] = level + expect(logger).to receive(level) + subject + end + end + end + + context 'with a nil response' do + 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| + expect(arguments[:status]).to eq 500 + end + subject + end + end + + context 'additional_loggers' do + before 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"]) + end + + %w[get put post delete options head patch].each do |the_method| + let(:request_method) { the_method } + context "with HTTP method[#{the_method}]" do + it 'should include additional information in the log' do + expect(logger).to receive('info') do |arguments| + expect(arguments).to have_key :headers + expect(arguments).to have_key :ip + expect(arguments).to have_key :response + end + subject + end + end + end + + 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' + ) + end + parameters = { + 'replace_me' => 'should not see', + 'replace_me_too' => 'should not see', + 'cant_touch_this' => 'should see' + } + request.post path, params: parameters + end + end +end diff -Nru ruby-grape-logging-1.3.0/spec/spec_helper.rb ruby-grape-logging-1.7.0/spec/spec_helper.rb --- ruby-grape-logging-1.3.0/spec/spec_helper.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/spec/spec_helper.rb 2017-11-02 06:46:00.000000000 +0000 @@ -0,0 +1,89 @@ +$:.unshift '.' + +require 'lib/grape_logging' + +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # 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 +end diff -Nru ruby-grape-logging-1.3.0/.travis.yml ruby-grape-logging-1.7.0/.travis.yml --- ruby-grape-logging-1.3.0/.travis.yml 1970-01-01 00:00:00.000000000 +0000 +++ ruby-grape-logging-1.7.0/.travis.yml 2017-11-02 06:46:00.000000000 +0000 @@ -0,0 +1,6 @@ +language: ruby +rvm: + - 2.3.1 +cache: bundler +script: + - bundle exec rspec \ No newline at end of file