Giter VIP home page Giter VIP logo

grape_logging's Introduction

grape_logging

Code Climate Build Status

Installation

Add this line to your application's Gemfile:

gem 'grape_logging'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install grape_logging

Basic Usage

In your api file (somewhere on the top), insert grape logging middleware before grape error middleware. This is important due to the behaviour of lib/grape/middleware/error.rb, which manipulates the status of the response when there is an error.

require 'grape_logging'
logger.formatter = GrapeLogging::Formatters::Default.new
insert_before Grape::Middleware::Error, GrapeLogging::Middleware::RequestLogger, { logger: logger }

ProTip: If your logger doesn't support setting formatter you can remove this line - it's optional

Features

Log Format

There are formatters provided for you, or you can provide your own.

GrapeLogging::Formatters::Default

[2015-04-16 12:52:12 +0200] INFO -- 200 -- total=2.06 db=0.36 -- PATCH /api/endpoint params={"some_param"=>{"value_1"=>"123", "value_2"=>"456"}}

GrapeLogging::Formatters::Json

{
  "date": "2015-04-16 12:52:12+0200",
  "severity": "INFO",
  "data": {
    "status": 200,
    "time": {
      "total": 2.06,
      "db": 0.36,
      "view": 1.70
    },
    "method": "PATCH",
    "path": "/api/endpoint",
    "params": {
      "value_1": "123",
      "value_2": "456"
    },
    "host": "localhost"
  }
}

GrapeLogging::Formatters::Lograge

severity="INFO", duration=2.06, db=0.36, view=1.70, datetime="2015-04-16 12:52:12+0200", status=200, method="PATCH", path="/api/endpoint", params={}, host="localhost"

GrapeLogging::Formatters::Logstash

{
  "@timestamp": "2015-04-16 12:52:12+0200",
  "severity": "INFO",
  "status": 200,
  "time": {
    "total": 2.06,
    "db": 0.36,
    "view": 1.70
  },
  "method": "PATCH",
  "path": "/api/endpoint",
  "params": {
    "value_1": "123",
    "value_2": "456"
  },
  "host": "localhost"
}

GrapeLogging::Formatters::Rails

Rails will print the "Started..." line:

Started GET "/api/endpoint" for ::1 at 2015-04-16 12:52:12 +0200
  User Load (0.7ms)  SELECT "users".* FROM "users" WHERE  "users"."id" = $1
  ...

The Rails formatter adds the last line of the request, like a standard Rails request:

Completed 200 OK in 349ms (Views: 250.1ms | DB: 98.63ms)

Custom

You can provide your own class that implements the call method returning a String:

def call(severity, datetime, _, data)
   ...
end

You can change the formatter like so

class MyAPI < Grape::API
  use GrapeLogging::Middleware::RequestLogger, logger: logger, formatter: MyFormatter.new
end

If you prefer some other format I strongly encourage you to do pull request with new formatter class ;)

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

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.

ClientEnv

The ClientEnv logger will add ip and user agent ua in your log.

RequestHeaders

The RequestHeaders logger will add request headers in your log.

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)

Set the log level

You can control the level used to log. The default is info.

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

and then add an initializer in your Rails project:

