Skip to content

Commit

Permalink
Wooly main (#16)
Browse files Browse the repository at this point in the history
* Fix supported gem versions in the Gemspec

* Allow skipping logging based on host

* Adjust and rebase

* Add documentation about host regex

* Updaten changelog and bump version

* Fix tests

---------

Co-authored-by: Steve Bell <steve@colloquial.io>
  • Loading branch information
coorasse and wooly authored Nov 26, 2024
1 parent 6dff4c4 commit fde088d
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ isolated transactions but don't need to create a new database or migrate data.
* Added tests with a dummy app
* Use a separate database connection configuration to isolate transactions
* I acknowledge that there might be issues on mysql. I don't use it so I won't fix them, but PR are welcome.
* Added `host_regexp` option to the middleware.

# 0.9.0

Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ If you want to log only requests on a certain path, you can pass a regular expre
config.middleware.insert_before Rails::Rack::Logger, RailsApiLogger::Middleware, path_regexp: /api/
```

If you want to log only requests on a certain host, you can also use a regular expression:

```ruby
config.middleware.insert_before Rails::Rack::Logger, RailsApiLogger::Middleware, host_regexp: /api.example.com/
```

If you want to skip logging the response or request body of certain requests, you can pass a regular expression:

```ruby
Expand Down
11 changes: 9 additions & 2 deletions app/middlewares/rails_api_logger/middleware.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
module RailsApiLogger
class Middleware
attr_accessor :only_state_change, :path_regexp, :skip_request_body_regexp, :skip_response_body_regexp
attr_accessor :only_state_change, :host_regexp, :path_regexp, :skip_request_body_regexp, :skip_response_body_regexp

def initialize(app, only_state_change: true,
host_regexp: /.*/,
path_regexp: /.*/,
skip_request_body_regexp: nil,
skip_response_body_regexp: nil)
@app = app
self.only_state_change = only_state_change
self.host_regexp = host_regexp
self.path_regexp = path_regexp
self.skip_request_body_regexp = skip_request_body_regexp
self.skip_response_body_regexp = skip_response_body_regexp
Expand Down Expand Up @@ -49,7 +51,12 @@ def skip_response_body?(env)
end

def log?(env, request)
env["PATH_INFO"] =~ path_regexp && (!only_state_change || request_with_state_change?(request))
# The HTTP_HOST header is preferred to the SERVER_NAME header per the Rack spec: https://github.com/rack/rack/blob/main/SPEC.rdoc#label-The+Environment
host = env["HTTP_HOST"] || env["SERVER_NAME"]
path = env["PATH_INFO"]
(host =~ host_regexp) &&
(path =~ path_regexp) &&
(!only_state_change || request_with_state_change?(request))
end

def parsed_body(body)
Expand Down
2 changes: 1 addition & 1 deletion lib/rails_api_logger/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module RailsApiLogger
VERSION = "0.9.0"
VERSION = "0.10.0"
end
37 changes: 35 additions & 2 deletions spec/inbound_requests_logger_middleware_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,45 @@ def request

RSpec.describe RailsApiLogger::Middleware do
let(:input) { {"book" => {"title" => "Harry Potter", "author" => "J.K. Rowling"}} }

let(:host_regexp) { /.*/ }
let(:path_regexp) { /.*/ }
let(:skip_request_body_regexp) { nil }
let(:skip_response_body_regexp) { nil }
let(:app) do
described_class.new(MyApp.new,
host_regexp: host_regexp,
path_regexp: path_regexp,
skip_request_body_regexp: skip_request_body_regexp,
skip_response_body_regexp: skip_response_body_regexp)
end
let(:request) { Rack::MockRequest.new(app) }
let(:response) { request.post("/api/v1/books", {input: input.to_json}) }
let(:response) { request.post("http://api.example.org/api/v1/books", {input: input.to_json}) }

before do
RailsApiLogger::InboundRequestLog.delete_all
end

context "when the HTTP_HOST matches the host_regexp" do
let(:host_regexp) { /api.example.org/ }

it "logs a request in the database" do
expect(response.status).to eq(200)
expect(response.body).to eq("Hello World")
expect(RailsApiLogger::InboundRequestLog.count).to eq(1)
inbound_request_log = RailsApiLogger::InboundRequestLog.first
expect(inbound_request_log.method).to eq("POST")
expect(inbound_request_log.path).to eq("/api/v1/books")
expect(inbound_request_log.request_body).to eq(input)
expect(inbound_request_log.response_code).to eq(200)
expect(inbound_request_log.response_body).to eq("Hello World")
expect(inbound_request_log.started_at).to be_present
expect(inbound_request_log.ended_at).to be_present
expect(inbound_request_log.duration).to be > 0
expect(inbound_request_log.loggable_type).to eq("Book")
expect(inbound_request_log.loggable_id).to be_present
end
end

context "when the PATH_INFO matches the path_regexp" do
let(:path_regexp) { /\/api/ }

Expand Down Expand Up @@ -108,6 +131,16 @@ def request
end
end

context "when the HTTP_HOST does not match the host_regexp" do
let(:host_regexp) { /foo.example.com/ }

it "does not log the request" do
expect(response.status).to eq(200)
expect(response.body).to eq("Hello World")
expect(RailsApiLogger::InboundRequestLog.count).to eq(0)
end
end

context "when the PATH_INFO does not match the path_regexp" do
let(:path_regexp) { /\/pupu/ }

Expand Down

0 comments on commit fde088d

Please sign in to comment.