rorvswild 1.2.0 → 1.3.0

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
  SHA1:
3
- metadata.gz: dbddf42d7a3d87901206dcdb0872b689c733b100
4
- data.tar.gz: 51c9aeebb5d2ec07863465db44f2253990421336
3
+ metadata.gz: 539fb2b080805724e336dc4d11c5321c4dccde4e
4
+ data.tar.gz: 7564c5063da3e4e140a1ead81da5273379966207
5
5
  SHA512:
6
- metadata.gz: 1b109fabeb568743f2d306c8295bdb4201fa01773fb0940c9c2c8ebe1679426fe91969d56fa3c6c02217ef91e9f4241b23eac881a68ef276f6354b86c4eb69f4
7
- data.tar.gz: e20ff2a1eae18fbaa31e4631f7a6093ce7b97be390ddc0acea6a6e6483820a1cefe7737572a439c90442d8299c79a119998c9ba33fee635f90d4c3194fadc8d4
6
+ metadata.gz: 9cc49fe8204ad12061a1c9995f81ad6d96b0352e5789abd3d762755d1caeb12ff10ee11442c13bef624bebfcf6d49be62838911e8ab4577a820460865850781d
7
+ data.tar.gz: d58eb06d7bd4004b9ee7964f07f98a1e512fe9a99cc315afff18f200708d4a04b81f2bf4645740940d7b98f247a08889e675e275168d695fbe78ade449d4c2ef
data/README.md CHANGED
@@ -1,17 +1,40 @@
1
+
1
2
  # RorVsWild
2
3
 
3
- Ruby on Rails app monitoring: performances & quality insights for rails developers.
4
+ <img align="right" src="/images/rorvswild_logo.jpg">
5
+
6
+ *RoRvsWild* is a free ruby gem to monitor performances and quality in Ruby on Rails applications.
7
+
8
+ This gem has a double mode, development and production.
9
+ It can be used without an account to monitor your requests performances in your development environment.
10
+ 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, errors monitoring and notifications.
11
+
4
12
 
5
13
  ## Installation
6
14
 
7
- First you need an API key. Signup here https://www.rorvswild.com to get one and a 14 day free trial.
15
+ #### Install the gem
16
+
17
+ * Add in your Gemfile `gem "rorvswild"`
18
+ * Run `bundle install` in you terminal
19
+ * Restart your local server and you’ll see a small button in the bottom left corner of your page.
20
+
21
+ ![RoRvsWild Local Button](/images/rorvswild_local_button.jpg)
8
22
 
9
- 1. Add in your Gemfile `gem "rorvswild"`
10
- 2. Run `bundle install`
11
- 3. Run `rorvswild-setup API_KEY`
12
- 4. Restart / deploy your app !
23
+ This is all what you need to do to monitor your local environment requests.
24
+
25
+ #### API key
26
+
27
+ **To monitor your production or staging environment, you need an API key.**
28
+ Signup on https://www.rorvswild.com and create an app to get one.
29
+
30
+ * Add in your Gemfile `gem "rorvswild"`
31
+ * Run `bundle install` in you terminal
32
+ * Run `rorvswild-setup API_KEY` in you terminal
33
+ * Deploy/Restart your app
34
+ * Make a few requests and refresh your app page on rorvswild.com to view the dashboard.
35
+
36
+ The `rorvswild-setup` command creates a `config/rorvswild.yml` file.
13
37
 
14
- The `rorvswild-setup` create a `config/rorvswild.yml` file.
15
38
  For those who prefer to manually use an initializer, they can do the following.
16
39
 
17
40
  ```ruby
@@ -19,7 +42,36 @@ For those who prefer to manually use an initializer, they can do the following.
19
42
  RorVsWild.start(api_key: API_KEY)
20
43
  ```
21
44
 
22
- ## Measure any code
45
+ You can create unlimited apps on *rorvswild.com* to monitor your different environments, or use the same key for both staging and production. If you want to add a staging server you have to edit your Gemfile.
46
+
47
+ ## Development mode: *RoRvsWild Local*
48
+
49
+ ![RoRvsWild Local](/images/rorvswild_local.jpg)
50
+
51
+ *RorVsWild Local* monitors the performances of requests in development environment.
52
+ 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.
53
+
54
+ *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.
55
+
56
+ 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.
57
+ To prevent this behaviour and better match the production, turn on cache_classes in your config/environments/development.rb:
58
+
59
+ ```
60
+ Rails.application.configure do
61
+ config.cache_classes = true
62
+ end
63
+ ```
64
+
65
+ 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.
66
+
67
+ ## Production mode: *RoRvsWild.com*
68
+
69
+ ![RoRvsWild.com](/images/rorvswild_prod.jpg)
70
+
71
+ *RoRvsWild.com* makes it easy to monitor requests, background jobs and errors in your production and staging environment.
72
+ It also comes with some extra options listed below.
73
+
74
+ #### Measure any code
23
75
 
