full_request_logger 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69103e9dda0de7ad14689c9479265fa4148620f406ba2cecc10e7350db55c183
4
- data.tar.gz: ad9049fdc9cc3c55e462dee1205af4df4239522f1a2f9902c3d0457e4e2b4de3
3
+ metadata.gz: 3277ad6d1379e4c24c95d9cea1d1f8aba4e2459296e554b325dbd190dbe5405a
4
+ data.tar.gz: cd66762f0e1c159111a7f842ec5c093680d6cac023d6094699b391586801da3b
5
5
  SHA512:
6
- metadata.gz: dec6f6c382133e02c94d8c875bab02cd925c046f91b6f0a85b742e707863fc4dbcee5256528d5d2332bd2c69ce251660b82227bb035ffecdcb843ac0ea2c47e9
7
- data.tar.gz: a9f6274384f9a81f4178cca95b99b28dbd72a9a960309055f0524b7c6c4ac2cea4a3508f36eb535d64c61d2191f30fbfc250aab7aa4600e982a869eb3a47d502
6
+ metadata.gz: c4999de51e83269df0d1224423670a7a2e22b82cd3751cc1af77fc3a787179663270d14d3be9675a6423848bf84e184c9d55c140c2fab4c93c4c7b621f365f9b
7
+ data.tar.gz: 072af0e253a048a8419a8c2b2c443927541a6871bb557b6b9a18b7c16da8fb02e06f9c24f29df569386459af5f3115e0eb534120c257de5b6cbde94197e778bf
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- full_request_logger (0.1)
4
+ full_request_logger (0.3)
5
5
  rails (>= 6.0.0)
6
6
  redis (>= 4.0)
7
7
 
data/README.md CHANGED
@@ -27,6 +27,14 @@ config.full_request_logger.ttl = 1.hour
27
27
  config.full_request_logger.redis = { host: "127.0.0.1", port: 36379, timeout: 1 }
