grape_rails_logger 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +15 -1
- data/lib/grape_rails_logger/debug_tracer.rb +2 -4
- data/lib/grape_rails_logger/endpoint_wrapper.rb +27 -21
- data/lib/grape_rails_logger/railtie.rb +1 -1
- data/lib/grape_rails_logger/status_extractor.rb +27 -16
- data/lib/grape_rails_logger/subscriber.rb +41 -10
- data/lib/grape_rails_logger/timings.rb +16 -0
- data/lib/grape_rails_logger/version.rb +1 -1
- data/lib/grape_rails_logger.rb +41 -7
- data/sig/grape_rails_logger.rbs +3 -0
- metadata +108 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e4483b69705ac60afc5e74a55a4b1d865ba08c6569e449cb2e7fcc9b82e8e449
|
|
4
|
+
data.tar.gz: d54444fd7424e615b480ca6bf85346eb3afef76d07f57991b5f342a8b7d79f39
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9c92013348863f50c25ed04f6c1c0141dc1b0b2fe6f73d4713cc2ba3ae0476beda731d5a8e0f9daa7fe7937f98fd07570483a3d9bdf1f30828b80c4a13496f7b
|
|
7
|
+
data.tar.gz: 4b95fcc595e37b91076965409651fc453cd112d16414c328ac20ab5daab090cade361f3836199ec351c9de1fddd091d4c05a7800dbde06f4ca26e1b79b2a378a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 1.2.2 (2026-09-15)
|
|
4
|
+
|
|
5
|
+
- Allow grape 4.x by expanding the runtime dependency to `< 5.0`
|
|
6
|
+
- Keep request log action names when grape stores path and method on endpoint config instead of `options`
|
|
7
|
+
|
|
8
|
+
## 1.2.1 (2026-07-18)
|
|
9
|
+
|
|
10
|
+
- Fix HTTP status in Grape request logs for exception subclasses of mapped error types
|
|
11
|
+
- Fix duplicate downstream app dispatch when Grape request instrumentation fails after the handler runs
|
|
12
|
+
- Scope ActiveRecord SQL timing aggregation to in-flight Grape requests only
|
|
13
|
+
- Honor TRACE at request time in DebugTracer so tracing follows the current process environment
|
|
14
|
+
- Cache effective Rails configuration to reduce allocation on each log event
|
|
15
|
+
- Warn in development when Grape request instrumentation fails
|
|
16
|
+
|
|
3
17
|
## 1.2.0 (2025-12-04)
|
|
4
18
|
|
|
5
19
|
- Update Grape dependency to allow 3.0.0+
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# grape_rails_logger
|
|
2
2
|
|
|
3
|
-
[](https://badge.fury.io/rb/grape_rails_logger) [](https://github.com/amkisko/grape_rails_logger.rb/actions/workflows/test.yml) [](https://codecov.io/
|
|
3
|
+
[](https://badge.fury.io/rb/grape_rails_logger) [](https://github.com/amkisko/grape_rails_logger.rb/actions/workflows/test.yml) [](https://app.codecov.io/github/amkisko/grape_rails_logger.rb)
|
|
4
4
|
|
|
5
5
|
Rails-compatible structured logging for Grape APIs with ActiveRecord timing, parameter filtering, and exception tracking.
|
|
6
6
|
|
|
@@ -103,6 +103,20 @@ Or use the release script:
|
|
|
103
103
|
usr/bin/release.rb
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
+
## Links
|
|
107
|
+
|
|
108
|
+
- [GitHub](https://github.com/amkisko/grape-rails-logger.rb)
|
|
109
|
+
- [GitLab](https://gitlab.com/amkisko/grape-rails-logger.rb)
|
|
110
|
+
- [RubyGems](https://rubygems.org/gems/grape_rails_logger)
|
|
111
|
+
- [Versions Atom](https://rubygems.org/gems/grape_rails_logger/versions.atom) (feed id `9849778222370`)
|
|
112
|
+
- [Versions Atom (grape-rails-logger)](https://rubygems.org/gems/grape-rails-logger/versions.atom) (feed id `9842277577683`)
|
|
113
|
+
- [libraries.io](https://libraries.io/rubygems/grape_rails_logger)
|
|
114
|
+
- [Deps.dev](https://deps.dev/rubygems/grape_rails_logger)
|
|
115
|
+
- [SonarCloud](https://sonarcloud.io/project/overview?id=amkisko_grape-rails-logger.rb)
|
|
116
|
+
- [Snyk](https://snyk.io/test/github/amkisko/grape-rails-logger.rb)
|
|
117
|
+
- [Codecov](https://app.codecov.io/github/amkisko/grape-rails-logger.rb)
|
|
118
|
+
- [OpenSSF Scorecard](https://scorecard.dev/viewer/?uri=github.com/amkisko/grape-rails-logger.rb)
|
|
119
|
+
|
|
106
120
|
## License
|
|
107
121
|
|
|
108
122
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -12,11 +12,9 @@ module GrapeRailsLogger
|
|
|
12
12
|
# use GrapeRailsLogger::DebugTracer # Only traces when TRACE=1
|
|
13
13
|
# end
|
|
14
14
|
class DebugTracer < ::Grape::Middleware::Base
|
|
15
|
-
TRACE_ENABLED = ENV["TRACE"]
|
|
16
|
-
|
|
17
15
|
def call!(env)
|
|
18
|
-
#
|
|
19
|
-
return @app.call(env) unless
|
|
16
|
+
# Read TRACE at call time so process env (and test ClimateControl) apply after load
|
|
17
|
+
return @app.call(env) unless ENV["TRACE"]
|
|
20
18
|
|
|
21
19
|
# Try to trace, but if anything fails, just pass through
|
|
22
20
|
trace_request(env) do
|
|
@@ -19,28 +19,30 @@ module GrapeRailsLogger
|
|
|
19
19
|
return @app.call(env) unless GrapeRailsLogger.effective_config.enabled
|
|
20
20
|
|
|
21
21
|
logger = resolve_logger
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
22
|
+
downstream_response = nil
|
|
23
|
+
|
|
24
|
+
Timings.track_grape_request do
|
|
25
|
+
# Wrap the entire request in ActiveSupport::Notifications
|
|
26
|
+
# This ensures we capture the final response AFTER Error middleware processes exceptions
|
|
27
|
+
ActiveSupport::Notifications.instrument("grape.request", env: env, logger: logger) do |payload|
|
|
28
|
+
# Call the wrapped app - Error middleware will process exceptions and return final response
|
|
29
|
+
# NOTE: We do NOT read the body here - Grape will process it and parse params
|
|
30
|
+
# We'll extract params later from already-parsed sources (endpoint.request.params)
|
|
31
|
+
downstream_response = @app.call(env)
|
|
32
|
+
|
|
33
|
+
# NOW collect all data AFTER Error middleware has processed exceptions
|
|
34
|
+
# At this point, response contains the final Rack response with correct status
|
|
35
|
+
# AND Grape has already parsed the params, so we can safely access endpoint.request.params
|
|
36
|
+
collect_response_metadata(downstream_response, env, payload)
|
|
37
|
+
|
|
38
|
+
# Return the response - subscriber will log it
|
|
39
|
+
downstream_response
|
|
40
|
+
end
|
|
40
41
|
end
|
|
41
42
|
rescue => e
|
|
42
|
-
# If notifications fail, still process the request
|
|
43
43
|
handle_instrumentation_error(e)
|
|
44
|
+
return downstream_response if downstream_response
|
|
45
|
+
|
|
44
46
|
@app.call(env)
|
|
45
47
|
end
|
|
46
48
|
|
|
@@ -51,7 +53,7 @@ module GrapeRailsLogger
|
|
|
51
53
|
config.logger || (defined?(Rails) && Rails.logger) || Logger.new($stdout)
|
|
52
54
|
end
|
|
53
55
|
|
|
54
|
-
def collect_response_metadata(response, env, payload
|
|
56
|
+
def collect_response_metadata(response, env, payload)
|
|
55
57
|
# Extract status from response - this is the FINAL status after Error middleware
|
|
56
58
|
status = extract_status_from_response(response)
|
|
57
59
|
payload[:status] = status if status.is_a?(Integer)
|
|
@@ -93,7 +95,11 @@ module GrapeRailsLogger
|
|
|
93
95
|
end
|
|
94
96
|
|
|
95
97
|
def handle_instrumentation_error(error)
|
|
96
|
-
|
|
98
|
+
return unless defined?(Rails) && Rails.env.development?
|
|
99
|
+
|
|
100
|
+
resolve_logger.warn("GrapeRailsLogger: instrumentation failed - #{error.class}: #{error.message}")
|
|
101
|
+
rescue
|
|
102
|
+
# Never let error reporting break requests
|
|
97
103
|
end
|
|
98
104
|
end
|
|
99
105
|
end
|
|
@@ -40,7 +40,7 @@ if defined?(Rails) && defined?(Rails::Railtie)
|
|
|
40
40
|
|
|
41
41
|
begin
|
|
42
42
|
subscriber_class = Rails.application.config.grape_rails_logger.subscriber_class || GrapeRequestLogSubscriber
|
|
43
|
-
subscriber = subscriber_class
|
|
43
|
+
subscriber = GrapeRailsLogger.subscriber_instance_for(subscriber_class)
|
|
44
44
|
subscriber.grape_request(ActiveSupport::Notifications::Event.new(*args))
|
|
45
45
|
rescue => e
|
|
46
46
|
# Last resort: if subscriber creation or invocation fails, log
|
|
@@ -22,6 +22,13 @@ module GrapeRailsLogger
|
|
|
22
22
|
# @param e [Exception] The exception to extract status from
|
|
23
23
|
# @return [Integer] HTTP status code, defaults to 500
|
|
24
24
|
def extract_status_from_exception(e)
|
|
25
|
+
inline = inline_status_from_exception(e)
|
|
26
|
+
return inline if inline.is_a?(Integer)
|
|
27
|
+
|
|
28
|
+
map_exception_to_status(e.class) || 500
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def inline_status_from_exception(e)
|
|
25
32
|
return e.status if e.respond_to?(:status) && e.status.is_a?(Integer)
|
|
26
33
|
|
|
27
34
|
if e.instance_variable_defined?(:@status)
|
|
@@ -33,24 +40,28 @@ module GrapeRailsLogger
|
|
|
33
40
|
return e.options[:status] if e.options[:status].is_a?(Integer)
|
|
34
41
|
end
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
exception_name.constantize
|
|
47
|
-
end
|
|
48
|
-
return status_code if exception_class && e.is_a?(exception_class)
|
|
49
|
-
rescue NameError
|
|
50
|
-
# Exception class not available, skip
|
|
43
|
+
nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Walk exception class and ancestors — O(ancestors) hash lookups, no constantize per map entry.
|
|
47
|
+
# Non-Module classes (e.g. test doubles) use a single-element chain.
|
|
48
|
+
def map_exception_to_status(e_class)
|
|
49
|
+
chain = if Module === e_class
|
|
50
|
+
e_class.ancestors
|
|
51
|
+
else
|
|
52
|
+
[e_class]
|
|
51
53
|
end
|
|
54
|
+
chain.each do |mod|
|
|
55
|
+
next unless mod.respond_to?(:name)
|
|
56
|
+
|
|
57
|
+
name = mod.name
|
|
58
|
+
next if name.to_s.empty?
|
|
52
59
|
|
|
53
|
-
|
|
60
|
+
status = EXCEPTION_STATUS_MAP[name]
|
|
61
|
+
return status if status
|
|
62
|
+
end
|
|
63
|
+
nil
|
|
54
64
|
end
|
|
65
|
+
private_class_method :inline_status_from_exception, :map_exception_to_status
|
|
55
66
|
end
|
|
56
67
|
end
|
|
@@ -19,7 +19,6 @@ module GrapeRailsLogger
|
|
|
19
19
|
|
|
20
20
|
FILTERED_PARAMS = %w[password secret token key].freeze
|
|
21
21
|
PARAM_EXCEPTIONS = %w[controller action format].freeze
|
|
22
|
-
AD_PARAMS = "action_dispatch.request.parameters"
|
|
23
22
|
|
|
24
23
|
def grape_request(event)
|
|
25
24
|
return unless event.is_a?(ActiveSupport::Notifications::Event)
|
|
@@ -482,21 +481,52 @@ module GrapeRailsLogger
|
|
|
482
481
|
def extract_action(event)
|
|
483
482
|
endpoint = event.payload.dig(:env, "api.endpoint")
|
|
484
483
|
return "unknown" unless endpoint
|
|
485
|
-
return "unknown" unless endpoint.respond_to?(:options)
|
|
486
|
-
return "unknown" unless endpoint.options
|
|
487
484
|
|
|
488
|
-
method = endpoint
|
|
489
|
-
path = endpoint
|
|
485
|
+
method = first_list_item(endpoint_http_methods(endpoint))
|
|
486
|
+
path = first_list_item(endpoint_paths(endpoint))
|
|
490
487
|
return "unknown" unless method && path
|
|
491
488
|
|
|
492
|
-
|
|
489
|
+
method_name = method.to_s.downcase
|
|
490
|
+
return method_name if path == "/" || path.empty?
|
|
493
491
|
|
|
494
492
|
clean_path = path.to_s.delete_prefix("/").gsub(/[:\/]/, "_").squeeze("_").gsub(/^_+|_+$/, "")
|
|
495
|
-
"#{
|
|
493
|
+
"#{method_name}_#{clean_path}"
|
|
496
494
|
rescue
|
|
497
495
|
"unknown"
|
|
498
496
|
end
|
|
499
497
|
|
|
498
|
+
def endpoint_http_methods(endpoint)
|
|
499
|
+
config = endpoint_config(endpoint)
|
|
500
|
+
methods = config.http_methods if config.respond_to?(:http_methods)
|
|
501
|
+
return methods if methods
|
|
502
|
+
return nil unless endpoint.respond_to?(:options) && endpoint.options
|
|
503
|
+
|
|
504
|
+
endpoint.options[:method]
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
def endpoint_paths(endpoint)
|
|
508
|
+
config = endpoint_config(endpoint)
|
|
509
|
+
paths = config.path if config.respond_to?(:path)
|
|
510
|
+
return paths if paths
|
|
511
|
+
return nil unless endpoint.respond_to?(:options) && endpoint.options
|
|
512
|
+
|
|
513
|
+
endpoint.options[:path]
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
# grape 4 stores definition-time verbs and path on protected Endpoint#config
|
|
517
|
+
def endpoint_config(endpoint)
|
|
518
|
+
return unless endpoint.respond_to?(:config, true)
|
|
519
|
+
|
|
520
|
+
endpoint.send(:config)
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
def first_list_item(value)
|
|
524
|
+
return value if value.nil? || value.is_a?(String) || value.is_a?(Symbol)
|
|
525
|
+
return value.first if value.respond_to?(:first)
|
|
526
|
+
|
|
527
|
+
value
|
|
528
|
+
end
|
|
529
|
+
|
|
500
530
|
def extract_controller(event)
|
|
501
531
|
endpoint = event.payload.dig(:env, "api.endpoint")
|
|
502
532
|
return nil unless endpoint&.source&.source_location
|
|
@@ -561,7 +591,7 @@ module GrapeRailsLogger
|
|
|
561
591
|
return {} unless endpoint&.respond_to?(:request) && endpoint.request
|
|
562
592
|
|
|
563
593
|
endpoint_params = endpoint.request.params
|
|
564
|
-
return {} if endpoint_params.
|
|
594
|
+
return {} if endpoint_params.blank?
|
|
565
595
|
|
|
566
596
|
params_hash = if endpoint_params.respond_to?(:to_unsafe_h)
|
|
567
597
|
endpoint_params.to_unsafe_h
|
|
@@ -679,7 +709,8 @@ module GrapeRailsLogger
|
|
|
679
709
|
endpoint = env["api.endpoint"]
|
|
680
710
|
return nil unless endpoint
|
|
681
711
|
|
|
682
|
-
api_class = endpoint.respond_to?(:
|
|
712
|
+
api_class = endpoint.respond_to?(:api) ? endpoint.api : nil
|
|
713
|
+
api_class ||= endpoint.respond_to?(:options) ? endpoint.options[:for] : nil
|
|
683
714
|
api_class ||= endpoint.respond_to?(:namespace) ? endpoint.namespace&.options&.dig(:for) : nil
|
|
684
715
|
api_class ||= endpoint.respond_to?(:route) ? endpoint.route&.options&.dig(:for) : nil
|
|
685
716
|
return nil unless api_class&.respond_to?(:content_types, true)
|
|
@@ -728,7 +759,7 @@ module GrapeRailsLogger
|
|
|
728
759
|
return nil unless Rails.application.config.respond_to?(:filter_parameters)
|
|
729
760
|
|
|
730
761
|
filter_parameters = Rails.application.config.filter_parameters
|
|
731
|
-
return nil if filter_parameters.
|
|
762
|
+
return nil if filter_parameters.blank?
|
|
732
763
|
|
|
733
764
|
# Prefer ActiveSupport::ParameterFilter (Rails 6.1+)
|
|
734
765
|
# This is the Rails-native parameter filtering system
|
|
@@ -19,6 +19,20 @@ module GrapeRailsLogger
|
|
|
19
19
|
state[:grape_db_calls] = 0
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def self.track_grape_request
|
|
23
|
+
state = execution_state
|
|
24
|
+
previous_tracking = state[:grape_db_tracking]
|
|
25
|
+
state[:grape_db_tracking] = true
|
|
26
|
+
reset_db_runtime
|
|
27
|
+
yield
|
|
28
|
+
ensure
|
|
29
|
+
state[:grape_db_tracking] = previous_tracking
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.grape_request_active?
|
|
33
|
+
!!execution_state[:grape_db_tracking]
|
|
34
|
+
end
|
|
35
|
+
|
|
22
36
|
def self.db_runtime
|
|
23
37
|
execution_state[:grape_db_runtime] ||= 0
|
|
24
38
|
end
|
|
@@ -29,6 +43,8 @@ module GrapeRailsLogger
|
|
|
29
43
|
|
|
30
44
|
def self.append_db_runtime(event)
|
|
31
45
|
state = execution_state
|
|
46
|
+
return unless state[:grape_db_tracking]
|
|
47
|
+
|
|
32
48
|
state[:grape_db_runtime] = (state[:grape_db_runtime] || 0) + event.duration
|
|
33
49
|
state[:grape_db_calls] = (state[:grape_db_calls] || 0) + 1
|
|
34
50
|
end
|
data/lib/grape_rails_logger.rb
CHANGED
|
@@ -13,6 +13,9 @@ require "grape_rails_logger/endpoint_wrapper"
|
|
|
13
13
|
require "grape_rails_logger/debug_tracer"
|
|
14
14
|
|
|
15
15
|
module GrapeRailsLogger
|
|
16
|
+
# Distinguish "Rails config did not define this key" from a real nil/false value
|
|
17
|
+
EFFECTIVE_CONFIG_ATTR_MISSING = Object.new.freeze
|
|
18
|
+
|
|
16
19
|
# Configuration for GrapeRailsLogger
|
|
17
20
|
#
|
|
18
21
|
# When running in Rails, use Rails.application.config.grape_rails_logger instead:
|
|
@@ -55,22 +58,53 @@ module GrapeRailsLogger
|
|
|
55
58
|
|
|
56
59
|
# Get the effective configuration (Rails-aware)
|
|
57
60
|
#
|
|
61
|
+
# Caches the synthesized {Config} while Rails config values are unchanged
|
|
62
|
+
# (avoids allocating a new {Config} on every call).
|
|
63
|
+
#
|
|
58
64
|
# @return [Config] The active configuration object
|
|
59
65
|
def self.effective_config
|
|
60
66
|
if defined?(Rails) && Rails.application && Rails.application.config.respond_to?(:grape_rails_logger)
|
|
61
|
-
# Use Rails config if available
|
|
62
67
|
rails_config = Rails.application.config.grape_rails_logger
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
signature = rails_effective_config_signature(rails_config)
|
|
69
|
+
if @rails_effective_config_signature == signature && @rails_effective_config
|
|
70
|
+
@rails_effective_config
|
|
71
|
+
else
|
|
72
|
+
@rails_effective_config_signature = signature
|
|
73
|
+
@rails_effective_config = build_effective_config_from_rails(rails_config)
|
|
74
|
+
end
|
|
69
75
|
else
|
|
70
76
|
# Fall back to module-level config for non-Rails usage
|
|
71
77
|
config
|
|
72
78
|
end
|
|
73
79
|
end
|
|
80
|
+
|
|
81
|
+
# @api private
|
|
82
|
+
def self.build_effective_config_from_rails(rails_config)
|
|
83
|
+
config_obj = Config.new
|
|
84
|
+
config_obj.enabled = rails_config.enabled if rails_config.respond_to?(:enabled)
|
|
85
|
+
config_obj.subscriber_class = rails_config.subscriber_class if rails_config.respond_to?(:subscriber_class)
|
|
86
|
+
config_obj.logger = rails_config.logger if rails_config.respond_to?(:logger)
|
|
87
|
+
config_obj.tag = rails_config.tag if rails_config.respond_to?(:tag)
|
|
88
|
+
config_obj
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def self.rails_effective_config_signature(rails_config)
|
|
92
|
+
[
|
|
93
|
+
rails_config.respond_to?(:enabled) ? rails_config.enabled : EFFECTIVE_CONFIG_ATTR_MISSING,
|
|
94
|
+
rails_config.respond_to?(:subscriber_class) ? rails_config.subscriber_class : EFFECTIVE_CONFIG_ATTR_MISSING,
|
|
95
|
+
rails_config.respond_to?(:logger) ? rails_config.logger : EFFECTIVE_CONFIG_ATTR_MISSING,
|
|
96
|
+
rails_config.respond_to?(:tag) ? rails_config.tag : EFFECTIVE_CONFIG_ATTR_MISSING
|
|
97
|
+
]
|
|
98
|
+
end
|
|
99
|
+
private_class_method :build_effective_config_from_rails, :rails_effective_config_signature
|
|
100
|
+
|
|
101
|
+
# Reuse one subscriber instance per class — {GrapeRequestLogSubscriber} has no per-request ivars.
|
|
102
|
+
#
|
|
103
|
+
# @api private
|
|
104
|
+
def self.subscriber_instance_for(subscriber_class)
|
|
105
|
+
@subscriber_instances ||= {}
|
|
106
|
+
@subscriber_instances[subscriber_class] ||= subscriber_class.new
|
|
107
|
+
end
|
|
74
108
|
end
|
|
75
109
|
|
|
76
110
|
# Load Railtie for Rails integration
|
data/sig/grape_rails_logger.rbs
CHANGED
|
@@ -13,10 +13,13 @@ module GrapeRailsLogger
|
|
|
13
13
|
def self.config: () -> Config
|
|
14
14
|
def self.configure: () { (Config) -> void } -> void
|
|
15
15
|
def self.effective_config: () -> Config
|
|
16
|
+
def self.subscriber_instance_for: (Class subscriber_class) -> GrapeRequestLogSubscriber
|
|
16
17
|
|
|
17
18
|
module Timings
|
|
18
19
|
def self.execution_state: () -> untyped
|
|
19
20
|
def self.reset_db_runtime: () -> void
|
|
21
|
+
def self.track_grape_request: () { (void) -> untyped } -> untyped
|
|
22
|
+
def self.grape_request_active?: () -> bool
|
|
20
23
|
def self.db_runtime: () -> Float
|
|
21
24
|
def self.db_calls: () -> Integer
|
|
22
25
|
def self.append_db_runtime: (ActiveSupport::Notifications::Event event) -> void
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: grape_rails_logger
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrei Makarov
|
|
@@ -15,7 +15,7 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '
|
|
18
|
+
version: '7.0'
|
|
19
19
|
- - "<"
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
21
|
version: '9.0'
|
|
@@ -25,7 +25,7 @@ dependencies:
|
|
|
25
25
|
requirements:
|
|
26
26
|
- - ">="
|
|
27
27
|
- !ruby/object:Gem::Version
|
|
28
|
-
version: '
|
|
28
|
+
version: '7.0'
|
|
29
29
|
- - "<"
|
|
30
30
|
- !ruby/object:Gem::Version
|
|
31
31
|
version: '9.0'
|
|
@@ -35,7 +35,7 @@ dependencies:
|
|
|
35
35
|
requirements:
|
|
36
36
|
- - ">="
|
|
37
37
|
- !ruby/object:Gem::Version
|
|
38
|
-
version: '
|
|
38
|
+
version: '7.0'
|
|
39
39
|
- - "<"
|
|
40
40
|
- !ruby/object:Gem::Version
|
|
41
41
|
version: '9.0'
|
|
@@ -45,7 +45,7 @@ dependencies:
|
|
|
45
45
|
requirements:
|
|
46
46
|
- - ">="
|
|
47
47
|
- !ruby/object:Gem::Version
|
|
48
|
-
version: '
|
|
48
|
+
version: '7.0'
|
|
49
49
|
- - "<"
|
|
50
50
|
- !ruby/object:Gem::Version
|
|
51
51
|
version: '9.0'
|
|
@@ -58,7 +58,7 @@ dependencies:
|
|
|
58
58
|
version: '1.6'
|
|
59
59
|
- - "<"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
61
|
+
version: '5.0'
|
|
62
62
|
type: :runtime
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -68,7 +68,7 @@ dependencies:
|
|
|
68
68
|
version: '1.6'
|
|
69
69
|
- - "<"
|
|
70
70
|
- !ruby/object:Gem::Version
|
|
71
|
-
version: '
|
|
71
|
+
version: '5.0'
|
|
72
72
|
- !ruby/object:Gem::Dependency
|
|
73
73
|
name: rspec
|
|
74
74
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -83,6 +83,20 @@ dependencies:
|
|
|
83
83
|
- - "~>"
|
|
84
84
|
- !ruby/object:Gem::Version
|
|
85
85
|
version: '3'
|
|
86
|
+
- !ruby/object:Gem::Dependency
|
|
87
|
+
name: polyrun
|
|
88
|
+
requirement: !ruby/object:Gem::Requirement
|
|
89
|
+
requirements:
|
|
90
|
+
- - ">="
|
|
91
|
+
- !ruby/object:Gem::Version
|
|
92
|
+
version: 2.2.0
|
|
93
|
+
type: :development
|
|
94
|
+
prerelease: false
|
|
95
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - ">="
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: 2.2.0
|
|
86
100
|
- !ruby/object:Gem::Dependency
|
|
87
101
|
name: webmock
|
|
88
102
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -112,75 +126,131 @@ dependencies:
|
|
|
112
126
|
- !ruby/object:Gem::Version
|
|
113
127
|
version: '13'
|
|
114
128
|
- !ruby/object:Gem::Dependency
|
|
115
|
-
name:
|
|
129
|
+
name: rspec_junit_formatter
|
|
116
130
|
requirement: !ruby/object:Gem::Requirement
|
|
117
131
|
requirements:
|
|
118
132
|
- - "~>"
|
|
119
133
|
- !ruby/object:Gem::Version
|
|
120
|
-
version: '0.
|
|
134
|
+
version: '0.6'
|
|
121
135
|
type: :development
|
|
122
136
|
prerelease: false
|
|
123
137
|
version_requirements: !ruby/object:Gem::Requirement
|
|
124
138
|
requirements:
|
|
125
139
|
- - "~>"
|
|
126
140
|
- !ruby/object:Gem::Version
|
|
127
|
-
version: '0.
|
|
141
|
+
version: '0.6'
|
|
128
142
|
- !ruby/object:Gem::Dependency
|
|
129
|
-
name:
|
|
143
|
+
name: standard
|
|
130
144
|
requirement: !ruby/object:Gem::Requirement
|
|
131
145
|
requirements:
|
|
132
146
|
- - "~>"
|
|
133
147
|
- !ruby/object:Gem::Version
|
|
134
|
-
version: '
|
|
148
|
+
version: '1.52'
|
|
135
149
|
type: :development
|
|
136
150
|
prerelease: false
|
|
137
151
|
version_requirements: !ruby/object:Gem::Requirement
|
|
138
152
|
requirements:
|
|
139
153
|
- - "~>"
|
|
140
154
|
- !ruby/object:Gem::Version
|
|
141
|
-
version: '
|
|
155
|
+
version: '1.52'
|
|
142
156
|
- !ruby/object:Gem::Dependency
|
|
143
|
-
name:
|
|
157
|
+
name: standard-custom
|
|
144
158
|
requirement: !ruby/object:Gem::Requirement
|
|
145
159
|
requirements:
|
|
146
160
|
- - "~>"
|
|
147
161
|
- !ruby/object:Gem::Version
|
|
148
|
-
version: '
|
|
162
|
+
version: '1.0'
|
|
149
163
|
type: :development
|
|
150
164
|
prerelease: false
|
|
151
165
|
version_requirements: !ruby/object:Gem::Requirement
|
|
152
166
|
requirements:
|
|
153
167
|
- - "~>"
|
|
154
168
|
- !ruby/object:Gem::Version
|
|
155
|
-
version: '
|
|
169
|
+
version: '1.0'
|
|
156
170
|
- !ruby/object:Gem::Dependency
|
|
157
|
-
name: standard
|
|
171
|
+
name: standard-performance
|
|
158
172
|
requirement: !ruby/object:Gem::Requirement
|
|
159
173
|
requirements:
|
|
160
174
|
- - "~>"
|
|
161
175
|
- !ruby/object:Gem::Version
|
|
162
|
-
version: '1'
|
|
176
|
+
version: '1.8'
|
|
163
177
|
type: :development
|
|
164
178
|
prerelease: false
|
|
165
179
|
version_requirements: !ruby/object:Gem::Requirement
|
|
166
180
|
requirements:
|
|
167
181
|
- - "~>"
|
|
168
182
|
- !ruby/object:Gem::Version
|
|
169
|
-
version: '1'
|
|
183
|
+
version: '1.8'
|
|
170
184
|
- !ruby/object:Gem::Dependency
|
|
171
|
-
name: standard-
|
|
185
|
+
name: standard-rails
|
|
172
186
|
requirement: !ruby/object:Gem::Requirement
|
|
173
187
|
requirements:
|
|
174
188
|
- - "~>"
|
|
175
189
|
- !ruby/object:Gem::Version
|
|
176
|
-
version: '1'
|
|
190
|
+
version: '1.5'
|
|
177
191
|
type: :development
|
|
178
192
|
prerelease: false
|
|
179
193
|
version_requirements: !ruby/object:Gem::Requirement
|
|
180
194
|
requirements:
|
|
181
195
|
- - "~>"
|
|
182
196
|
- !ruby/object:Gem::Version
|
|
183
|
-
version: '1'
|
|
197
|
+
version: '1.5'
|
|
198
|
+
- !ruby/object:Gem::Dependency
|
|
199
|
+
name: standard-rspec
|
|
200
|
+
requirement: !ruby/object:Gem::Requirement
|
|
201
|
+
requirements:
|
|
202
|
+
- - "~>"
|
|
203
|
+
- !ruby/object:Gem::Version
|
|
204
|
+
version: '0.3'
|
|
205
|
+
type: :development
|
|
206
|
+
prerelease: false
|
|
207
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
208
|
+
requirements:
|
|
209
|
+
- - "~>"
|
|
210
|
+
- !ruby/object:Gem::Version
|
|
211
|
+
version: '0.3'
|
|
212
|
+
- !ruby/object:Gem::Dependency
|
|
213
|
+
name: rubocop-rails
|
|
214
|
+
requirement: !ruby/object:Gem::Requirement
|
|
215
|
+
requirements:
|
|
216
|
+
- - "~>"
|
|
217
|
+
- !ruby/object:Gem::Version
|
|
218
|
+
version: '2.33'
|
|
219
|
+
type: :development
|
|
220
|
+
prerelease: false
|
|
221
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
222
|
+
requirements:
|
|
223
|
+
- - "~>"
|
|
224
|
+
- !ruby/object:Gem::Version
|
|
225
|
+
version: '2.33'
|
|
226
|
+
- !ruby/object:Gem::Dependency
|
|
227
|
+
name: rubocop-rspec
|
|
228
|
+
requirement: !ruby/object:Gem::Requirement
|
|
229
|
+
requirements:
|
|
230
|
+
- - "~>"
|
|
231
|
+
- !ruby/object:Gem::Version
|
|
232
|
+
version: '3.8'
|
|
233
|
+
type: :development
|
|
234
|
+
prerelease: false
|
|
235
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
236
|
+
requirements:
|
|
237
|
+
- - "~>"
|
|
238
|
+
- !ruby/object:Gem::Version
|
|
239
|
+
version: '3.8'
|
|
240
|
+
- !ruby/object:Gem::Dependency
|
|
241
|
+
name: rubocop-thread_safety
|
|
242
|
+
requirement: !ruby/object:Gem::Requirement
|
|
243
|
+
requirements:
|
|
244
|
+
- - "~>"
|
|
245
|
+
- !ruby/object:Gem::Version
|
|
246
|
+
version: '0.7'
|
|
247
|
+
type: :development
|
|
248
|
+
prerelease: false
|
|
249
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
250
|
+
requirements:
|
|
251
|
+
- - "~>"
|
|
252
|
+
- !ruby/object:Gem::Version
|
|
253
|
+
version: '0.7'
|
|
184
254
|
- !ruby/object:Gem::Dependency
|
|
185
255
|
name: appraisal
|
|
186
256
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -195,6 +265,20 @@ dependencies:
|
|
|
195
265
|
- - "~>"
|
|
196
266
|
- !ruby/object:Gem::Version
|
|
197
267
|
version: '2'
|
|
268
|
+
- !ruby/object:Gem::Dependency
|
|
269
|
+
name: bundler-audit
|
|
270
|
+
requirement: !ruby/object:Gem::Requirement
|
|
271
|
+
requirements:
|
|
272
|
+
- - "~>"
|
|
273
|
+
- !ruby/object:Gem::Version
|
|
274
|
+
version: '0.9'
|
|
275
|
+
type: :development
|
|
276
|
+
prerelease: false
|
|
277
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
278
|
+
requirements:
|
|
279
|
+
- - "~>"
|
|
280
|
+
- !ruby/object:Gem::Version
|
|
281
|
+
version: '0.9'
|
|
198
282
|
- !ruby/object:Gem::Dependency
|
|
199
283
|
name: memory_profiler
|
|
200
284
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -258,14 +342,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
258
342
|
requirements:
|
|
259
343
|
- - ">="
|
|
260
344
|
- !ruby/object:Gem::Version
|
|
261
|
-
version: '
|
|
345
|
+
version: '3.4'
|
|
262
346
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
263
347
|
requirements:
|
|
264
348
|
- - ">="
|
|
265
349
|
- !ruby/object:Gem::Version
|
|
266
350
|
version: '0'
|
|
267
351
|
requirements: []
|
|
268
|
-
rubygems_version:
|
|
352
|
+
rubygems_version: 4.0.6
|
|
269
353
|
specification_version: 4
|
|
270
354
|
summary: Unified JSON request logging for Grape on Rails with DB timing.
|
|
271
355
|
test_files: []
|