rorvswild 1.6.2 → 1.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -263
- data/lib/rorvswild/agent.rb +0 -5
- data/lib/rorvswild/client.rb +8 -3
- data/lib/rorvswild/deployment.rb +12 -7
- data/lib/rorvswild/installer.rb +11 -1
- data/lib/rorvswild/local/javascript/local.js +13 -1
- data/lib/rorvswild/local/local.html.erb +8 -4
- data/lib/rorvswild/local/middleware.rb +4 -0
- data/lib/rorvswild/local/stylesheet/local.css +105 -132
- data/lib/rorvswild/local/stylesheet/vendor/prism.css +10 -9
- data/lib/rorvswild/plugin/active_job.rb +2 -0
- data/lib/rorvswild/plugin/active_record.rb +22 -2
- data/lib/rorvswild/queue.rb +3 -0
- data/lib/rorvswild/section.rb +4 -2
- data/lib/rorvswild/version.rb +1 -1
- data/lib/rorvswild.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd38e8268715a48ce8f49f648317660e41a512d80bb445d3f1ae7800ff13c7a8
|
4
|
+
data.tar.gz: 310aac7f6ac148f387e03f690eb7b54bfe8d1a25a0f450ccfdb2ec21245b7d28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4975dcbaaf1df79282ca4e46277c201bbb21443ab3f59a1c44f3bd96573ca8ed56a25c748f5bd29e38dbe154c11cdae475768229603c9da6e16c2b505bf972c0
|
7
|
+
data.tar.gz: ff0593aa35f2e9352e66f87e9c0a8a6e2d99803b8740325755790b84eb5fc681646fa50f19935595d4534f513dc5113424326f4b180707d288467ff7d3be8293
|
data/README.md
CHANGED
@@ -4,28 +4,29 @@
|
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/rorvswild.svg)](https://badge.fury.io/rb/rorvswild)
|
5
5
|
[![Maintainability](https://api.codeclimate.com/v1/badges/2c4805cf658d7af794fe/maintainability)](https://codeclimate.com/github/BaseSecrete/rorvswild/maintainability)
|
6
6
|
|
7
|
-
<img align="right" src="./images/rorvswild_logo.jpg">
|
7
|
+
<img align="right" width="120px" src="./images/rorvswild_logo.jpg">
|
8
8
|
|
9
9
|
*RoRvsWild* is a ruby gem to monitor performances and exceptions in Ruby on Rails applications.
|
10
10
|
|
11
|
-
This gem has a double mode, development and production
|
12
|
-
It can be used without an account to monitor your requests performances in your development environment.
|
11
|
+
This gem has a double mode, **development** and **production**.
|
12
|
+
It can be used without an account to monitor your requests performances in your development environment.
|
13
13
|
It can also be used in your production and staging environments with an account on https://rorvswild.com. With such an account you also get extra benefits such as 30 day trace, background jobs monitoring, exceptions monitoring and notifications.
|
14
14
|
|
15
|
+
## Development mode
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
#### Install the gem
|
17
|
+
### Install the gem
|
19
18
|
|
20
19
|
* Add in your Gemfile `gem "rorvswild"`
|
21
20
|
* Run `bundle install` in you terminal
|
22
21
|
* Restart your local server and you’ll see a small button in the bottom left corner of your page.
|
23
22
|
|
24
|
-
|
23
|
+
<img width="166px" src="./images/rorvswild_local_button.png">
|
24
|
+
|
25
|
+
Click on the button, or navigate to http://localhost:3000/rorvswild to see the details panel:
|
25
26
|
|
26
|
-
|
27
|
+
![RoRvsWild Local](./images/rorvswild_local.png)
|
27
28
|
|
28
|
-
|
29
|
+
## Production mode
|
29
30
|
|
30
31
|
**To monitor your production or staging environment, you need an API key.**
|
31
32
|
Signup on https://www.rorvswild.com and create an app to get one.
|
@@ -36,260 +37,10 @@ Signup on https://www.rorvswild.com and create an app to get one.
|
|
36
37
|
* Deploy/Restart your app
|
37
38
|
* Make a few requests and refresh your app page on rorvswild.com to view the dashboard.
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
If you prefer to use an initializer, you can do the following:
|
42
|
-
|
43
|
-
```ruby
|
44
|
-
# config/initializers/rorvswild.rb
|
45
|
-
RorVsWild.start(api_key: API_KEY)
|
46
|
-
```
|
47
|
-
|
48
|
-
You can create unlimited apps on *rorvswild.com*. If you want to monitor your staging environment, create a new app and edit your rorvswild.yml to add the API key.
|
49
|
-
|
50
|
-
In case there is no data in the dashboard, you can run in a rails console : `RorVsWild.check`.
|
51
|
-
|
52
|
-
## Development mode: *RoRvsWild Local*
|
53
|
-
|
54
|
-
![RoRvsWild Local](./images/rorvswild_local.jpg)
|
55
|
-
|
56
|
-
*RorVsWild Local* monitors the performances of requests in development environment.
|
57
|
-
It shows most of the requests performances insights *RoRvsWild.com* displays. **A big difference is everything works locally and no data is sent and recorded on our servers**. You don’t even need an account to use it.
|
58
|
-
|
59
|
-
*RoRvsWild Local* renders a small button in the bottom left corner of your page showing the runtime of the current request. If you click on it, you get all the profiled sections ordered by impact, which is depending on the sections average runtime and the calls count. As on RoRvsWild.com, the bottleneck is always on the top of the list.
|
60
|
-
|
61
|
-
You may want to hide or change the widget position like in the example below with the `widget` option :
|
62
|
-
|
63
|
-
```yaml
|
64
|
-
# config/rorvswild.yml
|
65
|
-
|
66
|
-
development:
|
67
|
-
widget: top-right
|
68
|
-
|
69
|
-
#accepted values : top-left, top-right, bottom-right, bottom-left (default), hidden
|
70
|
-
```
|
71
|
-
|
72
|
-
You can still access the profiler at http://localhost:3000/rorvswild if you choose to hide the widget.
|
73
|
-
|
74
|
-
Be aware that the performances on your development machine may vary from the production server. Obviously because of the different hardware and database size. Also, Rails is reloading all the code in development environment and this takes quite a lot of time.
|
75
|
-
To prevent this behaviour and better match the production, turn on cache_classes in your config/environments/development.rb:
|
76
|
-
|
77
|
-
```
|
78
|
-
Rails.application.configure do
|
79
|
-
config.cache_classes = true
|
80
|
-
end
|
81
|
-
```
|
82
|
-
|
83
|
-
If you are using `Rack::Deflater` middleware you won't see the small button in the corner. Because of the compression it is not possible to inject some JavaScript into the page. In that case visit http://localhost:3000/rorvswild to see the profiler.
|
84
|
-
|
85
|
-
## Production mode: *RoRvsWild.com*
|
86
|
-
|
87
|
-
![RoRvsWild.com](./images/rorvswild_prod.jpg)
|
88
|
-
|
89
|
-
*RoRvsWild.com* makes it easy to monitor requests, background jobs and errors in your production and staging environment.
|
90
|
-
It also comes with some extra options listed below.
|
91
|
-
|
92
|
-
#### Measure any section of code
|
93
|
-
|
94
|
-
RorVsWild measures a lot of events such as SQL queries. But it might not be enough for you. There is a solution to measure any section of code to help you find the most hidden bottlenecks.
|
95
|
-
|
96
|
-
```ruby
|
97
|
-
# Measure a code given as a string
|
98
|
-
RorVsWild.measure("bubble_sort(array)")
|
99
|
-
|
100
|
-
# Measure a code given as a block
|
101
|
-
RorVsWild.measure { bubble_sort(array) }
|
102
|
-
|
103
|
-
# Measure a code given as a block with an optional description
|
104
|
-
RorVsWild.measure("Optional description") { bubble_sort(array) }
|
105
|
-
```
|
106
|
-
|
107
|
-
For each custom measure, a section is added with the file name and line number where it has been called.
|
108
|
-
|
109
|
-
#### Send errors manually
|
110
|
-
|
111
|
-
When you already have a begin / rescue block, this manner suits well:
|
112
|
-
|
113
|
-
```ruby
|
114
|
-
begin
|
115
|
-
# Your code ...
|
116
|
-
rescue => exception
|
117
|
-
RorVsWild.record_error(exception)
|
118
|
-
end
|
119
|
-
```
|
120
|
-
|
121
|
-
If you prefer to be concise, just run the code from a block:
|
122
|
-
|
123
|
-
```ruby
|
124
|
-
RorVsWild.catch_error { 1 / 0 } # => #<ZeroDivisionError: divided by 0>
|
125
|
-
```
|
126
|
-
|
127
|
-
Moreover, you can provide extra details when capturing errors:
|
128
|
-
|
129
|
-
```ruby
|
130
|
-
RorVsWild.record_error(exception, {something: "important"})
|
131
|
-
```
|
132
|
-
|
133
|
-
```ruby
|
134
|
-
RorVsWild.catch_error(something: "important") { 1 / 0 }
|
135
|
-
```
|
136
|
-
|
137
|
-
It is also possible to pre-fill this context data at the begining of each request or job :
|
138
|
-
|
139
|
-
```ruby
|
140
|
-
class ApplicationController < ActionController::Base
|
141
|
-
before_action :prefill_error_context
|
142
|
-
|
143
|
-
def prefill_error_context
|
144
|
-
RorVsWild.merge_error_context(something: "important")
|
145
|
-
end
|
146
|
-
end
|
147
|
-
```
|
148
|
-
|
149
|
-
#### Ignore requests, jobs, exceptions and plugins
|
150
|
-
|
151
|
-
From the configuration file, you can tell RorVsWild to skip monitoring some requests, jobs, exceptions and plugins.
|
152
|
-
|
153
|
-
```yaml
|
154
|
-
# config/rorvswild.yml
|
155
|
-
production:
|
156
|
-
api_key: API_KEY
|
157
|
-
ignore_requests:
|
158
|
-
- HeartbeatController#show
|
159
|
-
- !ruby/regexp /SecretController/ # Ignore the entire controller
|
160
|
-
ignore_jobs:
|
161
|
-
- SecretJob
|
162
|
-
- !ruby/regexp /Secret::/ # Ignore the entire Secret namespace
|
163
|
-
ignore_exceptions:
|
164
|
-
- ActionController::RoutingError # Ignore by default any 404
|
165
|
-
- ZeroDivisionError
|
166
|
-
- !ruby/regexp /Secret::/ # Ignore all secret errors
|
167
|
-
ignore_plugins:
|
168
|
-
- Sidekiq # If you don't want to monitor your Sidekiq jobs
|
169
|
-
```
|
170
|
-
|
171
|
-
Here is the equivalent if you prefer initialising RorVsWild manually.
|
172
|
-
|
173
|
-
```ruby
|
174
|
-
# config/initializers/rorvswild.rb
|
175
|
-
RorVsWild.start(
|
176
|
-
api_key: "API_KEY",
|
177
|
-
ignore_requests: ["ApplicationController#heartbeat", /SecretController/],
|
178
|
-
ignore_jobs: ["SecretJob", /Secret::/],
|
179
|
-
ignore_exceptions: ["ActionController::RoutingError", "ZeroDivisionError", /Secret::/],
|
180
|
-
ignore_plugins: ["Sidekiq"])
|
181
|
-
```
|
182
|
-
|
183
|
-
Finally here is the list of all plugins you can ignore :
|
184
|
-
|
185
|
-
- ActionController
|
186
|
-
- ActionMailer
|
187
|
-
- ActionView
|
188
|
-
- ActiveJob
|
189
|
-
- ActiveRecord
|
190
|
-
- DelayedJob
|
191
|
-
- Elasticsearch
|
192
|
-
- Mongo
|
193
|
-
- NetHttp
|
194
|
-
- Redis
|
195
|
-
- Resque
|
196
|
-
- Sidekiq
|
197
|
-
|
198
|
-
#### Change logger
|
199
|
-
|
200
|
-
By default RorVsWild uses `Rails.logger` or standard output. However in some cases you want to isolate RorVsWild's logs.
|
201
|
-
To do that, you have to specifiy the log destination via the `logger` option :
|
202
|
-
|
203
|
-
```yaml
|
204
|
-
# config/rorvswild.yml
|
205
|
-
production:
|
206
|
-
api_key: API_KEY
|
207
|
-
logger: log/rorvswild.yml
|
208
|
-
```
|
209
|
-
|
210
|
-
Here is the equivalent if you prefer initialising RorVsWild manually :
|
211
|
-
|
212
|
-
```ruby
|
213
|
-
# config/initializers/rorvswild.rb
|
214
|
-
RorVsWild.start(api_key: "API_KEY", logger: "log/rorvswild.log")
|
215
|
-
```
|
216
|
-
|
217
|
-
In the case you want a custom logger such as Syslog, you can only do it by initialising it manually :
|
218
|
-
|
219
|
-
```ruby
|
220
|
-
# config/initializers/rorvswild.rb
|
221
|
-
RorVsWild.start(api_key: "API_KEY", logger: Logger::Syslog.new)
|
222
|
-
```
|
223
|
-
|
224
|
-
### Deployment tracking
|
225
|
-
|
226
|
-
Since version 1.6.0, RorVsWild compares performances between each deployment.
|
227
|
-
That is convenient to detect quickly a performance deterioration.
|
228
|
-
|
229
|
-
It is working without any actions from your part if the application is :
|
230
|
-
|
231
|
-
- Deployed via Capistrano
|
232
|
-
- Inside a Git repositoriy
|
233
|
-
- Hosted on Heroku if [Dyno metadata](https://devcenter.heroku.com/articles/dyno-metadata) is enabled
|
234
|
-
- Hosted on Scalingo
|
235
|
-
|
236
|
-
Because we are not aware of all cloud hosting providers, there is a generic method to provide these data via the configuration :
|
237
|
-
|
238
|
-
```yaml
|
239
|
-
# config/rorvswild.yml
|
240
|
-
production:
|
241
|
-
api_key: API_KEY
|
242
|
-
deployment:
|
243
|
-
revision: <%= "Anything that will return the deployment version" %> # Mandatory
|
244
|
-
description: <%= "Eventually if you have a description such as a Git message" %>
|
245
|
-
author: <%= "Author's name of the deployment" %>
|
246
|
-
email: <%= "emailOf@theAuthor.com" %>
|
247
|
-
```
|
248
|
-
|
249
|
-
Here is the equivalent if you prefer initialising RorVsWild manually :
|
250
|
-
|
251
|
-
```ruby
|
252
|
-
# config/initializers/rorvswild.rb
|
253
|
-
RorVsWild.start(api_key: "API_KEY", deployment: {
|
254
|
-
revision: "Unique version number such as Git commit ID",
|
255
|
-
description: "Message such as in Git",
|
256
|
-
author: "Deployer's name",
|
257
|
-
email: "Deployer's email"
|
258
|
-
})
|
259
|
-
```
|
260
|
-
|
261
|
-
Only the revision is mandatory, but it's better if you are able to provide more information.
|
262
|
-
|
263
|
-
|
264
|
-
#### Server metrics monitoring
|
265
|
-
|
266
|
-
Since version 1.6.0 RorVsWild monitors server metrics such as load average, CPU, memory, swap and disk space.
|
267
|
-
For now, only Linux is supported.
|
268
|
-
The data are available in a server tab beside requests and jobs.
|
269
|
-
|
270
|
-
Metrics are grouped by hostnames.
|
271
|
-
Cloud providers give random hostnames which change on every deployment.
|
272
|
-
You can manually define them:
|
273
|
-
|
274
|
-
```yaml
|
275
|
-
# config/rorvswild.yml
|
276
|
-
production:
|
277
|
-
api_key: API_KEY
|
278
|
-
server:
|
279
|
-
name: <%= "Some code that return a relevant hostname" %>
|
280
|
-
```
|
281
|
-
|
282
|
-
Here is the equivalent if you prefer initialising RorVsWild manually :
|
40
|
+
![RoRvsWild Production](./images/rorvswild_prod.png)
|
283
41
|
|
284
|
-
|
285
|
-
# config/initializers/rorvswild.rb
|
286
|
-
RorVsWild.start(api_key: "API_KEY", server: {name: "host.name"})
|
287
|
-
```
|
42
|
+
## Full documentation
|
288
43
|
|
289
|
-
|
44
|
+
- [Installation](https://www.rorvswild.com/docs/get-started/installation)
|
45
|
+
- [Configuration](https://www.rorvswild.com/docs/get-started/configuration)
|
290
46
|
|
291
|
-
1. Fork it ( https://github.com/[my-github-username]/rorvswild/fork )
|
292
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
293
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
294
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
295
|
-
5. Create a new Pull Request
|
data/lib/rorvswild/agent.rb
CHANGED
@@ -36,7 +36,6 @@ module RorVsWild
|
|
36
36
|
RorVsWild.logger.debug("Start RorVsWild #{RorVsWild::VERSION}")
|
37
37
|
setup_plugins
|
38
38
|
cleanup_data
|
39
|
-
send_deployment
|
40
39
|
end
|
41
40
|
|
42
41
|
def load_features
|
@@ -160,10 +159,6 @@ module RorVsWild
|
|
160
159
|
config[:ignore_exceptions].any? { |str_or_regex| str_or_regex === exception.class.to_s }
|
161
160
|
end
|
162
161
|
|
163
|
-
def send_deployment
|
164
|
-
client.post("/deployments", deployment: Deployment.to_h)
|
165
|
-
end
|
166
|
-
|
167
162
|
#######################
|
168
163
|
### Private methods ###
|
169
164
|
#######################
|
data/lib/rorvswild/client.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "set"
|
2
4
|
require "uri"
|
3
5
|
require "json/ext"
|
@@ -7,7 +9,7 @@ module RorVsWild
|
|
7
9
|
class Client
|
8
10
|
HTTPS = "https".freeze
|
9
11
|
CERTIFICATE_AUTHORITIES_PATH = File.expand_path("../../../cacert.pem", __FILE__)
|
10
|
-
DEFAULT_TIMEOUT =
|
12
|
+
DEFAULT_TIMEOUT = 10
|
11
13
|
|
12
14
|
attr_reader :api_url, :api_key, :timeout, :threads
|
13
15
|
|
@@ -27,6 +29,7 @@ module RorVsWild
|
|
27
29
|
"X-Ruby-Version" => RUBY_VERSION,
|
28
30
|
}
|
29
31
|
@headers["X-Rails-Version"] = Rails.version if defined?(Rails)
|
32
|
+
@http_unauthorized = false
|
30
33
|
end
|
31
34
|
|
32
35
|
def post(path, data)
|
@@ -60,8 +63,10 @@ module RorVsWild
|
|
60
63
|
end
|
61
64
|
|
62
65
|
def transmit(request)
|
63
|
-
if http = take_or_create_connection
|
64
|
-
http.request(request)
|
66
|
+
if !@http_unauthorized && http = take_or_create_connection
|
67
|
+
response = http.request(request)
|
68
|
+
@http_unauthorized = true if response.code == "401"
|
69
|
+
response
|
65
70
|
end
|
66
71
|
rescue Exception => ex
|
67
72
|
RorVsWild.logger.error(ex.full_message)
|
data/lib/rorvswild/deployment.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "open3"
|
4
|
+
|
3
5
|
module RorVsWild
|
4
6
|
module Deployment
|
5
7
|
def self.load_config(config)
|
@@ -57,15 +59,13 @@ module RorVsWild
|
|
57
59
|
end
|
58
60
|
|
59
61
|
def self.read_from_scalingo
|
60
|
-
return unless ENV["SOURCE_VERSION"]
|
61
62
|
@revision = ENV["SOURCE_VERSION"]
|
62
63
|
end
|
63
64
|
|
64
65
|
def self.read_from_git
|
65
|
-
@revision = normalize_string(
|
66
|
-
return unless
|
67
|
-
lines =
|
68
|
-
return unless lines
|
66
|
+
return unless @revision = normalize_string(shell("git rev-parse HEAD"))
|
67
|
+
return @revision unless log_stdout = shell("git log -1 --pretty=%an%n%ae%n%B")
|
68
|
+
lines = log_stdout.lines
|
69
69
|
@author = normalize_string(lines[0])
|
70
70
|
@email = normalize_string(lines[1])
|
71
71
|
@description = lines[2..-1] && normalize_string(lines[2..-1].join)
|
@@ -75,8 +75,8 @@ module RorVsWild
|
|
75
75
|
def self.read_from_capistrano
|
76
76
|
return unless File.readable?("REVISION")
|
77
77
|
return unless @revision = File.read("REVISION")
|
78
|
-
|
79
|
-
|
78
|
+
return unless stdout = shell("git --git-dir ../../repo log --format=%an%n%ae%n%B -n 1 #{@revision}")
|
79
|
+
lines = stdout.lines
|
80
80
|
@author = normalize_string(lines[0])
|
81
81
|
@email = normalize_string(lines[1])
|
82
82
|
@description = lines[2..-1] && normalize_string(lines[2..-1].join)
|
@@ -89,5 +89,10 @@ module RorVsWild
|
|
89
89
|
string.empty? ? nil : string
|
90
90
|
end
|
91
91
|
end
|
92
|
+
|
93
|
+
def self.shell(command)
|
94
|
+
stdout, stderr, process = Open3.capture3(command) rescue nil
|
95
|
+
stdout if process && process.success?
|
96
|
+
end
|
92
97
|
end
|
93
98
|
end
|
data/lib/rorvswild/installer.rb
CHANGED
@@ -17,6 +17,16 @@ module RorVsWild
|
|
17
17
|
|
18
18
|
def self.template(api_key)
|
19
19
|
<<YAML
|
20
|
+
development:
|
21
|
+
# Widget position
|
22
|
+
# widget: top-left, top-right, bottom-left, bottom-right or hidden
|
23
|
+
|
24
|
+
# Open files in your text editor by clicking from the local widget.
|
25
|
+
# VSCode: vscode://file${path}:${line}
|
26
|
+
# Sublime: subl://${path}:${line}
|
27
|
+
# It should be set with an env variable when developers are not using the same editor.
|
28
|
+
editor_url: <%= ENV.fetch("RORVSWILD_EDITOR_URL", "vscode://file${path}:${line}") %>
|
29
|
+
|
20
30
|
production:
|
21
31
|
api_key: #{api_key}
|
22
32
|
# ignore_requests: # Do not monitor the following actions
|
@@ -46,7 +56,7 @@ production:
|
|
46
56
|
# revision: <%= "Anything that will return the deployment version" %> # Mandatory
|
47
57
|
# description: <%= "Eventually if you have a description such as a Git message" %>
|
48
58
|
# author: <%= "Author's name of the deployment" %>
|
49
|
-
|
59
|
+
# email: <%= "emailOf@theAuthor.example" %>
|
50
60
|
YAML
|
51
61
|
end
|
52
62
|
end
|
@@ -3,6 +3,7 @@ var RorVsWild = this.RorVsWild = {};
|
|
3
3
|
RorVsWild.Local = function(container) {
|
4
4
|
this.root = container
|
5
5
|
this.embedded = !(this.active = location.pathname == "/rorvswild")
|
6
|
+
RorVsWild.Local.editorUrl = container.getAttribute("data-editor-url")
|
6
7
|
this.fetchData()
|
7
8
|
}
|
8
9
|
|
@@ -44,6 +45,7 @@ RorVsWild.Local.prototype.expand = function() {
|
|
44
45
|
this.currentRequest = this.requests[0]
|
45
46
|
this.active = true
|
46
47
|
this.render()
|
48
|
+
window.addEventListener("keydown", this.keydown.bind(this))
|
47
49
|
}
|
48
50
|
|
49
51
|
RorVsWild.Local.prototype.collapse = function() {
|
@@ -51,6 +53,11 @@ RorVsWild.Local.prototype.collapse = function() {
|
|
51
53
|
this.render()
|
52
54
|
}
|
53
55
|
|
56
|
+
RorVsWild.Local.prototype.keydown = function(event) {
|
57
|
+
if (event.key == "Escape")
|
58
|
+
this.collapse()
|
59
|
+
}
|
60
|
+
|
54
61
|
RorVsWild.Local.formatRuntime = function(runtime) {
|
55
62
|
return runtime > 0 && runtime < 1 ? "<1" : Math.round(runtime)
|
56
63
|
}
|
@@ -112,7 +119,7 @@ RorVsWild.Local.Request.prototype.runtime = function() {
|
|
112
119
|
RorVsWild.Local.Request.prototype.sections = function() {
|
113
120
|
return this.data.sections.map(function(section) {
|
114
121
|
var runtime = (section.total_runtime - section.children_runtime)
|
115
|
-
|
122
|
+
var object = {
|
116
123
|
impact: RorVsWild.Local.formatImpact(runtime * 100 / this.data.runtime),
|
117
124
|
averageRuntime: RorVsWild.Local.formatRuntime(runtime / section.calls),
|
118
125
|
command: section.kind != "view" ? section.command : null,
|
@@ -123,5 +130,10 @@ RorVsWild.Local.Request.prototype.sections = function() {
|
|
123
130
|
runtime: runtime,
|
124
131
|
language: RorVsWild.Local.kindToLanguage(section.kind),
|
125
132
|
}
|
133
|
+
if (RorVsWild.Local.editorUrl) {
|
134
|
+
var path = section.file[0] == "/" ? section.file : this.data.environment.cwd + "/" + section.file
|
135
|
+
object.url = RorVsWild.Local.editorUrl.replace("${path}", path).replace("${line}", section.line)
|
136
|
+
}
|
137
|
+
return object
|
126
138
|
}.bind(this)).sort(function(a, b) { return b.runtime - a.runtime })
|
127
139
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div id="RorVsWild.Local" class="<%= widget_css %>">
|
2
|
-
<div data-barber="RorVsWild.Local">
|
2
|
+
<div data-barber="RorVsWild.Local" data-editor-url="<%= editor_url %>">
|
3
3
|
</div>
|
4
4
|
</div>
|
5
5
|
|
@@ -55,8 +55,7 @@
|
|
55
55
|
{{/currentRequest}}
|
56
56
|
</div>
|
57
57
|
<div class="rorvswild-local-panel__footer">
|
58
|
-
This data is not sent to rorvswild.com.
|
59
|
-
<a href="https://www.rorvswild.com" class="rorvswild-local-panel__footer__link">create an account</a>.
|
58
|
+
This data is not sent to rorvswild.com. <a href="https://www.rorvswild.com" class="rorvswild-local-panel__footer__link">Create an account</a> to monitor your production environment.
|
60
59
|
</div>
|
61
60
|
</div>
|
62
61
|
|
@@ -102,7 +101,12 @@
|
|
102
101
|
<div class="rorvswild-local-panel__request-details__section">
|
103
102
|
<div class="rorvswild-local-panel__request-details__section__main">
|
104
103
|
<span class="rorvswild-local-panel__request-details__section__file">
|
105
|
-
{{
|
104
|
+
{{#url}}
|
105
|
+
<a href="{{url}}" class="rorvswild-local-panel__request-details__section__file__name" title="Open in your editor">{{file}}<span>:{{line}}</span></a>
|
106
|
+
{{/url}}
|
107
|
+
{{^url}}
|
108
|
+
<span class="rorvswild-local-panel__request-details__section__file__name">{{file}}<span>:{{line}}</span></span>
|
109
|
+
{{/url}}
|
106
110
|
<div class="rorvswild-local-panel__request-details__section__code">
|
107
111
|
<span class="rorvswild-local-panel__request-details__section__kind">{{kind}}</span>
|
108
112
|
<span class="rorvswild-local-panel__request-details__section__command">
|
@@ -61,6 +61,10 @@ module RorVsWild
|
|
61
61
|
config && config[:widget] && "is-#{config[:widget]}"
|
62
62
|
end
|
63
63
|
|
64
|
+
def editor_url
|
65
|
+
RorVsWild.agent.config[:editor_url]
|
66
|
+
end
|
67
|
+
|
64
68
|
def inject_into(html)
|
65
69
|
if index = html.index("</body>")
|
66
70
|
markup = File.read(File.join(LOCAL_FOLDER, "local.html.erb"))
|
@@ -1,12 +1,10 @@
|
|
1
|
-
|
2
|
-
/************* TOGGLER **********************/
|
3
|
-
/********************************************/
|
4
|
-
|
1
|
+
/* TOGGLER */
|
5
2
|
.rorvswild-local-toggler {
|
6
|
-
background:
|
7
|
-
color:
|
8
|
-
|
9
|
-
|
3
|
+
background: rgb(17 20 27) !important;
|
4
|
+
color: rgb(182 202 255) !important;
|
5
|
+
font-weight: 700 !important;
|
6
|
+
box-shadow: 0 0 0 1px rgba(69,74,84,1) inset, 0 1px 4px 0px rgba(14,18,26,0.96) !important;
|
7
|
+
border-radius: 2px !important;
|
10
8
|
font-family: SF Mono, Menlo, Consolas, DejaVu Sans Mono, monospace !important;
|
11
9
|
font-size: 15px !important;
|
12
10
|
line-height: 24px !important;
|
@@ -15,18 +13,18 @@
|
|
15
13
|
left: 12px !important;
|
16
14
|
padding: 0 12px !important;
|
17
15
|
cursor: pointer !important;
|
18
|
-
z-index:
|
16
|
+
z-index: 99999999999999999 !important;
|
19
17
|
}
|
20
18
|
|
21
19
|
.rorvswild-local-toggler small {
|
22
|
-
color:
|
23
|
-
font-
|
20
|
+
color: rgb(146 149 159) !important;
|
21
|
+
font-weight: 400 !important;
|
22
|
+
font-size: 10px !important;
|
24
23
|
margin-left: 4px !important;
|
25
24
|
display: inline-block !important;
|
26
25
|
}
|
27
26
|
|
28
|
-
|
29
|
-
|
27
|
+
/* TOGGLER POSITION OPTION (default bottom-left) */
|
30
28
|
.is-top-right .rorvswild-local-toggler {
|
31
29
|
bottom: auto !important;
|
32
30
|
left: auto !important;
|
@@ -45,38 +43,29 @@
|
|
45
43
|
right: 12px !important;
|
46
44
|
}
|
47
45
|
|
48
|
-
.is-hidden .rorvswild-local-toggler {
|
49
|
-
display: none;
|
50
|
-
}
|
51
|
-
|
52
|
-
/********************************************/
|
53
|
-
/*************** PANEL **********************/
|
54
|
-
/********************************************/
|
46
|
+
.is-hidden .rorvswild-local-toggler { display: none; }
|
55
47
|
|
48
|
+
/* PANEL */
|
56
49
|
.rorvswild-local-panel {
|
57
|
-
background:
|
58
|
-
|
59
|
-
color: #eceef1 !important;
|
50
|
+
background: rgb(17 20 27) !important;
|
51
|
+
color: rgb(199 203 214) !important;
|
60
52
|
font-family: SF Mono, Menlo, Consolas, DejaVu Sans Mono, monospace !important;
|
61
53
|
font-size: 15px !important;
|
62
54
|
line-height: 24px !important;
|
63
55
|
position: fixed !important;
|
64
|
-
top:
|
65
|
-
left:
|
66
|
-
right:
|
67
|
-
bottom:
|
56
|
+
top: 0 !important;
|
57
|
+
left: 0 !important;
|
58
|
+
right: 0 !important;
|
59
|
+
bottom: 0 !important;
|
68
60
|
z-index: 100000000000000000 !important;
|
69
|
-
overflow: hidden !important;
|
70
|
-
display: -webkit-box !important;
|
71
|
-
display: -ms-flexbox !important;
|
72
61
|
display: flex !important;
|
73
|
-
-
|
74
|
-
|
75
|
-
|
76
|
-
flex-direction: column !important;
|
62
|
+
flex-direction: column !important;
|
63
|
+
overflow: hidden;
|
64
|
+
height: 100dvh;
|
77
65
|
}
|
78
66
|
|
79
|
-
.rorvswild-local-panel.is-hidden
|
67
|
+
.rorvswild-local-panel.is-hidden,
|
68
|
+
.rorvswild-local-panel:not(.is-hidden) + .rorvswild-local-toggler {
|
80
69
|
display: none !important;
|
81
70
|
}
|
82
71
|
|
@@ -88,41 +77,37 @@
|
|
88
77
|
}
|
89
78
|
|
90
79
|
.rorvswild-local-panel ::-moz-selection {
|
91
|
-
background:
|
92
|
-
color:
|
80
|
+
background: rgb(71 75 83) !important;
|
81
|
+
color: rgb(224 228 239) !important;
|
93
82
|
}
|
94
83
|
|
95
84
|
.rorvswild-local-panel ::selection {
|
96
|
-
background:
|
97
|
-
color:
|
85
|
+
background: rgb(71 75 83) !important;
|
86
|
+
color: rgb(224 228 239) !important;
|
98
87
|
}
|
99
88
|
|
100
89
|
.rorvswild-local-panel small {
|
101
|
-
color:
|
102
|
-
font-size:
|
103
|
-
|
90
|
+
color: rgb(146 149 159) !important;
|
91
|
+
font-size: 10px !important;
|
92
|
+
font-weight: 400 !important;
|
93
|
+
margin-left: 2px !important;
|
104
94
|
}
|
105
95
|
|
106
96
|
/* Panel Header */
|
107
97
|
.rorvswild-local-panel__header {
|
108
|
-
background:
|
109
|
-
z-index: 100000000000000005 !important;
|
98
|
+
background: rgb(26 29 36) !important;
|
110
99
|
padding: 12px !important;
|
111
|
-
box-shadow: 0 1px 2px 0 rgba(
|
112
|
-
display: -webkit-box;
|
113
|
-
display: -ms-flexbox;
|
100
|
+
box-shadow: 0 1px 2px 0 rgba(14,18,26, .8) !important;
|
114
101
|
display: flex;
|
115
102
|
}
|
116
103
|
|
117
104
|
.rorvswild-local-panel__header__title {
|
118
|
-
color:
|
105
|
+
color: rgb(199 203 214) !important;
|
119
106
|
text-transform: uppercase !important;
|
120
107
|
font-size: 12px !important;
|
121
108
|
letter-spacing: 2px !important;
|
122
109
|
text-align: center !important;
|
123
|
-
|
124
|
-
-ms-flex: 1;
|
125
|
-
flex: 1;
|
110
|
+
flex: 1;
|
126
111
|
}
|
127
112
|
|
128
113
|
.rorvswild-local-panel svg {
|
@@ -131,26 +116,18 @@
|
|
131
116
|
stroke-width: 2 !important;
|
132
117
|
fill: none !important;
|
133
118
|
stroke-linecap: square !important;
|
134
|
-
stroke:
|
119
|
+
stroke: rgb(146 149 159) !important;
|
135
120
|
stroke-miterlimit: 10 !important;
|
136
121
|
vertical-align: middle !important;
|
137
122
|
}
|
138
123
|
|
139
|
-
.rorvswild-local-panel svg:hover {
|
140
|
-
stroke: #eceef1 !important;
|
141
|
-
}
|
124
|
+
.rorvswild-local-panel svg:hover { stroke: rgb(199 203 214) !important; }
|
142
125
|
|
143
|
-
.rorvswild-local-panel__logo {
|
144
|
-
width: 60px !important;
|
145
|
-
}
|
126
|
+
.rorvswild-local-panel__logo { width: 60px !important; }
|
146
127
|
|
147
128
|
.rorvswild-local-panel__header__icons {
|
148
129
|
width: 60px !important;
|
149
|
-
display: -webkit-box !important;
|
150
|
-
display: -ms-flexbox !important;
|
151
130
|
display: flex !important;
|
152
|
-
-webkit-box-pack: end !important;
|
153
|
-
-ms-flex-pack: end !important;
|
154
131
|
justify-content: flex-end !important;
|
155
132
|
}
|
156
133
|
|
@@ -161,25 +138,23 @@
|
|
161
138
|
|
162
139
|
.rorvswild-local-panel__github svg {
|
163
140
|
stroke: none !important;
|
164
|
-
fill:
|
141
|
+
fill: rgb(146 149 159) !important;
|
165
142
|
}
|
166
143
|
|
167
144
|
.rorvswild-local-panel__github svg:hover {
|
168
145
|
stroke: none !important;
|
169
|
-
fill:
|
146
|
+
fill: rgb(199 203 214) !important;
|
170
147
|
}
|
171
148
|
|
172
149
|
/* Panel Content */
|
173
|
-
|
174
150
|
.rorvswild-local-panel__content {
|
175
|
-
-webkit-box-flex: 1 !important;
|
176
|
-
-ms-flex: 1 !important;
|
177
151
|
flex: 1 !important;
|
178
152
|
height: calc(100% - 48px) !important;
|
179
|
-
overflow-
|
153
|
+
overflow-y: auto;
|
154
|
+
overscroll-behavior: contain;
|
180
155
|
}
|
181
156
|
|
182
|
-
.rorvswild-local-panel__content::-webkit-scrollbar { width:
|
157
|
+
.rorvswild-local-panel__content::-webkit-scrollbar { width: 4px !important; }
|
183
158
|
|
184
159
|
.rorvswild-local-panel__content::-webkit-scrollbar-corner { background: transparent !important; }
|
185
160
|
|
@@ -189,44 +164,46 @@
|
|
189
164
|
}
|
190
165
|
|
191
166
|
.rorvswild-local-panel__content::-webkit-scrollbar-thumb {
|
192
|
-
background-color:
|
193
|
-
outline: 1px solid
|
167
|
+
background-color: rgb(146 149 159) !important;
|
168
|
+
outline: 1px solid rgb(146 149 159) !important;
|
194
169
|
}
|
195
170
|
|
196
171
|
/* Panel request summary */
|
197
|
-
|
198
172
|
.rorvswild-local-panel__request {
|
199
|
-
display: -webkit-box !important;
|
200
|
-
display: -ms-flexbox !important;
|
201
173
|
display: flex !important;
|
202
174
|
padding: 12px 12px 11px !important;
|
203
|
-
border-bottom: 1px solid
|
175
|
+
border-bottom: 1px solid rgb(26 29 36) !important;
|
204
176
|
cursor: pointer !important;
|
205
|
-
-ms-flex-wrap: wrap !important;
|
206
177
|
flex-wrap: wrap !important;
|
207
178
|
}
|
208
179
|
|
209
|
-
.rorvswild-local-panel__request:hover { background:
|
180
|
+
.rorvswild-local-panel__request:hover { background: rgb(26 29 36) !important; }
|
210
181
|
|
211
182
|
.rorvswild-local-panel__request__name {
|
212
183
|
word-break: break-all !important;
|
213
184
|
overflow-wrap: break-word !important;
|
214
185
|
width: 100% !important;
|
186
|
+
color: rgb(199 203 214) !important;
|
187
|
+
font-weight: 700;
|
215
188
|
}
|
216
189
|
|
217
190
|
.rorvswild-local-panel__request__path {
|
218
|
-
color:
|
191
|
+
color: rgb(146 149 159) !important;
|
192
|
+
font-weight: 400;
|
219
193
|
display: block !important;
|
220
194
|
}
|
221
195
|
|
222
196
|
.rorvswild-local-panel__request__started-at {
|
223
|
-
color:
|
197
|
+
color: rgb(146 149 159) !important;
|
224
198
|
margin-left: 12px !important;
|
225
199
|
}
|
226
|
-
.rorvswild-local-panel__request__runtime { color: #80abe3 !important; }
|
227
200
|
|
228
|
-
|
201
|
+
.rorvswild-local-panel__request__runtime {
|
202
|
+
color: rgb(182 202 255) !important;
|
203
|
+
font-weight: 700 !important;
|
204
|
+
}
|
229
205
|
|
206
|
+
/* Panel request details */
|
230
207
|
.rorvswild-local-panel__back-button {
|
231
208
|
margin: 24px 12px 18px !important;
|
232
209
|
cursor: pointer !important;
|
@@ -234,12 +211,9 @@
|
|
234
211
|
}
|
235
212
|
|
236
213
|
.rorvswild-local-panel__request-details__request {
|
237
|
-
display: -webkit-box !important;
|
238
|
-
display: -ms-flexbox !important;
|
239
214
|
display: flex !important;
|
240
215
|
margin-bottom: 48px !important;
|
241
216
|
padding: 12px 12px 0 !important;
|
242
|
-
-ms-flex-wrap: wrap !important;
|
243
217
|
flex-wrap: wrap !important;
|
244
218
|
}
|
245
219
|
|
@@ -254,26 +228,21 @@ h2.rorvswild-local-panel__request__name__title {
|
|
254
228
|
}
|
255
229
|
|
256
230
|
/* details sections */
|
257
|
-
|
258
231
|
.rorvswild-local-panel__request-details__section {
|
259
232
|
padding: 12px 12px 11px !important;
|
260
|
-
border-bottom: 1px solid
|
233
|
+
border-bottom: 1px solid rgb(26 29 36) !important;
|
261
234
|
display: block !important;
|
262
235
|
}
|
263
236
|
|
264
237
|
.rorvswild-local-panel__request-details__section:hover {
|
265
|
-
background:
|
266
|
-
-webkit-transition: all .3s !important;
|
238
|
+
background: rgb(26 29 36) !important;
|
267
239
|
transition: all .3s !important;
|
268
240
|
}
|
269
241
|
|
270
242
|
.rorvswild-local-panel__request-details__section__main {
|
271
|
-
display: -webkit-box !important;
|
272
|
-
display: -ms-flexbox !important;
|
273
243
|
display: flex !important;
|
274
244
|
width: 100% !important;
|
275
|
-
|
276
|
-
flex-wrap: wrap !important;
|
245
|
+
flex-wrap: wrap !important;
|
277
246
|
}
|
278
247
|
|
279
248
|
.rorvswild-local-panel__request-details__section__file {
|
@@ -281,33 +250,62 @@ h2.rorvswild-local-panel__request__name__title {
|
|
281
250
|
word-break: break-all !important;
|
282
251
|
overflow-wrap: break-word !important;
|
283
252
|
min-width: 0 !important;
|
253
|
+
color: rgb(199 203 214) !important;
|
254
|
+
}
|
255
|
+
|
256
|
+
a.rorvswild-local-panel__request-details__section__file__name {
|
257
|
+
text-decoration-color: rgb(146 149 159);
|
258
|
+
font-weight: 700;
|
259
|
+
}
|
260
|
+
|
261
|
+
a.rorvswild-local-panel__request-details__section__file__name:hover {
|
262
|
+
text-decoration-color: rgb(199 203 214);
|
263
|
+
}
|
264
|
+
|
265
|
+
a.rorvswild-local-panel__request-details__section__file__name::after {
|
266
|
+
content: '↗';
|
267
|
+
text-decoration: none;
|
268
|
+
display: inline-block;
|
269
|
+
margin-left: 4px;
|
270
|
+
opacity: 0.5;
|
271
|
+
}
|
272
|
+
|
273
|
+
a.rorvswild-local-panel__request-details__section__file__name:hover::after { opacity: 1; }
|
274
|
+
|
275
|
+
.rorvswild-local-panel__request-details__section__file__name span {
|
276
|
+
background: rgb(38 41 49);
|
277
|
+
text-decoration: none;
|
278
|
+
display: inline-block;
|
284
279
|
}
|
285
280
|
|
286
281
|
.rorvswild-local-panel__request-details__section__average {
|
287
|
-
color:
|
282
|
+
color: rgb(182 202 255) !important;
|
283
|
+
font-weight: 700 !important;
|
288
284
|
width: 48px !important;
|
289
285
|
margin:0 12px 0 0 !important;
|
290
286
|
}
|
291
287
|
|
292
288
|
.rorvswild-local-panel__request-details__section__calls {
|
293
|
-
color:
|
289
|
+
color: rgb(199 203 214) !important;
|
294
290
|
width: 48px !important;
|
295
291
|
margin: 0 12px 0 0 !important;
|
296
292
|
}
|
297
293
|
|
298
294
|
.rorvswild-local-panel__request-details__section__impact {
|
295
|
+
color: rgb(199 203 214) !important;
|
299
296
|
width: 48px !important;
|
297
|
+
font-weight: 700 !important;
|
300
298
|
margin: 0 12px 0 0 !important;
|
301
299
|
}
|
302
300
|
|
303
301
|
.rorvswild-local-panel__request-details__section__code {
|
304
|
-
display: -webkit-box !important;
|
305
|
-
display: -ms-flexbox !important;
|
306
302
|
display: flex !important;
|
303
|
+
color: rgb(146 149 159) !important;
|
304
|
+
margin-top: 8px !important;
|
307
305
|
}
|
308
306
|
|
309
307
|
.rorvswild-local-panel__request-details__section__kind {
|
310
|
-
background:
|
308
|
+
background: rgb(38 41 49) !important;
|
311
309
|
font-size: 10px !important;
|
312
310
|
text-transform: uppercase !important;
|
313
311
|
text-align: center !important;
|
@@ -318,9 +316,7 @@ h2.rorvswild-local-panel__request__name__title {
|
|
318
316
|
}
|
319
317
|
|
320
318
|
.rorvswild-local-panel__request-details__section__command {
|
321
|
-
color:
|
322
|
-
-webkit-box-flex: 1 !important;
|
323
|
-
-ms-flex: 1 !important;
|
319
|
+
color: rgb(146 149 159) !important;
|
324
320
|
flex: 1 !important;
|
325
321
|
margin-left: 12px !important;
|
326
322
|
opacity: 1;
|
@@ -328,55 +324,32 @@ h2.rorvswild-local-panel__request__name__title {
|
|
328
324
|
}
|
329
325
|
|
330
326
|
/* Panel Footer */
|
331
|
-
|
332
327
|
.rorvswild-local-panel__footer {
|
333
328
|
width: 100% !important;
|
334
|
-
background:
|
335
|
-
color:
|
329
|
+
background: rgb(38 41 49) !important;
|
330
|
+
color: rgb(182 202 255) !important;
|
336
331
|
padding: 12px !important;
|
337
332
|
text-align: center !important;
|
338
333
|
}
|
339
334
|
|
340
335
|
a.rorvswild-local-panel__footer__link {
|
341
|
-
color:
|
336
|
+
color: rgb(199 203 214) !important;
|
342
337
|
text-decoration: underline !important;
|
343
338
|
line-height: inherit !important;
|
344
339
|
}
|
345
340
|
|
346
|
-
/* MEDIA QUERIES */
|
347
|
-
|
348
341
|
@media screen and (min-width: 720px) {
|
349
|
-
.rorvswild-local-panel__request-details__section__main {
|
350
|
-
-ms-flex-wrap: nowrap !important;
|
351
|
-
flex-wrap: nowrap !important;
|
352
|
-
}
|
342
|
+
.rorvswild-local-panel__request-details__section__main { flex-wrap: nowrap !important; }
|
353
343
|
|
354
|
-
.rorvswild-local-panel__request__name
|
355
|
-
|
356
|
-
-ms-flex: 1 !important;
|
357
|
-
flex: 1 !important;
|
358
|
-
}
|
344
|
+
.rorvswild-local-panel__request__name,
|
345
|
+
.rorvswild-local-panel__request-details__section__file { flex: 1 !important; }
|
359
346
|
|
360
347
|
.rorvswild-local-panel__request__runtime { margin-left: 12px !important; }
|
361
348
|
|
362
|
-
.rorvswild-local-panel__request-
|
363
|
-
|
364
|
-
-ms-flex: 1 !important;
|
365
|
-
flex: 1 !important;
|
366
|
-
}
|
367
|
-
|
368
|
-
.rorvswild-local-panel__request-details__section__average {
|
369
|
-
text-align: right !important;
|
370
|
-
margin: 0 0 0 12px !important;
|
371
|
-
}
|
372
|
-
|
373
|
-
.rorvswild-local-panel__request-details__section__calls {
|
374
|
-
text-align: right !important;
|
375
|
-
margin: 0 0 0 12px !important;
|
376
|
-
}
|
377
|
-
|
349
|
+
.rorvswild-local-panel__request-details__section__average,
|
350
|
+
.rorvswild-local-panel__request-details__section__calls,
|
378
351
|
.rorvswild-local-panel__request-details__section__impact {
|
379
352
|
text-align: right !important;
|
380
353
|
margin: 0 0 0 12px !important;
|
381
354
|
}
|
382
|
-
}
|
355
|
+
}
|
@@ -7,15 +7,16 @@ http://prismjs.com/download.html?themes=prism-twilight&languages=markup+css+clik
|
|
7
7
|
*/
|
8
8
|
.rorvswild-local-panel code[class*="language-"],
|
9
9
|
.rorvswild-local-panel pre[class*="language-"] {
|
10
|
-
color:
|
10
|
+
color: rgb(199 203 214) !important;
|
11
11
|
background: none !important;
|
12
12
|
font-family: SF Mono, Menlo, Consolas, DejaVu Sans Mono, monospace !important;
|
13
13
|
text-align: left !important;
|
14
14
|
text-shadow: 0 0 0 !important;
|
15
15
|
word-spacing: normal !important;
|
16
16
|
|
17
|
-
font-size:
|
17
|
+
font-size: 14px !important;
|
18
18
|
line-height: 24px !important;
|
19
|
+
font-weight: 300 !important;
|
19
20
|
|
20
21
|
white-space: pre-line !important;
|
21
22
|
word-wrap: break-word !important;
|
@@ -60,7 +61,7 @@ http://prismjs.com/download.html?themes=prism-twilight&languages=markup+css+clik
|
|
60
61
|
.rorvswild-local-panel .token.prolog,
|
61
62
|
.rorvswild-local-panel .token.doctype,
|
62
63
|
.rorvswild-local-panel .token.cdata {
|
63
|
-
color:
|
64
|
+
color: rgb(146 149 159) !important;
|
64
65
|
font-style: italic !important;
|
65
66
|
opacity: 0.7 !important;
|
66
67
|
}
|
@@ -77,7 +78,7 @@ http://prismjs.com/download.html?themes=prism-twilight&languages=markup+css+clik
|
|
77
78
|
.rorvswild-local-panel .token.boolean,
|
78
79
|
.rorvswild-local-panel .token.number,
|
79
80
|
.rorvswild-local-panel .token.deleted {
|
80
|
-
color:
|
81
|
+
color: rgb(255 185 173) !important;
|
81
82
|
}
|
82
83
|
|
83
84
|
.rorvswild-local-panel .token.property,
|
@@ -85,7 +86,7 @@ http://prismjs.com/download.html?themes=prism-twilight&languages=markup+css+clik
|
|
85
86
|
.rorvswild-local-panel .token.symbol,
|
86
87
|
.rorvswild-local-panel .token.builtin,
|
87
88
|
.rorvswild-local-panel .token.string {
|
88
|
-
color:
|
89
|
+
color: rgb(182 202 255) !important;
|
89
90
|
}
|
90
91
|
|
91
92
|
.rorvswild-local-panel .token.attr-name,
|
@@ -98,17 +99,17 @@ http://prismjs.com/download.html?themes=prism-twilight&languages=markup+css+clik
|
|
98
99
|
.rorvswild-local-panel .token.atrule,
|
99
100
|
.rorvswild-local-panel .token.attr-value,
|
100
101
|
.rorvswild-local-panel .token.keyword {
|
101
|
-
color:
|
102
|
+
color: rgb(248 185 227) !important;
|
102
103
|
}
|
103
104
|
|
104
105
|
.rorvswild-local-panel .token.constant,
|
105
106
|
.rorvswild-local-panel .token.regex,
|
106
107
|
.rorvswild-local-panel .token.important {
|
107
|
-
color:
|
108
|
+
color: rgb(227 201 134) !important;
|
108
109
|
}
|
109
110
|
|
110
111
|
.rorvswild-local-panel .token.function {
|
111
|
-
color:
|
112
|
+
color: rgb(124 218 210) !important;
|
112
113
|
}
|
113
114
|
|
114
115
|
.rorvswild-local-panel .token.important,
|
@@ -132,5 +133,5 @@ http://prismjs.com/download.html?themes=prism-twilight&languages=markup+css+clik
|
|
132
133
|
.rorvswild-local-panel .language-markup .token.tag,
|
133
134
|
.rorvswild-local-panel .language-markup .token.attr-name,
|
134
135
|
.rorvswild-local-panel .language-markup .token.punctuation {
|
135
|
-
color:
|
136
|
+
color: rgb(146 149 159) !important;
|
136
137
|
}
|
@@ -16,6 +16,8 @@ module RorVsWild
|
|
16
16
|
section.file, section.line = job.method(:perform).source_location
|
17
17
|
section.file = RorVsWild.agent.locator.relative_path(section.file)
|
18
18
|
block.call
|
19
|
+
rescue Exception => ex
|
20
|
+
job.rescue_with_handler(ex) or raise
|
19
21
|
ensure
|
20
22
|
RorVsWild::Section.stop
|
21
23
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RorVsWild
|
2
4
|
module Plugin
|
3
5
|
class ActiveRecord
|
@@ -19,8 +21,8 @@ module RorVsWild
|
|
19
21
|
return if IGNORED_QUERIES.include?(payload[:name])
|
20
22
|
RorVsWild::Section.start do |section|
|
21
23
|
section.appendable_command = APPENDABLE_QUERIES.include?(payload[:sql])
|
22
|
-
section.command = payload[:sql]
|
23
|
-
section.kind = "sql"
|
24
|
+
section.command = normalize_sql_query(payload[:sql])
|
25
|
+
section.kind = "sql"
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
@@ -28,6 +30,24 @@ module RorVsWild
|
|
28
30
|
return if IGNORED_QUERIES.include?(payload[:name])
|
29
31
|
RorVsWild::Section.stop
|
30
32
|
end
|
33
|
+
|
34
|
+
SQL_STRING_REGEX = /'((?:''|\\'|[^'])*)'/
|
35
|
+
SQL_NUMERIC_REGEX = /(?<!\w)\d+(\.\d+)?(?!\w)/
|
36
|
+
SQL_PARAMETER_REGEX = /\$\d+/
|
37
|
+
SQL_IN_REGEX = /(\bIN\s*\()([^)]+)(\))/i
|
38
|
+
SQL_ONE_LINE_COMMENT_REGEX =/--.*$/
|
39
|
+
SQL_MULTI_LINE_COMMENT_REGEX = /\/\*.*?\*\//m
|
40
|
+
|
41
|
+
def normalize_sql_query(sql)
|
42
|
+
sql = sql.to_s.gsub(SQL_STRING_REGEX, "?")
|
43
|
+
sql.gsub!(SQL_PARAMETER_REGEX, "?")
|
44
|
+
sql.gsub!(SQL_NUMERIC_REGEX, "?")
|
45
|
+
sql.gsub!(SQL_IN_REGEX, '\1?\3')
|
46
|
+
sql.gsub!(SQL_ONE_LINE_COMMENT_REGEX, "")
|
47
|
+
sql.gsub!(SQL_MULTI_LINE_COMMENT_REGEX, "")
|
48
|
+
sql.strip!
|
49
|
+
sql
|
50
|
+
end
|
31
51
|
end
|
32
52
|
end
|
33
53
|
end
|
data/lib/rorvswild/queue.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RorVsWild
|
2
4
|
class Queue
|
3
5
|
SLEEP_TIME = 10
|
@@ -56,6 +58,7 @@ module RorVsWild
|
|
56
58
|
end
|
57
59
|
|
58
60
|
def flush_indefinetely
|
61
|
+
client.post("/deployments", deployment: Deployment.to_h)
|
59
62
|
sleep(SLEEP_TIME) and flush while true
|
60
63
|
rescue Exception => ex
|
61
64
|
RorVsWild.logger.error(ex)
|
data/lib/rorvswild/section.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RorVsWild
|
2
4
|
class Section
|
3
5
|
attr_reader :started_at
|
@@ -30,7 +32,7 @@ module RorVsWild
|
|
30
32
|
@calls = 1
|
31
33
|
@total_runtime = 0
|
32
34
|
@children_runtime = 0
|
33
|
-
@kind = "code"
|
35
|
+
@kind = "code"
|
34
36
|
@started_at = RorVsWild.clock_milliseconds
|
35
37
|
location = RorVsWild.agent.locator.find_most_relevant_location(caller_locations)
|
36
38
|
@file = RorVsWild.agent.locator.relative_path(location.path)
|
@@ -61,7 +63,7 @@ module RorVsWild
|
|
61
63
|
total_runtime - children_runtime
|
62
64
|
end
|
63
65
|
|
64
|
-
COMMAND_MAX_SIZE =
|
66
|
+
COMMAND_MAX_SIZE = 5_000
|
65
67
|
|
66
68
|
def command=(value)
|
67
69
|
@command = value && value.size > COMMAND_MAX_SIZE ? value[0, COMMAND_MAX_SIZE] + " [TRUNCATED]" : value
|
data/lib/rorvswild/version.rb
CHANGED
data/lib/rorvswild.rb
CHANGED
@@ -68,6 +68,7 @@ module RorVsWild
|
|
68
68
|
|
69
69
|
def self.check
|
70
70
|
api_key = RorVsWild.agent.config[:api_key]
|
71
|
+
agent.client.instance_variable_set(:@http_unauthorized, false)
|
71
72
|
return puts "You API key is missing and has to be defined in config/rorvswild.yml." if !api_key || api_key.empty?
|
72
73
|
puts case response = agent.client.post("/jobs", jobs: [{sections: [], name: "RorVsWild.check", runtime: 0}])
|
73
74
|
when Net::HTTPOK then "Connection to RorVsWild works fine !"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rorvswild
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexis Bernard
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-01-12 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Performances and errors insights for rails developers.
|
15
15
|
email:
|