24
76
  You can measure any code like this (useful to monitor cronjobs):
25
77
 
@@ -33,12 +85,12 @@ Or like that:
33
85
  RorVsWild.measure_block("A great job name") { User.all.do_something_great }
34
86
  ```
35
87
 
36
- Then it will appears in the jobs page.
88
+ Then it will appear in the jobs page.
37
89
 
38
90
  Note that Calling `measure_code` or `measure_block` inside or a request or a job will add a section.
39
91
  That is convenient to profile finely parts of your code.
40
92
 
41
- ## Send errors manually
93
+ #### Send errors manually
42
94
 
43
95
  When you already have a begin / rescue block, this manner suits well:
44
96
 
@@ -66,9 +118,9 @@ RorVsWild.record_error(exception, {something: "important"})
66
118
  RorVsWild.catch_error(something: "important") { 1 / 0 }
67
119
  ```
68
120
 
69
- ## Ignore exceptions
121
+ #### Ignore exceptions
70
122
 
71
- By using the ignored_exceptions parameter you can prevent RorVsWild from recording specific exceptions.
123
+ By using the ignored_exceptions parameter you can prevent *RoRvsWild* from recording specific exceptions.
72
124
 
73
125
  ```yaml
74
126
  # config/rorvswild.yml
@@ -20,7 +20,7 @@ module RorVsWild
20
20
  @ignored_exceptions = config[:ignored_exceptions]
21
21
  @app_root = config[:app_root]
22
22
  @client = Client.new(config)
23
- @queue = Queue.new(client)
23
+ @queue = config[:queue] || Queue.new(client)
24
24
  cleanup_data
25
25
 
26
26
  if defined?(Rails)
@@ -0,0 +1,67 @@
1
+ var Mustache = this.Mustache
2
+ var Barber = this.Barber = {}
3
+
4
+ Barber.launch = function(root, namespace) {
5
+ var elements = (root || document).querySelectorAll("[data-barber]")
6
+ Array.prototype.forEach.call(elements, function(element) { Barber.start(element, namespace) })
7
+ }
8
+
9
+ Barber.start = function(element, namespace) {
10
+ var name = element.getAttribute("data-barber")
11
+ var func = Barber.stringToFunction(name, namespace)
12
+ if (func instanceof Function)
13
+ Barber.instanciate(func, element)
14
+ else
15
+ console.warn("View " + name + " is not a function.")
16
+ }
17
+
18
+ Barber.instanciate = function(func, element) {
19
+ try {
20
+ view = new func(element)
21
+ } catch (ex) {
22
+ console.error(ex)
23
+ }
24
+ }
25
+
26
+ Barber.stringToFunction = function(fullName, parent) {
27
+ var func = parent || window
28
+ var names = fullName.split(".")
29
+ for (var i = 0; i < names.length; i++)
30
+ if (!(func = func[names[i]]))
31
+ return null
32
+ return func
33
+ }
34
+
35
+ Barber.render = function(name, view, element) {
36
+ var partials = Barber.partials()
37
+ if (!partials[name]) {
38
+ console.error("Partial " + name + " does not exists.")
39
+ return
40
+ }
41
+ element.innerHTML = Mustache.render(partials[name], view, partials)
42
+ Barber.listenEvents(element, view)
43
+ }
44
+
45
+ Barber.partials = function() {
46
+ var elements = document.querySelectorAll('[type="x-tmpl-mustache"][data-partial]')
47
+ return Array.prototype.reduce.call(elements, function(hash, element) {
48
+ hash[element.getAttribute("data-partial")] = element.innerHTML
49
+ return hash
50
+ }, {})
51
+ }
52
+
53
+ Barber.listenEvents = function(root, view) {
54
+ root.querySelectorAll("[data-events]").forEach(function(element) {
55
+ element.getAttribute("data-events").split(" ").forEach(function(eventAndAction) {
56
+ var array = eventAndAction.split("->")
57
+ Barber.listenEvent(view, element, array[0], array[1])
58
+ })
59
+ })
60
+ }
61
+
62
+ Barber.listenEvent = function(view, element, event, action) {
63
+ if (view[action] instanceof Function)
64
+ element.addEventListener(event, view[action].bind(view))
65
+ else
66
+ console.warn("Action " + view.constructor.name + "." + action + " is not a function.")
67
+ }
@@ -0,0 +1,108 @@
1
+ var RorVsWild = this.RorVsWild = {};
2
+
3
+ RorVsWild.Local = function(container) {
4
+ this.root = container
5
+ this.embedded = !(this.active = location.pathname == "/rorvswild")
6
+ this.data = JSON.parse((this.container = container).getAttribute("data-json"))
7
+ this.requests = this.data.map(function(data) { return new RorVsWild.Local.Request(data) })
8
+ this.render()
9
+ }
10
+
11
+ RorVsWild.Local.prototype.render = function() {
12
+ Barber.render("RorVsWild.Local", this, this.root)
13
+ Prism.highlightAllUnder(this.root)
14
+ }
15
+
16
+ RorVsWild.Local.prototype.lastRuntime = function() {
17
+ return this.requests[0] ? this.requests[0].runtime() : "N/A"
18
+ }
19
+
20
+ RorVsWild.Local.prototype.toggle = function() {
21
+ this.active ? this.collapse() : this.expand()
22
+ }
23
+
24
+ RorVsWild.Local.prototype.expand = function() {
25
+ this.currentRequest = this.requests[0]
26
+ this.active = true
27
+ this.render()
28
+ }
29
+
30
+ RorVsWild.Local.prototype.collapse = function() {
31
+ this.active = false
32
+ this.render()
33
+ }
34
+
35
+ RorVsWild.Local.formatRuntime = function(runtime) {
36
+ return runtime > 0 && runtime < 1 ? "<1" : Math.round(runtime)
37
+ }
38
+
39
+ RorVsWild.Local.formatImpact = function(impact) {
40
+ return impact > 0 && impact < 1 ? "<1" : Math.round(impact)
41
+ }
42
+
43
+ RorVsWild.Local.formatDateTime = function(date) {
44
+ var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
45
+ var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()
46
+ var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours()
47
+ return [date.getDate(), months[date.getMonth()], hours + ":" + minutes].join(" ")
48
+ }
49
+
50
+ RorVsWild.Local.prototype.goToRequestDetails = function(event) {
51
+ var id = parseInt(event.currentTarget.getAttribute("data-request-id"))
52
+ this.currentRequest = this.requests.find(function(req) { return req.id == id })
53
+ this.render()
54
+ }
55
+
56
+ RorVsWild.Local.prototype.goToHistory = function(event) {
57
+ this.currentRequest = null
58
+ this.render()
59
+ }
60
+
61
+ RorVsWild.Local.prototype.containerStyle = function() {
62
+ if (!this.active)
63
+ return 'display: none !important;'
64
+ }
65
+
66
+ RorVsWild.Local.kindToLanguage = function(kind) {
67
+ switch (kind) {
68
+ case "sql": return "language-sql"
69
+ case "mongo": return "language-javascript"
70
+ case "elasticsearch": return "language-json"
71
+ default: return "language-none"
72
+ }
73
+ }
74
+
75
+ RorVsWild.Local.lastId = 0
76
+
77
+ RorVsWild.Local.nextId = function() {
78
+ return RorVsWild.Local.lastId += 1
79
+ }
80
+
81
+ RorVsWild.Local.Request = function(data) {
82
+ this.id = RorVsWild.Local.nextId()
83
+ this.data = data
84
+ this.name = data.name
85
+ this.path = data.path
86
+ this.startedAt = RorVsWild.Local.formatDateTime(new Date(data.started_at))
87
+ }
88
+
89
+ RorVsWild.Local.Request.prototype.runtime = function() {
90
+ return RorVsWild.Local.formatRuntime(this.data.runtime)
91
+ }
92
+
93
+ RorVsWild.Local.Request.prototype.sections = function() {
94
+ return this.data.sections.map(function(section) {
95
+ var runtime = (section.total_runtime - section.children_runtime)
96
+ return {
97
+ impact: RorVsWild.Local.formatImpact(runtime * 100 / this.data.runtime),
98
+ averageRuntime: RorVsWild.Local.formatRuntime(runtime / section.calls),
99
+ command: section.kind != "view" ? section.command : null,
100
+ calls: section.calls,
101
+ kind: section.kind.substring(0, 7),
102
+ file: section.file,
103
+ line: section.line,
104
+ runtime: runtime,
105
+ language: RorVsWild.Local.kindToLanguage(section.kind),
106
+ }
107
+ }.bind(this)).sort(function(a, b) { return b.runtime - a.runtime })
108
+ }