28
28
  ```
29
29
 
30
+ You can restrict which requests will be stored by setting an eligibility function that gets to evaluate the request:
31
+
32
+ ```ruby
33
+ config.full_request_logger.eligibility = ->(request) { request.params[:full_request_log] == "1" }
34
+ ```
35
+
36
+ This makes it easier to use the logger on a busy site that would otherwise result in a lot of needless redis writes.
37
+
30
38
  The request logs access can be protected behind http basic by adding the following credentials
31
39
  (using `./bin/rails credentials:edit --environment production`):
32
40
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'full_request_logger'
3
- s.version = '0.2'
3
+ s.version = '0.3'
4
4
  s.authors = 'David Heinemeier Hansson'
5
5
  s.email = 'david@basecamp.com'
6
6
  s.summary = 'Make full request logs accessible via web UI'
@@ -4,9 +4,11 @@ module FullRequestLogger
4
4
  extend ActiveSupport::Autoload
5
5
 
6
6
  autoload :Recorder
7
+ autoload :Processor
7
8
 
8
9
  mattr_accessor :ttl
9
10
  mattr_accessor :redis
10
11
  mattr_accessor :enabled
12
+ mattr_accessor :eligibility
11
13
  mattr_accessor :credentials
12
14
  end
@@ -17,6 +17,7 @@ module FullRequestLogger
17
17
  FullRequestLogger.enabled = app.config.full_request_logger.enabled || false
18
18
  FullRequestLogger.ttl = app.config.full_request_logger.ttl || 10.minutes
19
19
  FullRequestLogger.redis = app.config.full_request_logger.redis || {}
20
+ FullRequestLogger.eligibility = app.config.full_request_logger.eligibility || true
20
21
  FullRequestLogger.credentials = app.config.full_request_logger.credentials || app.credentials.full_request_logger
21
22
  end
22
23
  end
@@ -5,11 +5,7 @@ module FullRequestLogger
5
5
  end
6
6
 
7
7
  def call(env)
8
- @app.call(env).tap do
9
- if FullRequestLogger.enabled
10
- Recorder.instance.store ActionDispatch::Request.new(env).request_id
11
- end
12
- end
8
+ @app.call(env).tap { Processor.new(env).process }
13
9
  end
14
10
  end
15
- end
11
+ end
@@ -0,0 +1,40 @@
1
+ require "full_request_logger/recorder"
2
+ require "action_dispatch/http/request"
3
+
4
+ class FullRequestLogger::Processor
5
+ def initialize(env)
6
+ @env = env
7
+ end
8
+
9
+ def process
10
+ if enabled? && eligible_for_storage?
11
+ recorder.store request_id
12
+ else
13
+ recorder.clear
14
+ end
15
+ end
16
+
17
+ private
18
+ def enabled?
19
+ FullRequestLogger.enabled
20
+ end
21
+
22
+ def eligible_for_storage?
23
+ if eligibility.respond_to?(:call)
24
+ eligibility.call(request)
25
+ else
26
+ eligibility
27
+ end
28
+ end
29
+
30
+ delegate :eligibility, to: FullRequestLogger
31
+
32
+ def recorder
33
+ @recorder ||= FullRequestLogger::Recorder.instance
34
+ end
35
+
36
+ delegate :request_id, to: :request
37
+ def request
38
+ @request ||= ActionDispatch::Request.new(@env)
39
+ end
40
+ end
@@ -4,16 +4,10 @@ require "redis"
4
4
  require "zlib"
5
5
 
6
6
  class FullRequestLogger::Recorder
7
- attr_reader :redis
8
-
9
7
  def self.instance
10
8
  @instance ||= new
11
9
  end
12
10
 
13
- def initialize
14
- @redis = Redis.new FullRequestLogger.redis
15
- end
16
-
17
11
  # Extends an existing logger instance with a broadcast aspect that'll send a copy of all logging lines to this recorder.
18
12
  def attach_to(logger)
19
13
  logger.extend ActiveSupport::Logger.broadcast(ActiveSupport::Logger.new(self))
@@ -38,7 +32,7 @@ class FullRequestLogger::Recorder
38
32
  compress(log_to_be_stored)
39
33
  end
40
34
  ensure
41
- messages.clear
35
+ clear
42
36
  end
43
37
 
44
38
  # Returns a single string with all the log messages that were captured for the given +request_id+ (or nil if nothing was
@@ -49,9 +43,14 @@ class FullRequestLogger::Recorder
49
43
  end
50
44
  end
51
45
 
52
- # Clear out any messages pending in the buffer as well as all existing stored request logs.
53
- def reset
46
+ # Clears the current buffer of log messages.
47
+ def clear
54
48
  messages.clear
49
+ end
50
+
51
+ # Clear out any messages pending in the buffer as well as all existing stored request logs.
52
+ def clear_all
53
+ clear
55
54
  clear_stored_requests
56
55
  end
57
56
 
@@ -61,6 +60,10 @@ class FullRequestLogger::Recorder
61
60
  end
62
61
 
63
62
  private
63
+ def redis
64
+ @redis ||= Redis.new FullRequestLogger.redis
65
+ end
66
+
64
67
  def messages
65
68
  Thread.current[:full_request_logger_messages] ||= []
66
69
  end
@@ -0,0 +1,64 @@
1
+ require_relative "../test/dummy/config/environment"
2
+ require "rails/test_help"
3
+
4
+ require "full_request_logger"
5
+
6
+ FullRequestLogger.enabled = true
7
+ FullRequestLogger.eligibility = true
8
+
9
+ class ProcessorTest < ActiveSupport::TestCase
10
+ LOGGER = Logger.new(StringIO.new)
11
+ FRL = FullRequestLogger::Recorder.instance.tap { |frl| frl.attach_to(LOGGER) }
12
+
13
+ setup do
14
+ @processor = FullRequestLogger::Processor.new({ "action_dispatch.request_id" => "123" })
15
+ end
16
+
17
+ teardown { FRL.clear_all }
18
+
19
+ test "store when enabled with basic eligibility" do
20
+ LOGGER.info "hello!"
21
+ @processor.process
22
+ assert FRL.combined_log.blank?
23
+ assert_equal "hello!", FRL.retrieve("123")
24
+ end
25
+
26
+ test "clear without store when not enabled" do
27
+ begin
28
+ FullRequestLogger.enabled = false
29
+
30
+ LOGGER.info "hello!"
31
+ @processor.process
32
+ assert FRL.combined_log.blank?
33
+ assert_nil FRL.retrieve("123")
34
+ ensure
35
+ FullRequestLogger.enabled = true
36
+ end
37
+ end
38
+
39
+ test "successful eligibility will store request" do
40
+ begin
41
+ FullRequestLogger.eligibility = ->(request) { request.request_id == "123" }
42
+
43
+ LOGGER.info "hello!"
44
+ @processor.process
45
+ assert FRL.combined_log.blank?
46
+ assert_equal "hello!", FRL.retrieve("123")
47
+ ensure
48
+ FullRequestLogger.eligibility = true
49
+ end
50
+ end
51
+
52
+ test "failing eligibility will not store request" do
53
+ begin
54
+ FullRequestLogger.eligibility = ->(request) { request.request_id == "678" }
55
+
56
+ LOGGER.info "hello!"
57
+ @processor.process
58
+ assert FRL.combined_log.blank?
59
+ assert_nil FRL.retrieve("123")
60
+ ensure
61
+ FullRequestLogger.eligibility = true
62
+ end
63
+ end
64
+ end
@@ -9,7 +9,7 @@ class RecorderTest < ActiveSupport::TestCase
9
9
  @full_request_logger = FullRequestLogger::Recorder.new.tap { |frl| frl.attach_to(@logger) }
10
10
  end
11
11
 
12
- teardown { @full_request_logger.reset }
12
+ teardown { @full_request_logger.clear_all }
13
13
 
14
14
  test "attached frl will store writes made to logger" do
15
15
  @logger.info "This is a line"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: full_request_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.2'
4
+ version: '0.3'
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
@@ -72,6 +72,7 @@ files:
72
72
  - lib/full_request_logger.rb
73
73
  - lib/full_request_logger/engine.rb
74
74
  - lib/full_request_logger/middleware.rb
75
+ - lib/full_request_logger/processor.rb
75
76
  - lib/full_request_logger/recorder.rb
76
77
  - test/dummy/.babelrc
77
78
  - test/dummy/.gitignore
@@ -136,6 +137,7 @@ files:
136
137
  - test/dummy/public/apple-touch-icon-precomposed.png
137
138
  - test/dummy/public/apple-touch-icon.png
138
139
  - test/dummy/public/favicon.ico
140
+ - test/processor_test.rb
139
141
  - test/recorder_test.rb
140
142
  homepage: https://github.com/basecamp/full_request_logger
141
143
  licenses:
@@ -224,4 +226,5 @@ test_files:
224
226
  - test/dummy/public/apple-touch-icon-precomposed.png
225
227
  - test/dummy/public/apple-touch-icon.png
226
228
  - test/dummy/public/favicon.ico
229
+ - test/processor_test.rb
227
230
  - test/recorder_test.rb