Skip to content

Commit fde088d

Browse files
coorassewooly
andauthoredNov 26, 2024··
Wooly main (#16)
* 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 <[email protected]>
1 parent 6dff4c4 commit fde088d

File tree

5 files changed

+52
-5
lines changed

5 files changed

+52
-5
lines changed
 

‎CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ isolated transactions but don't need to create a new database or migrate data.
3232
* Added tests with a dummy app
3333
* Use a separate database connection configuration to isolate transactions
3434
* I acknowledge that there might be issues on mysql. I don't use it so I won't fix them, but PR are welcome.
35+
* Added `host_regexp` option to the middleware.
3536

3637
# 0.9.0
3738

‎README.md

+6
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ If you want to log only requests on a certain path, you can pass a regular expre
127127
config.middleware.insert_before Rails::Rack::Logger, RailsApiLogger::Middleware, path_regexp: /api/
128128
```
129129

130+
If you want to log only requests on a certain host, you can also use a regular expression:
131+
132+
```ruby
133+
config.middleware.insert_before Rails::Rack::Logger, RailsApiLogger::Middleware, host_regexp: /api.example.com/
134+
```
135+
130136
If you want to skip logging the response or request body of certain requests, you can pass a regular expression:
131137

132138
```ruby

‎app/middlewares/rails_api_logger/middleware.rb

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
module RailsApiLogger
22
class Middleware
3-
attr_accessor :only_state_change, :path_regexp, :skip_request_body_regexp, :skip_response_body_regexp
3+
attr_accessor :only_state_change, :host_regexp, :path_regexp, :skip_request_body_regexp, :skip_response_body_regexp
44

55
def initialize(app, only_state_change: true,
6+
host_regexp: /.*/,
67
path_regexp: /.*/,
78
skip_request_body_regexp: nil,
89
skip_response_body_regexp: nil)
910
@app = app
1011
self.only_state_change = only_state_change
12+
self.host_regexp = host_regexp
1113
self.path_regexp = path_regexp
1214
self.skip_request_body_regexp = skip_request_body_regexp
1315
self.skip_response_body_regexp = skip_response_body_regexp
@@ -49,7 +51,12 @@ def skip_response_body?(env)
4951
end
5052

5153
def log?(env, request)
52-
env["PATH_INFO"] =~ path_regexp && (!only_state_change || request_with_state_change?(request))
54+
# 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
55+
host = env["HTTP_HOST"] || env["SERVER_NAME"]
56+
path = env["PATH_INFO"]
57+
(host =~ host_regexp) &&
58+
(path =~ path_regexp) &&
59+
(!only_state_change || request_with_state_change?(request))
5360
end
5461

5562
def parsed_body(body)

‎lib/rails_api_logger/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module RailsApiLogger
4-
VERSION = "0.9.0"
4+
VERSION = "0.10.0"
55
end

‎spec/inbound_requests_logger_middleware_spec.rb

+35-2
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,45 @@ def request
2424

2525
RSpec.describe RailsApiLogger::Middleware do
2626
let(:input) { {"book" => {"title" => "Harry Potter", "author" => "J.K. Rowling"}} }
27-
27+
let(:host_regexp) { /.*/ }
28+
let(:path_regexp) { /.*/ }
2829
let(:skip_request_body_regexp) { nil }
2930
let(:skip_response_body_regexp) { nil }
3031
let(:app) do
3132
described_class.new(MyApp.new,
33+
host_regexp: host_regexp,
3234
path_regexp: path_regexp,
3335
skip_request_body_regexp: skip_request_body_regexp,
3436
skip_response_body_regexp: skip_response_body_regexp)
3537
end
3638
let(:request) { Rack::MockRequest.new(app) }
37-
let(:response) { request.post("/api/v1/books", {input: input.to_json}) }
39+
let(:response) { request.post("http://api.example.org/api/v1/books", {input: input.to_json}) }
3840

3941
before do
4042
RailsApiLogger::InboundRequestLog.delete_all
4143
end
4244

45+
context "when the HTTP_HOST matches the host_regexp" do
46+
let(:host_regexp) { /api.example.org/ }
47+
48+
it "logs a request in the database" do
49+
expect(response.status).to eq(200)
50+
expect(response.body).to eq("Hello World")
51+
expect(RailsApiLogger::InboundRequestLog.count).to eq(1)
52+
inbound_request_log = RailsApiLogger::InboundRequestLog.first
53+
expect(inbound_request_log.method).to eq("POST")
54+
expect(inbound_request_log.path).to eq("/api/v1/books")
55+
expect(inbound_request_log.request_body).to eq(input)
56+
expect(inbound_request_log.response_code).to eq(200)
57+
expect(inbound_request_log.response_body).to eq("Hello World")
58+
expect(inbound_request_log.started_at).to be_present
59+
expect(inbound_request_log.ended_at).to be_present
60+
expect(inbound_request_log.duration).to be > 0
61+
expect(inbound_request_log.loggable_type).to eq("Book")
62+
expect(inbound_request_log.loggable_id).to be_present
63+
end
64+
end
65+
4366
context "when the PATH_INFO matches the path_regexp" do
4467
let(:path_regexp) { /\/api/ }
4568

@@ -108,6 +131,16 @@ def request
108131
end
109132
end
110133

134+
context "when the HTTP_HOST does not match the host_regexp" do
135+
let(:host_regexp) { /foo.example.com/ }
136+
137+
it "does not log the request" do
138+
expect(response.status).to eq(200)
139+
expect(response.body).to eq("Hello World")
140+
expect(RailsApiLogger::InboundRequestLog.count).to eq(0)
141+
end
142+
end
143+
111144
context "when the PATH_INFO does not match the path_regexp" do
112145
let(:path_regexp) { /\/pupu/ }
113146

0 commit comments

Comments
 (0)
Please sign in to comment.