# 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

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

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.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release to create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

  1. Fork it ( https://github.com/aserafin/grape_logging/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

grape_logging's People

Contributors

aserafin avatar daveharris avatar diguliu avatar e1senh0rn avatar elieteyssedou avatar flanger001 avatar glaucocustodio avatar guizmaii avatar jason-uh avatar jtmarmon avatar julianalucena avatar liukgg avatar luong-komorebi avatar luxflux avatar marshall-lee avatar scauglog avatar shuuuuun avatar strnadj avatar vorce avatar yalongzhang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

grape_logging's Issues

Log fail status code

Is there a way to log the status code for a fail? So instead of getting :status=>"fail" I would like to see :status=>405 or whatever.

`ArgumentError` is raised if the keys of `parameters` include invalid byte sequence

We use GrapeLogging::Middleware::RequestLogger like below:

class MyApi < Grape::API
  use GrapeLogging::Middleware::RequestLogger, {
    include: [GrapeLogging::Loggers::FilterParameters.new],
  }
  post {}
end

If we send a request whose body includes invalid byte sequence, ArgumentError is raised.

echo -e '{"\xff":1}' | curl -X POST -H 'Content-Type: application/json' localhost:3000 --data-binary @-

Here is the server log:

ArgumentError (invalid byte sequence in UTF-8):

actionpack (5.2.1) lib/action_dispatch/http/parameter_filter.rb:63:in `=~'
actionpack (5.2.1) lib/action_dispatch/http/parameter_filter.rb:63:in `block (2 levels) in call'
actionpack (5.2.1) lib/action_dispatch/http/parameter_filter.rb:63:in `any?'
actionpack (5.2.1) lib/action_dispatch/http/parameter_filter.rb:63:in `block in call'
actionpack (5.2.1) lib/action_dispatch/http/parameter_filter.rb:61:in `each'
actionpack (5.2.1) lib/action_dispatch/http/parameter_filter.rb:61:in `call'
actionpack (5.2.1) lib/action_dispatch/http/parameter_filter.rb:15:in `filter'
grape_logging (1.7.0) lib/grape_logging/loggers/filter_parameters.rb:32:in `clean_parameters'
grape_logging (1.7.0) lib/grape_logging/loggers/filter_parameters.rb:27:in `safe_parameters'
grape_logging (1.7.0) lib/grape_logging/loggers/filter_parameters.rb:13:in `parameters'
grape_logging (1.7.0) lib/grape_logging/middleware/request_logger.rb:140:in `block (2 levels) in collect_parameters'
(snip)

Formatter setting doesn't seem to work

Hi, thanks you for making this great gem GrapeLogging.
I have a problem with formatter setting.

I'm trying to change log formatter from default one to GrapeLogging::Formatters::Lograge, but it doesn't seem to work.

For example, "time" key exists even after update.
Here is an actual response in localhost.

response (some params are masked)

{:status=>403, :time=>{:total=>189.43, :db=>3.74, :view=>185.69}, :method=>"POST", :path=>"/api/v1/users/login", :params=>{"xxx"=>"xxx", "xxx"=>"xxx"}, :host=>"localhost", :response=>{:xxx=>"xxx"}}

And here is my related gem versions and related codes.

versions

  • rails => 5.0.1
  • grape => 1.0.1
  • grape_logging => 1.7.0

codes

  • app/api/xxx/v1/base.rb
class XXX::V1
  class Base < Grape::API
    use GrapeLogging::Middleware::RequestLogger,
        instrumentation_key: 'grape_key',
        formatter: GrapeLogging::Formatters::Lograge.new,
        include: [
          GrapeLogging::Loggers::Response.new,
          GrapeLogging::Loggers::FilterParameters.new,
          GrapeLogging::Loggers::RequestHeaders.new,
        ]
  end
end
  • config/environments/development.rb
Rails.application.configure do
  ...
  config.logger = ActFluentLoggerRails::Logger.new
  config.lograge.enabled = true
  config.lograge.formatter = Lograge::Formatters::Raw.new
end
  • config/initializers/lograge.rb
Rails.application.configure do
  config.lograge.base_controller_class = 'Grape::API'
end

Could you tell me how to fix it?
Thanks.

disable logging during tests

I use grape_logging in a rails app and I'd like to disable it when I run my test suite. What should I write in my rails_helper ?

Make formatter optional

There are logger implementations that don't expose `.formatter. Make grape-logging compatible with them!

Thread-safety

I was looking into expanding our API logging when I stumbled upon this Gem. When exploring its inner workings I found an issue with your middleware, it is not thread-safe because instance variables are used and passed whilst the middleware is used in a concurrent manner. See:
https://github.com/aserafin/grape_logging/blob/6e562a278864a382bf5cf37cda7bad8924f0ad29/lib/grape_logging/middleware/request_logger.rb#L60C34-L60C38

The @env can be overwritten during the call! causing the request and responds to mismatch, effectively sending a response that was meant for another client.

You could add this disclaimer to the readme, patch it or yank the gem altogether as it seems to no longer be maintained. Since I am not a user I won't be submitting a PR to fix it, but thank you for creating the gem regardless, its a nice insight to see how you solved it.

wrong status code 500 logged

I am using the newest gem versions. It looks like the logger is executed before the rescue_from which sets the statuscode.

  logger.formatter = GrapeLogging::Formatters::Default.new
  use GrapeLogging::Middleware::RequestLogger, logger: logger, include: [ GrapeLogging::Loggers::Response.new,
                                                                               GrapeLogging::Loggers::FilterParameters.new,
                                                                               GrapeLogging::Loggers::ClientEnv.new,
                                                                               GrapeLogging::Loggers::RequestHeaders.new ]

  rescue_from WineBouncer::Errors::OAuthUnauthorizedError do |e|
    error! e, 401
  end

undefined method `keys' + undefined method `clear_tags!'

Hi,

I'm using grape inside Rails. When using Rails.logger as logger and GrapeLogging::Formatters::Default as formatter, I receive these exceptions ( complete backtrace ) when grape tries to log the request.

This is my configuration:

module Foobar
  class Api < Grape::API
    logger Rails.logger

    use GrapeLogging::Middleware::RequestLogger,
      logger: logger,
      formatter: GrapeLogging::Formatters::Default.new,
      include: [ GrapeLogging::Loggers::Response.new,
                 GrapeLogging::Loggers::FilterParameters.new,
                 GrapeLogging::Loggers::ClientEnv.new,
                 GrapeLogging::Loggers::RequestHeaders.new ]

I noticed that if I change logger Rails.logger with logger Rails.logger.dup it works, without any exception. Why?

uninitialized constant ActiveSupport::ParameterFilter in version 1.8.3 with rails 6

I am on Rails 6. Version 1.8.2 and 1.8.3 and throwing following error:

`block in load_missing_constant': uninitialized constant ActiveSupport::ParameterFilter (NameError)

however 1.8.1 is working. Disabling the gem makes the app work again:

Loading development environment (Rails 6.0.0)
irb(main):001:0> ActiveSupport::ParameterFilter
=> ActiveSupport::ParameterFilter

Not working with grape 0.12

After upgrading I see:

NoMethodError (undefined method `downcase' for 2:Fixnum)

An issue that response method tries to get an array values from @app_response, but it can't because @app_response stores Rack::Response instead of an array.

Don't know yet how to fix that issue, any suggestion can be helpful and transformed into a PR.

Push update to rubygems

Is it possible to push an update version v1.4.0 to rubygems?
I would like to have it in my project.

Thanks!

GrapeLogging is slow in production when running long time.

I'm using GrapeLogging version 1.8.1 (Latest release at this time) on my production environment. But If I running for long time it's consume many time of my process (Around 80~90% only for GrapeLogging).

I tracking time by New Relic. Segment of process is "GrapeLogging::Middleware::RequestLogger#call"

I'm not sure about these problem came from GrapeLogging but I want to know anyone face these problem like me? How to deal with it?

I'm using jruby:9.1-jre-alpine docker's base image.

ActiveSupport::ParameterFilter depends on Rails > 6.0

The most recent release of grape_logging depends on ActiveSupport::ParameterFilter, which is only compatible with Rails 6.

This broke my Rails 5.2 application upon upgrading. Please update the gemspec to prevent updating past 1.8.1 for Rails 5.2 or modify the code to handle both Rails versions.

NameError: uninitialized constant Grape::Middleware::Base::Helpers

Ref: ruby-grape/grape#1939 (comment)

Here is the complete stack:

NameError: uninitialized constant Grape::Middleware::Base::Helpers
  /Users/pboling/.asdf/installs/ruby/2.5.7/lib/ruby/gems/2.5.0/gems/grape-1.3.1/lib/grape/middleware/base.rb:8:in `<class:Base>'
  /Users/pboling/.asdf/installs/ruby/2.5.7/lib/ruby/gems/2.5.0/gems/grape-1.3.1/lib/grape/middleware/base.rb:7:in `<module:Middleware>'
  /Users/pboling/.asdf/installs/ruby/2.5.7/lib/ruby/gems/2.5.0/gems/grape-1.3.1/lib/grape/middleware/base.rb:6:in `<module:Grape>'
  /Users/pboling/.asdf/installs/ruby/2.5.7/lib/ruby/gems/2.5.0/gems/grape-1.3.1/lib/grape/middleware/base.rb:5:in `<top (required)>'
  /Users/pboling/.asdf/installs/ruby/2.5.7/lib/ruby/gems/2.5.0/gems/grape_logging-1.8.3/lib/grape_logging/middleware/request_logger.rb:1:in `require'
  /Users/pboling/.asdf/installs/ruby/2.5.7/lib/ruby/gems/2.5.0/gems/grape_logging-1.8.3/lib/grape_logging/middleware/request_logger.rb:1:in `<top (required)>'
  /Users/pboling/.asdf/installs/ruby/2.5.7/lib/ruby/gems/2.5.0/gems/grape_logging-1.8.3/lib/grape_logging.rb:16:in `require'
  /Users/pboling/.asdf/installs/ruby/2.5.7/lib/ruby/gems/2.5.0/gems/grape_logging-1.8.3/lib/grape_logging.rb:16:in `<top (required)>'
  config.ru:3:in `require'
  config.ru:3:in `block in <main>'
  /Users/pboling/.asdf/installs/ruby/2.5.7/lib/ruby/gems/2.5.0/gems/rack-2.2.2/lib/rack/builder.rb:116:in `eval'

Removing grape_logging from the project fixes the issue. @dblock says:

If this fixes that feels like grape_logging should be doing a require 'grape'. Open an issue in that repo.

Seems like this repo needs to require 'grape' somewhere.

UPDATE: If I move require 'grape_logging' to spot in the load order after I am sure grape has been loaded, then this error goes away. This gem, as is, doesn't load grape properly on it's own, but allowing bundler to load grape works.

In other words, if I have a require 'grape_logging' early on, before bundler loads my environment, then I get this error with latest version of grape.

Hat tip to @robert-hromej who had the right idea.

[question] Can I include multiple log levels instead of just one?

class API < Grape::API
  # ...
  logger.formatter = GrapeLogging::Formatters::Default.new
  log_file = File.open('./log/logfile.log', 'a')
  log_file.sync = true
  logger Logger.new GrapeLogging::MultiIO.new(STDOUT, log_file)
  insert_after Rack::Head, GrapeLogging::Middleware::RequestLogger, logger: logger, log_level: :info, include: [
    GrapeLogging::Loggers::ClientEnv.new,
    GrapeLogging::Loggers::RequestHeaders.new
  ]

  # ...
end

If I am understanding the readme file correctly, I am only able to specify one log log level, is there a way to specify multiple? And if there is, can it be added to the readme , that would be amazing :)

Pass status code to loggers

Right now the loggers only have access to the request and response_body, but it would be nice to have access to the status code as well. For now, we're working around the problem by storing the intended status code in the request.env, but this is not ideal.

Not sure the best way to support this without breaking compatibility of the parameters call in

params.merge! logger.parameters(request, response_body) do |_, oldval, newval|
. We could check if the signature accepts an optional 3rd argument?

Problems using formatters with rails 5 logger

I ran into #48 and from what I can tell, formatters would not work when passing in the Rails.logger. Suppose we have this:

use GrapeLogging::Middleware::RequestLogger, { logger: Rails.logger, formatter: GrapeLogging::Formatters::Json.new }

It looks like log reporter would attempt to set the Rails.logger formatter globally

  class LoggerReporter
    def initialize(logger, formatter, log_level)
      @logger = logger || Logger.new(STDOUT)
      @log_level = log_level || :info
      if @logger.respond_to?(:formatter=)
        @logger.formatter = formatter || @logger.formatter || GrapeLogging::Formatters::Default.new
      end
    end

This won't work because Rails assumes the formatter is of type ActiveSupport::TaggedLogging::Formatter and we get the error mentioned in #48.

undefined method `clear_tags!

Either way I am not sure we would actually want to set the GrapeLogging Formatter globally on the Rails.logger as this seems a bit heavy handed.

To get around this issue, I used the instrumentation_key feature and avoid using Rails.logger and GrapeLogging formatters altogether.

use GrapeLogging::Middleware::RequestLogger, {
  instrumentation_key: 'grape_logging',
  include: [GrapeLogging::Loggers::FilterParameters.new]
}

ActiveSupport::Notifications.subscribe('grape_logging') do |_name, _starts, _ends, _notification_id, payload|
  Rails.logger.info("API request #{payload.to_json}")
end

This is fine for my purposes but I am not sure of the right way to use grape log formatters and Rails.logger together.

Filtering for all loggers

Currently only FilterParameters logger exists to filter sensitive information from request parameters, but similarly sensitive information can also be contained in Request Headers as well as Response (e.g. the Authorization header, which could contain access token).

I have subclassed the FilterParameters logger for now, to achieve such result, but probably it would be best to move the filtering to Logger::Base.

  class FilterResponseLogger < GrapeLogging::Loggers::FilterParameters
    def parameters(_, response)
      response && response.respond_to?(:body) ? { response: clean_response(response) } : {}
    end

    private
    def clean_response(response)
      case response.header['Content-Type']
      when 'application/json'
        body = JSON.parse(response.body.first) #it's stored inside an array
        parameter_filter.filter(body).reject{ |key, _value| @exceptions.include?(key) }
      else
        # Better to not log, than log with sensitive data
        "FilterResponseLogger: Don't know how to filter '#{response.header['Content-Type']}' response, skipping."
      end
    rescue
      # Can't really log the error message here, as that could itself contain sensitive data
      # e.g. JSON.parse with invalid data will put whole data into the error message.
      "FilterResponseLogger: Error filtering response, skipping."
    end
  end

  class FilterRequestHeaderLogger < GrapeLogging::Loggers::FilterParameters
    HTTP_PREFIX = 'HTTP_'.freeze

    def parameters(request, _)
      headers = {}

      request.env.each_pair do |k, v|
        next unless k.to_s.start_with? HTTP_PREFIX

        k = k[HTTP_PREFIX.size..-1].split('_').each(&:capitalize!).join('-')
        headers[k] = v
      end

      { headers: clean_headers(headers) }
    end

    private
    def clean_headers(headers)
      parameter_filter.filter(headers).reject{ |key, _value| @exceptions.include?(key) }
    rescue
      # Can't really log the error message here, as that could itself contain sensitive data
      # e.g. JSON.parse with invalid data will put whole data into the error message.
      "FilterRequestHeaderLogger: Error filtering request headers, skipping."
    end
  end

What do you think?

Using GrapeLogging::Formatters logs does not trigger Logstash file input

Hi there,

I was doing some tests with grape_logging and Logstash, using GrapeLogging::Formatters::Logstash, and i encountered a problem. My logs where been written into the log file but Logstash wasn't getting any of them.

That also happened when i used GrapeLogging::Formatters::Json.

Using the Default formatter doesn't cause this problem.

logstash.conf

input {
  file {
    type => "test"
    path =>"/tmp/log/*.log"
  }
}
filter {

}
output {
  elasticsearch {
    index => "logstash"
    hosts => ["localhost:9200"]
  }
  stdout { }
}

api.rb

class API < Grape::API
  format :json
  log_file = File.open('/tmp/log/test.log', 'a+')
  log_file.sync = true
  logger Logger.new GrapeLogging::MultiIO.new(STDOUT, log_file)
  logger.formatter = GrapeLogging::Formatters::Logstash.new
  use GrapeLogging::Middleware::RequestLogger, {
    logger: logger,
    include: [ GrapeLogging::Loggers::Response.new,
                    GrapeLogging::Loggers::FilterParameters.new,
                    GrapeLogging::Loggers::ClientEnv.new,
                    GrapeLogging::Loggers::RequestHeaders.new ]
   }
end

Failing tests

Hi,

Whilst building this against Ruby2.7 and grape (1.3.1), I get the following failures:

Failures:

  1) GrapeLogging::Formatters::Rails#call exception data returns a string with a backtrace
     Failure/Error: expect(lines[1]).to include 'grape_logging'
       expected "\t/usr/share/rubygems-integration/all/gems/rspec-core-3.9.1/lib/rspec/core/example.rb:257:in `instance_exec'" to include "grape_logging"
     # ./spec/lib/grape_logging/formatters/rails_spec.rb:40:in `block (4 levels) in <top (required)>'

  2) GrapeLogging::Loggers::Response with a parseable JSON body returns an array of parseable JSON objects
     Failure/Error:
       expect(subject.parameters(nil, response)).to eq({
         response: [response.body.first.dup]
       })
     
       expected: {:response=>["{\"one\": \"two\", \"three\": {\"four\": 5}}"]}
            got: {:response=>[{"one"=>"two", "three"=>{"four"=>5}}]}
     
       (compared using ==)
     
       Diff:
       @@ -1,2 +1,2 @@
       -:response => ["{\"one\": \"two\", \"three\": {\"four\": 5}}"],
       +:response => [{"one"=>"two", "three"=>{"four"=>5}}],
       
     # ./spec/lib/grape_logging/loggers/response_spec.rb:11:in `block (3 levels) in <top (required)>'

