routes-analyzer 0.1.1 → 0.1.4
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/README.md +41 -3
- data/lib/routes/analyzer/middleware.rb +53 -3
- data/lib/routes/analyzer/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 79618d6dca3b9246b8023943d2863bc985e3d9674fd56e51aec84ad0c10ebf62
|
|
4
|
+
data.tar.gz: 07043a67f3c6011aacc34097476444e45c7749ed8134bd71b48bb29ffe47cdff
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 86f3904c67a101f44776d2d583c1f818340b5f79218a9ac0297a3eca2045faaff4142218cdb8e8a1bc4ec68ac122918aa237845dd2ad8a068a4ee2a45804058b
|
|
7
|
+
data.tar.gz: 43bf9d60f739f769efe4bd35a628a30537298226da1b5b8457f98e726168718361f292663eaa47a1d811baac744d489278a0a969bcb0e13f3792c791be5a9b78
|
data/README.md
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
# Routes::Analyzer
|
|
2
2
|
|
|
3
|
+
[](https://badge.fury.io/rb/routes-analyzer)
|
|
4
|
+
|
|
3
5
|
A Ruby on Rails plugin that tracks and analyzes route usage in your application. It uses Redis to store route access patterns and provides insights into which routes are being used and which are not.
|
|
4
6
|
|
|
5
7
|
## Features
|
|
6
8
|
|
|
7
9
|
- **Route Usage Tracking**: Automatically tracks which routes are accessed and how often
|
|
10
|
+
- **Smart Parameter Handling**: Routes with parameters (like `/users/:id`) are properly grouped under a single pattern instead of creating separate entries for each parameter value
|
|
8
11
|
- **Redis Storage**: Uses Redis to store usage statistics efficiently
|
|
9
12
|
- **Configurable Timeframe**: Set custom analysis periods (default 30 days)
|
|
10
13
|
- **Comprehensive Reporting**: Shows both used and unused routes
|
|
@@ -109,12 +112,47 @@ Displays current configuration and tests Redis connectivity.
|
|
|
109
112
|
## How It Works
|
|
110
113
|
|
|
111
114
|
1. **Middleware Integration**: The plugin automatically adds middleware to your Rails application
|
|
112
|
-
2. **
|
|
113
|
-
|
|
115
|
+
2. **Route Filtering**: Only routes explicitly defined in `routes.rb` are tracked. This ensures that:
|
|
116
|
+
- Undefined routes (404 errors) are not tracked
|
|
117
|
+
- Catch-all routes that handle unknown paths don't pollute the data
|
|
118
|
+
- Only legitimate application routes are analyzed
|
|
119
|
+
3. **Request Tracking**: Each valid HTTP request is analyzed to extract route information
|
|
120
|
+
4. **Redis Storage**: Usage data is stored in Redis with the following structure:
|
|
114
121
|
- Route path and HTTP method
|
|
115
122
|
- Access count within the timeframe
|
|
116
123
|
- Last access timestamp
|
|
117
|
-
|
|
124
|
+
5. **Data Expiration**: Redis keys automatically expire after the configured timeframe plus a buffer period
|
|
125
|
+
|
|
126
|
+
## Route Detection
|
|
127
|
+
|
|
128
|
+
The middleware uses Rails' routing system to determine if a route is valid:
|
|
129
|
+
|
|
130
|
+
- **Path Parameters Check**: Verifies that Rails recognized the route and set path parameters
|
|
131
|
+
- **Route Recognition**: Uses `Rails.application.routes.recognize_path` to confirm the route exists in `routes.rb`
|
|
132
|
+
- **Error Handling**: Gracefully handles routing errors and invalid requests without tracking them
|
|
133
|
+
|
|
134
|
+
This approach ensures that only routes you've intentionally defined are included in the usage analysis.
|
|
135
|
+
|
|
136
|
+
## Parameterized Route Handling
|
|
137
|
+
|
|
138
|
+
The gem intelligently handles routes with parameters by tracking them under their route pattern rather than individual parameter values:
|
|
139
|
+
|
|
140
|
+
- **Route Definition**: `/users/:id` in `routes.rb`
|
|
141
|
+
- **Actual Requests**: `/users/123`, `/users/456`, `/users/789`
|
|
142
|
+
- **Tracked As**: Single entry for `/users/:id` with combined statistics
|
|
143
|
+
|
|
144
|
+
This means that accessing `/users/123` three times and `/users/456` two times will show up as 5 total accesses to the `/users/:id` route pattern, not as separate routes.
|
|
145
|
+
|
|
146
|
+
**Example Output:**
|
|
147
|
+
```
|
|
148
|
+
COUNT ROUTE METHOD CONTROLLER#ACTION
|
|
149
|
+
--------------------------------------------------------------
|
|
150
|
+
15 /users/:id GET users#show
|
|
151
|
+
8 /users/:id/profile GET users#profile
|
|
152
|
+
23 /posts/:id GET posts#show
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
This grouping provides much more meaningful insights into which route patterns are being used in your application.
|
|
118
156
|
|
|
119
157
|
## Data Structure
|
|
120
158
|
|
|
@@ -23,6 +23,9 @@ module Routes
|
|
|
23
23
|
return false unless Routes::Analyzer.track_usage?
|
|
24
24
|
return false unless env["action_controller.instance"]
|
|
25
25
|
|
|
26
|
+
# Check if the route is actually defined in routes.rb
|
|
27
|
+
return false unless route_defined_in_rails?(env)
|
|
28
|
+
|
|
26
29
|
true
|
|
27
30
|
rescue => e
|
|
28
31
|
Rails.logger.warn "Routes::Analyzer: Failed to check tracking conditions: #{e.message}"
|
|
@@ -57,19 +60,49 @@ module Routes
|
|
|
57
60
|
Rails.logger.warn "Routes::Analyzer: Failed to track route usage: #{e.message}"
|
|
58
61
|
end
|
|
59
62
|
|
|
63
|
+
def route_defined_in_rails?(env)
|
|
64
|
+
request = Rack::Request.new(env)
|
|
65
|
+
|
|
66
|
+
# First check: if Rails didn't set path_parameters, it means the route wasn't recognized
|
|
67
|
+
# This happens when Rails can't match the request to any defined route
|
|
68
|
+
path_params = env["action_dispatch.request.path_parameters"]
|
|
69
|
+
return false unless path_params
|
|
70
|
+
|
|
71
|
+
# Second check: verify that Rails can recognize this path/method combination
|
|
72
|
+
# This ensures the route is actually defined in routes.rb and not just handled by a catch-all
|
|
73
|
+
route_exists = Rails.application.routes.recognize_path(
|
|
74
|
+
request.path_info,
|
|
75
|
+
method: request.request_method.downcase.to_sym
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return true if route_exists
|
|
79
|
+
false
|
|
80
|
+
rescue ActionController::RoutingError, NoMethodError
|
|
81
|
+
# If recognize_path raises RoutingError, the route is not defined in routes.rb
|
|
82
|
+
# NoMethodError can occur if the controller/action doesn't exist
|
|
83
|
+
false
|
|
84
|
+
rescue => e
|
|
85
|
+
Rails.logger.warn "Routes::Analyzer: Error checking route definition: #{e.message}"
|
|
86
|
+
false
|
|
87
|
+
end
|
|
88
|
+
|
|
60
89
|
def extract_route_info(env, request)
|
|
61
90
|
# Get the matched route from Rails
|
|
62
91
|
if env["action_controller.instance"]
|
|
63
92
|
controller = env["action_controller.instance"]
|
|
64
93
|
action = controller.action_name
|
|
65
94
|
controller_name = controller.controller_name
|
|
95
|
+
method = request.request_method.upcase
|
|
96
|
+
|
|
97
|
+
# Find the route pattern instead of using the actual path
|
|
98
|
+
route_path = find_route_pattern(controller_name, action, method)
|
|
66
99
|
|
|
67
|
-
#
|
|
68
|
-
route_path
|
|
100
|
+
# Fallback to actual path if pattern not found
|
|
101
|
+
route_path ||= request.path_info
|
|
69
102
|
|
|
70
103
|
{
|
|
71
104
|
route: route_path,
|
|
72
|
-
method:
|
|
105
|
+
method: method,
|
|
73
106
|
controller: controller_name,
|
|
74
107
|
action: action
|
|
75
108
|
}
|
|
@@ -79,6 +112,23 @@ module Routes
|
|
|
79
112
|
nil
|
|
80
113
|
end
|
|
81
114
|
|
|
115
|
+
def find_route_pattern(controller_name, action, method)
|
|
116
|
+
return nil unless defined?(Rails) && Rails.application
|
|
117
|
+
|
|
118
|
+
Rails.application.routes.routes.each do |route|
|
|
119
|
+
if route.defaults[:controller] == controller_name &&
|
|
120
|
+
route.defaults[:action] == action &&
|
|
121
|
+
route.verb == method
|
|
122
|
+
return route.path.spec.to_s.gsub(/\(\.:format\)$/, "")
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
nil
|
|
127
|
+
rescue => e
|
|
128
|
+
Rails.logger.warn "Routes::Analyzer: Failed to find route pattern: #{e.message}"
|
|
129
|
+
nil
|
|
130
|
+
end
|
|
131
|
+
|
|
82
132
|
def build_redis_key(route, method)
|
|
83
133
|
"#{configuration.redis_key_prefix}:#{method}:#{route.gsub('/', ':')}"
|
|
84
134
|
end
|