Finished in 0.10391 seconds (files took 1.5 seconds to load)
34 examples, 2 failures

Failed examples:

rspec ./spec/lib/grape_logging/formatters/rails_spec.rb:33 # GrapeLogging::Formatters::Rails#call exception data returns a string with a backtrace
rspec ./spec/lib/grape_logging/loggers/response_spec.rb:10 # GrapeLogging::Loggers::Response with a parseable JSON body returns an array of parseable JSON objects

Logging to file and not STDOUT

Hello, i used the logging to a file option and it works well.
I'm trying to remove logging to STDOUT and keep only logging to an external file.
Is that possible?

NoMethodError: undefined method `+' for nil:NilClass

I have a Grape API in a Rails application, and I'm sub-classing GrapeLogging::Middleware::RequestLogger so I can sanitize the #parameters method. I'm getting an error in production that is originating at /gems/grape_logging-1.0.2/lib/grape_logging/middleware/request_logger.rb:11 in block in before. It looks like env[:db_duration] is returning nil. Details below.


Versions:

  • grape (0.10.1)
  • grape-entity (0.4.4)
  • grape_logging (1.0.2)
  • rails (4.2.1)

Sub-class:

module Api::Middleware
  class RequestLogger < GrapeLogging::Middleware::RequestLogger
    protected

    def parameters(response, duration)
      filters = Rails.application.config.filter_parameters
      ActionDispatch::Http::ParameterFilter.new(filters).filter(super)
    end
  end
end

Usage:

use Api::Middleware::RequestLogger, { logger: Rails.logger }

Stacktrace:

/gems/grape_logging-1.0.2/lib/grape_logging/middleware/request_logger.rb:11 in block in before
/gems/activesupport-4.2.1/lib/active_support/notifications/fanout.rb:127 in call
/gems/activesupport-4.2.1/lib/active_support/notifications/fanout.rb:127 in finish
/gems/activesupport-4.2.1/lib/active_support/notifications/fanout.rb:46 in block in finish
/gems/activesupport-4.2.1/lib/active_support/notifications/fanout.rb:46 in each
/gems/activesupport-4.2.1/lib/active_support/notifications/fanout.rb:46 in finish
/gems/activesupport-4.2.1/lib/active_support/notifications/instrumenter.rb:36 in finish
/gems/activesupport-4.2.1/lib/active_support/notifications/instrumenter.rb:25 in instrument
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:467 in log
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:154 in execute
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql/schema_statements.rb:275 in client_min_messages=
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:673 in configure_connection
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:658 in connect
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:242 in initialize
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:44 in new
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:44 in postgresql_connection
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:438 in new_connection
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:448 in checkout_new_connection
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:422 in acquire_connection
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:349 in block in checkout
/data/gdweb/.rbenv/versions/2.1.5/lib/ruby/2.1.0/monitor.rb:211 in mon_synchronize
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:348 in checkout
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:263 in block in connection
/data/gdweb/.rbenv/versions/2.1.5/lib/ruby/2.1.0/monitor.rb:211 in mon_synchronize
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:262 in connection
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:567 in retrieve_connection
/gems/activerecord-4.2.1/lib/active_record/connection_handling.rb:113 in retrieve_connection
/gems/activerecord-4.2.1/lib/active_record/connection_handling.rb:87 in connection
/gems/activerecord-4.2.1/lib/active_record/query_cache.rb:51 in restore_query_cache_settings
/gems/activerecord-4.2.1/lib/active_record/query_cache.rb:43 in rescue in call
/gems/activerecord-4.2.1/lib/active_record/query_cache.rb:31 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/activerecord-4.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:649 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/actionpack-4.2.1/lib/action_dispatch/middleware/callbacks.rb:29 in block in call
/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:88 in call
/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:88 in _run_callbacks
/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:776 in _run_call_callbacks
/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:81 in run_callbacks
/gems/actionpack-4.2.1/lib/action_dispatch/middleware/callbacks.rb:27 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/actionpack-4.2.1/lib/action_dispatch/middleware/remote_ip.rb:78 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/actionpack-4.2.1/lib/action_dispatch/middleware/debug_exceptions.rb:17 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/actionpack-4.2.1/lib/action_dispatch/middleware/show_exceptions.rb:30 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/lograge-0.3.0/lib/lograge/rails_ext/rack/logger.rb:15 in call_app
/gems/railties-4.2.1/lib/rails/rack/logger.rb:20 in block in call
/gems/activesupport-4.2.1/lib/active_support/tagged_logging.rb:68 in block in tagged
/gems/activesupport-4.2.1/lib/active_support/tagged_logging.rb:26 in tagged
/gems/activesupport-4.2.1/lib/active_support/tagged_logging.rb:68 in tagged
/gems/railties-4.2.1/lib/rails/rack/logger.rb:20 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/actionpack-4.2.1/lib/action_dispatch/middleware/request_id.rb:21 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/rack-1.6.0/lib/rack/methodoverride.rb:22 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/rack-1.6.0/lib/rack/runtime.rb:18 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/activesupport-4.2.1/lib/active_support/cache/strategy/local_cache_middleware.rb:28 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/rack-1.6.0/lib/rack/sendfile.rb:113 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/railties-4.2.1/lib/rails/engine.rb:518 in call
/gems/railties-4.2.1/lib/rails/application.rb:164 in call
/gems/railties-4.2.1/lib/rails/railtie.rb:194 in public_send
/gems/railties-4.2.1/lib/rails/railtie.rb:194 in method_missing
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
lib/pulse.rb:11 in call
/gems/newrelic_rpm-3.9.9.275/lib/new_relic/agent/instrumentation/middleware_tracing.rb:57 in call
/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:576 in process_client
/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:670 in worker_loop
/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:525 in spawn_missing_workers
/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:536 in maintain_worker_count
/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:294 in join
/gems/unicorn-4.8.3/bin/unicorn:126 in <top (required)>
/data/gdweb/app/current/bin/unicorn:16 in load
/data/gdweb/app/current/bin/unicorn:16 in <main>

Failing GrapeLogging::Formatters::Rails#call test

I ran the test suite using ruby2.5 and I got one failure:

Failures:

  1) GrapeLogging::Formatters::Rails#call exception data returns a string with a backtrace
     Failure/Error: expect(lines[1]).to include 'grape_logging'
       expected "\t/usr/lib/ruby/vendor_ruby/rspec/core/example.rb:254:in `instance_exec'" to include "grape_logging"
     # ./spec/lib/grape_logging/formatters/rails_spec.rb:40:in `block (4 levels) in <top (required)>'

Have you ever faced this issue? I saw that the tests are passing in travis but with ruby2.3

Request: Add logger definitions for the default included fields

As im going through and adding the log output to my ELK stack, i have to parse out the logged fields, but unfortunately there are no definitions for the order of fields being output, is it possible to have these added to the documentation, or to the wiki :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.