x-ray-machine 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +132 -0
- data/Guardfile +8 -0
- data/README.md +100 -0
- data/bin/bundler +16 -0
- data/bin/coderay +16 -0
- data/bin/erubis +16 -0
- data/bin/guard +16 -0
- data/bin/htmldiff +16 -0
- data/bin/ldiff +16 -0
- data/bin/listen +16 -0
- data/bin/pry +16 -0
- data/bin/rackup +16 -0
- data/bin/rails +16 -0
- data/bin/rake +16 -0
- data/bin/rspec +16 -0
- data/bin/sprockets +16 -0
- data/bin/thor +16 -0
- data/bin/tilt +16 -0
- data/lib/x-ray-machine.rb +2 -0
- data/lib/x_ray_machine.rb +12 -0
- data/lib/x_ray_machine/config.rb +79 -0
- data/lib/x_ray_machine/log_subscriber.rb +23 -0
- data/lib/x_ray_machine/railtie.rb +13 -0
- data/lib/x_ray_machine/summary.rb +41 -0
- data/lib/x_ray_machine/version.rb +3 -0
- data/lib/x_ray_machine/x_ray.rb +25 -0
- data/spec/lib/x_ray_machine/config_spec.rb +55 -0
- data/spec/lib/x_ray_machine/log_subscriber_spec.rb +48 -0
- data/spec/lib/x_ray_machine/summary_spec.rb +55 -0
- data/spec/lib/x_ray_machine/x_ray_spec.rb +44 -0
- data/spec/spec_helper.rb +10 -0
- data/x-ray-machine.gemspec +23 -0
- data/x-ray.jpg +0 -0
- metadata +162 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0a96ac18783ffbb5d0c77256f0cdb11e3cf7c2ce
|
4
|
+
data.tar.gz: a8b664e63e6450c3f0cb3012c397a9d65af50802
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3dec83fd88b356ae3fe723dd451537fdd483d2555dd3f63d888af90e476bd6adaa1c4c4aa1d25e5da3490313a4c1c53bafa6369756b5d6ec2d1731d5fd9522a5
|
7
|
+
data.tar.gz: 4542b55289dcaa18d99aadca5f3ba18475b0bc8a663ede503bb02baa2d4297dc093bf2134f66fdf656775a80851aa010897749c0bfda6f7b1bdea33a8aa03799
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
-c -f p -r spec_helper
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
x-ray-machine (0.0.0)
|
5
|
+
rails (~> 4.0, >= 4.0.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
actionmailer (4.1.8)
|
11
|
+
actionpack (= 4.1.8)
|
12
|
+
actionview (= 4.1.8)
|
13
|
+
mail (~> 2.5, >= 2.5.4)
|
14
|
+
actionpack (4.1.8)
|
15
|
+
actionview (= 4.1.8)
|
16
|
+
activesupport (= 4.1.8)
|
17
|
+
rack (~> 1.5.2)
|
18
|
+
rack-test (~> 0.6.2)
|
19
|
+
actionview (4.1.8)
|
20
|
+
activesupport (= 4.1.8)
|
21
|
+
builder (~> 3.1)
|
22
|
+
erubis (~> 2.7.0)
|
23
|
+
activemodel (4.1.8)
|
24
|
+
activesupport (= 4.1.8)
|
25
|
+
builder (~> 3.1)
|
26
|
+
activerecord (4.1.8)
|
27
|
+
activemodel (= 4.1.8)
|
28
|
+
activesupport (= 4.1.8)
|
29
|
+
arel (~> 5.0.0)
|
30
|
+
activesupport (4.1.8)
|
31
|
+
i18n (~> 0.6, >= 0.6.9)
|
32
|
+
json (~> 1.7, >= 1.7.7)
|
33
|
+
minitest (~> 5.1)
|
34
|
+
thread_safe (~> 0.1)
|
35
|
+
tzinfo (~> 1.1)
|
36
|
+
arel (5.0.1.20140414130214)
|
37
|
+
builder (3.2.2)
|
38
|
+
celluloid (0.16.0)
|
39
|
+
timers (~> 4.0.0)
|
40
|
+
coderay (1.1.0)
|
41
|
+
diff-lcs (1.2.5)
|
42
|
+
erubis (2.7.0)
|
43
|
+
ffi (1.9.6)
|
44
|
+
formatador (0.2.5)
|
45
|
+
guard (2.10.1)
|
46
|
+
formatador (>= 0.2.4)
|
47
|
+
listen (~> 2.7)
|
48
|
+
lumberjack (~> 1.0)
|
49
|
+
pry (>= 0.9.12)
|
50
|
+
thor (>= 0.18.1)
|
51
|
+
guard-rspec (4.3.1)
|
52
|
+
guard (~> 2.1)
|
53
|
+
rspec (>= 2.14, < 4.0)
|
54
|
+
hike (1.2.3)
|
55
|
+
hitimes (1.2.2)
|
56
|
+
i18n (0.6.11)
|
57
|
+
json (1.8.1)
|
58
|
+
listen (2.8.3)
|
59
|
+
celluloid (>= 0.15.2)
|
60
|
+
rb-fsevent (>= 0.9.3)
|
61
|
+
rb-inotify (>= 0.9)
|
62
|
+
lumberjack (1.0.9)
|
63
|
+
mail (2.6.3)
|
64
|
+
mime-types (>= 1.16, < 3)
|
65
|
+
method_source (0.8.2)
|
66
|
+
mime-types (2.4.3)
|
67
|
+
minitest (5.4.3)
|
68
|
+
multi_json (1.10.1)
|
69
|
+
pry (0.10.1)
|
70
|
+
coderay (~> 1.1.0)
|
71
|
+
method_source (~> 0.8.1)
|
72
|
+
slop (~> 3.4)
|
73
|
+
rack (1.5.2)
|
74
|
+
rack-test (0.6.2)
|
75
|
+
rack (>= 1.0)
|
76
|
+
rails (4.1.8)
|
77
|
+
actionmailer (= 4.1.8)
|
78
|
+
actionpack (= 4.1.8)
|
79
|
+
actionview (= 4.1.8)
|
80
|
+
activemodel (= 4.1.8)
|
81
|
+
activerecord (= 4.1.8)
|
82
|
+
activesupport (= 4.1.8)
|
83
|
+
bundler (>= 1.3.0, < 2.0)
|
84
|
+
railties (= 4.1.8)
|
85
|
+
sprockets-rails (~> 2.0)
|
86
|
+
railties (4.1.8)
|
87
|
+
actionpack (= 4.1.8)
|
88
|
+
activesupport (= 4.1.8)
|
89
|
+
rake (>= 0.8.7)
|
90
|
+
thor (>= 0.18.1, < 2.0)
|
91
|
+
rake (10.3.2)
|
92
|
+
rb-fsevent (0.9.4)
|
93
|
+
rb-inotify (0.9.5)
|
94
|
+
ffi (>= 0.5.0)
|
95
|
+
rspec (3.1.0)
|
96
|
+
rspec-core (~> 3.1.0)
|
97
|
+
rspec-expectations (~> 3.1.0)
|
98
|
+
rspec-mocks (~> 3.1.0)
|
99
|
+
rspec-core (3.1.7)
|
100
|
+
rspec-support (~> 3.1.0)
|
101
|
+
rspec-expectations (3.1.2)
|
102
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
103
|
+
rspec-support (~> 3.1.0)
|
104
|
+
rspec-mocks (3.1.3)
|
105
|
+
rspec-support (~> 3.1.0)
|
106
|
+
rspec-support (3.1.2)
|
107
|
+
slop (3.6.0)
|
108
|
+
sprockets (2.11.3)
|
109
|
+
hike (~> 1.2)
|
110
|
+
multi_json (~> 1.0)
|
111
|
+
rack (~> 1.0)
|
112
|
+
tilt (~> 1.1, != 1.3.0)
|
113
|
+
sprockets-rails (2.2.0)
|
114
|
+
actionpack (>= 3.0)
|
115
|
+
activesupport (>= 3.0)
|
116
|
+
sprockets (>= 2.8, < 4.0)
|
117
|
+
thor (0.19.1)
|
118
|
+
thread_safe (0.3.4)
|
119
|
+
tilt (1.4.1)
|
120
|
+
timers (4.0.1)
|
121
|
+
hitimes
|
122
|
+
tzinfo (1.2.2)
|
123
|
+
thread_safe (~> 0.1)
|
124
|
+
|
125
|
+
PLATFORMS
|
126
|
+
ruby
|
127
|
+
|
128
|
+
DEPENDENCIES
|
129
|
+
bundler (~> 1.7)
|
130
|
+
guard-rspec (~> 4.3)
|
131
|
+
rspec (~> 3.1)
|
132
|
+
x-ray-machine!
|
data/Guardfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# X Ray Machine
|
2
|
+
|
3
|
+
![X-Ray](./x-ray.jpg)
|
4
|
+
|
5
|
+
Ever wanted to log and profile your external API calls in a Rails app the
|
6
|
+
same way Rails does with active record? Look no further, as the `x-ray-machine`
|
7
|
+
is the thing that will enable you to do that!
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
As per usual add this to your `Gemfile`
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'x-ray-machine'
|
15
|
+
```
|
16
|
+
|
17
|
+
Then just call `XRay.whatevers` with some marker you wanna see in the logs
|
18
|
+
(it can be an url or anything stringy) and then give it a block to measure.
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
class MyThing
|
22
|
+
def talk_to_elastic_search
|
23
|
+
url = figure_the_url
|
24
|
+
|
25
|
+
XRay.elastic_search url do
|
26
|
+
make_the_actual_request url
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def talk_to_twitter_api
|
31
|
+
XRay.twitter "loading recent tweets" do
|
32
|
+
load_some_tweets_for_fun_and_profit
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def craaaazy_stuff
|
37
|
+
XRay.baaacooon "fat acids hitting the brain" do
|
38
|
+
i_wonder_if_spacemen_eat_bacon
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
This will show something like this in your rails console
|
45
|
+
|
46
|
+
```log
|
47
|
+
ElasticSearch (5.1ms) /url?bla=bla&bla
|
48
|
+
Twitter (100.2ms) loading recent tweets
|
49
|
+
Baaacooon (10.1ms) fat acids hitting the brain
|
50
|
+
```
|
51
|
+
|
52
|
+
## Marking Cached Results
|
53
|
+
|
54
|
+
In case you want to mark a query as cached, you can use the `ray`
|
55
|
+
object that is passed down the block, and mark it as cached
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
url = "some/url.thing"
|
59
|
+
|
60
|
+
XRay.heavy_request url do |ray|
|
61
|
+
if result = find_in_cache(url)
|
62
|
+
ray.cached = true
|
63
|
+
else
|
64
|
+
result = make_the_actual_request(url)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
After that your log entry will look like so
|
70
|
+
|
71
|
+
```log
|
72
|
+
HeavyRequest CACHE (0.1ms) /url?bla=bla&bla
|
73
|
+
```
|
74
|
+
|
75
|
+
|
76
|
+
## Customization & Configuration
|
77
|
+
|
78
|
+
Normally, the `XRay` object will use `method_missing` and automatically
|
79
|
+
guess the name for the entry and use a random color for it, but you can
|
80
|
+
customize things
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
XRayMachine.config do |config|
|
84
|
+
config.elastic_search = {
|
85
|
+
color: :yellow, # color for the line
|
86
|
+
title: "ES", # title for the entries
|
87
|
+
show_in_summary: false # show/hide the results in the summary
|
88
|
+
}
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
__NOTE__: the name you use with the `config` should match the one
|
93
|
+
that you use on the `XRay` class to track your queries.
|
94
|
+
|
95
|
+
|
96
|
+
## Copyright & License
|
97
|
+
|
98
|
+
All code in this repository is released under the terms of the MIT License
|
99
|
+
|
100
|
+
Copyright (C) 2014 Nikolay Nemshilov
|
data/bin/bundler
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'bundler' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('bundler', 'bundler')
|
data/bin/coderay
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'coderay' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('coderay', 'coderay')
|
data/bin/erubis
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'erubis' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('erubis', 'erubis')
|
data/bin/guard
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'guard' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('guard', 'guard')
|
data/bin/htmldiff
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'htmldiff' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('diff-lcs', 'htmldiff')
|
data/bin/ldiff
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'ldiff' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('diff-lcs', 'ldiff')
|
data/bin/listen
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'listen' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('listen', 'listen')
|
data/bin/pry
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'pry' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('pry', 'pry')
|
data/bin/rackup
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rackup' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rack', 'rackup')
|
data/bin/rails
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rails' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('railties', 'rails')
|
data/bin/rake
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rake' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rake', 'rake')
|
data/bin/rspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rspec' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rspec-core', 'rspec')
|
data/bin/sprockets
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'sprockets' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('sprockets', 'sprockets')
|
data/bin/thor
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'thor' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('thor', 'thor')
|
data/bin/tilt
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'tilt' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('tilt', 'tilt')
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module XRayMachine
|
2
|
+
# x-ray all everything!
|
3
|
+
end
|
4
|
+
|
5
|
+
require_relative "./x_ray_machine/version"
|
6
|
+
require_relative "./x_ray_machine/x_ray"
|
7
|
+
require_relative "./x_ray_machine/config"
|
8
|
+
require_relative "./x_ray_machine/log_subscriber"
|
9
|
+
require_relative "./x_ray_machine/summary"
|
10
|
+
require_relative "./x_ray_machine/railtie"
|
11
|
+
|
12
|
+
XRay = XRayMachine::XRay
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module XRayMachine
|
2
|
+
|
3
|
+
def self.config(&block)
|
4
|
+
yield options
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.options
|
8
|
+
@options ||= Options.new
|
9
|
+
end
|
10
|
+
|
11
|
+
class Options
|
12
|
+
COLORS = {
|
13
|
+
red: "\e[31m",
|
14
|
+
green: "\e[32m",
|
15
|
+
yellow: "\e[33m",
|
16
|
+
blue: "\e[34m",
|
17
|
+
magenta: "\e[35m",
|
18
|
+
cyan: "\e[36m"
|
19
|
+
}
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@streams = {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def method_missing(name, config=nil)
|
26
|
+
name = name[0, name.size - 1] if name[name.size - 1] == "="
|
27
|
+
name = name.to_sym
|
28
|
+
|
29
|
+
if config
|
30
|
+
@streams[name] = fill_defaults_for(config)
|
31
|
+
else
|
32
|
+
@streams[name] ||= generate_options_for(name)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def generate_options_for(name)
|
39
|
+
fill_defaults_for title: name.to_s.gsub(/(^|_)([a-z])/) { |m| $2.upcase }
|
40
|
+
end
|
41
|
+
|
42
|
+
def fill_defaults_for(config)
|
43
|
+
{
|
44
|
+
color: available_colors[0],
|
45
|
+
show_in_summary: true
|
46
|
+
}.merge config
|
47
|
+
end
|
48
|
+
|
49
|
+
def available_colors
|
50
|
+
used_colors = @streams.map{|_,o| o[:color] }.compact
|
51
|
+
COLORS.keys - used_colors
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Config
|
56
|
+
attr_reader :title, :color, :show_in_summary
|
57
|
+
|
58
|
+
def self.for(stream)
|
59
|
+
options = XRayMachine.options.__send__ stream
|
60
|
+
title = options[:title]
|
61
|
+
color = options[:color]
|
62
|
+
show_in_summary = options[:show_in_summary]
|
63
|
+
|
64
|
+
new title, color, show_in_summary
|
65
|
+
end
|
66
|
+
|
67
|
+
def initialize(title, color, show_in_summary)
|
68
|
+
@title = title
|
69
|
+
@color = XRayMachine::Options::COLORS[color] || XRayMachine::Options::COLORS[:red]
|
70
|
+
@show_in_summary = show_in_summary
|
71
|
+
end
|
72
|
+
|
73
|
+
alias :show_in_summary? :show_in_summary
|
74
|
+
|
75
|
+
def to_h
|
76
|
+
{title: title, color: color, show_in_summary: show_in_summary}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module XRayMachine
|
2
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
3
|
+
def self.runtimes
|
4
|
+
Thread.current["x_ray_machine_runtimes"] ||= Hash.new{|k,_| 0}
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.reset_runtimes
|
8
|
+
Thread.current["x_ray_machine_runtimes"] = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def request(event)
|
12
|
+
group = event.payload[:group]
|
13
|
+
config = XRayMachine::Config.for(group)
|
14
|
+
|
15
|
+
self.class.runtimes[group] += event.duration
|
16
|
+
|
17
|
+
name = config.title
|
18
|
+
name += " CACHE" if event.payload[:cache]
|
19
|
+
name = '%s (%.1fms)' % [name, event.duration]
|
20
|
+
debug " #{color(name, config.color, true)} #{event.payload[:query]}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module XRayMachine
|
2
|
+
class Railtie < Rails::Railtie
|
3
|
+
railtie_name :x_ray_machine
|
4
|
+
|
5
|
+
config.before_initialize do |app|
|
6
|
+
XRayMachine::LogSubscriber.attach_to :xraymachine
|
7
|
+
|
8
|
+
ActiveSupport.on_load(:action_controller) do
|
9
|
+
include XRayMachine::Summary::Runtime
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module XRayMachine
|
2
|
+
class Summary
|
3
|
+
def self.add(payload)
|
4
|
+
payload_sum = XRayMachine::LogSubscriber.runtimes.map{|k,v| v}.inject(0){|a,b| a+b}
|
5
|
+
|
6
|
+
# most of the times things are lazyloaded
|
7
|
+
if payload[:view_runtime] && payload[:view_runtime] > payload_sum
|
8
|
+
payload[:view_runtime] -= payload_sum
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.messages
|
13
|
+
XRayMachine::LogSubscriber.runtimes.map do |stream_name, duration|
|
14
|
+
stream = XRayMachine::Config.for(stream_name)
|
15
|
+
if stream.show_in_summary?
|
16
|
+
"%s: %.1fms" % [stream.title, duration]
|
17
|
+
end
|
18
|
+
end.compact
|
19
|
+
end
|
20
|
+
|
21
|
+
module Runtime
|
22
|
+
extend ActiveSupport::Concern
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def append_info_to_payload(payload)
|
27
|
+
super.tap do
|
28
|
+
XRayMachine::Summary.add(payload)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module ClassMethods
|
33
|
+
def log_process_action(payload)
|
34
|
+
super.tap do |messages|
|
35
|
+
messages += XRayMachine::Summary.messages
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module XRayMachine
|
2
|
+
class XRay
|
3
|
+
def cached
|
4
|
+
@cached || false
|
5
|
+
end
|
6
|
+
|
7
|
+
def cached=(val)
|
8
|
+
@cached = val
|
9
|
+
end
|
10
|
+
|
11
|
+
alias :cached? :cached
|
12
|
+
|
13
|
+
def self.method_missing(name, query, &block)
|
14
|
+
options = {group: name, query: query, cache: false}
|
15
|
+
|
16
|
+
ActiveSupport::Notifications.instrument "request.xraymachine", options do
|
17
|
+
ray = XRayMachine::XRay.new
|
18
|
+
|
19
|
+
block.call(ray).tap do |result|
|
20
|
+
options[:cache] = true if ray.cached?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe XRayMachine::Config do
|
4
|
+
|
5
|
+
before { XRayMachine.instance_eval{ @options = nil } }
|
6
|
+
|
7
|
+
describe ".config" do
|
8
|
+
|
9
|
+
it "allows to config things" do
|
10
|
+
XRayMachine.config do |config|
|
11
|
+
config.thing = {title: "Thingy"}
|
12
|
+
end
|
13
|
+
|
14
|
+
expect(XRayMachine.options.instance_variable_get("@streams")).to eq({
|
15
|
+
thing: {title: "Thingy", color: :red, show_in_summary: true}
|
16
|
+
})
|
17
|
+
end
|
18
|
+
|
19
|
+
it "allows to override colors and the summary settings" do
|
20
|
+
XRayMachine.config do |config|
|
21
|
+
config.thing = {title: "Thingy", color: :yellow, show_in_summary: false}
|
22
|
+
end
|
23
|
+
|
24
|
+
expect(XRayMachine.options.instance_variable_get("@streams")).to eq({
|
25
|
+
thing: {title: "Thingy", color: :yellow, show_in_summary: false}
|
26
|
+
})
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe ".for" do
|
32
|
+
subject { XRayMachine::Config.for("some_thing").to_h }
|
33
|
+
|
34
|
+
it "generates a new config if the settings are missing" do
|
35
|
+
is_expected.to eq({title: "SomeThing", color: "\e[31m", show_in_summary: true})
|
36
|
+
end
|
37
|
+
|
38
|
+
it "uses the user settings when it configured" do
|
39
|
+
XRayMachine.config { |c| c.some_thing = {title: "ST", color: :yellow} }
|
40
|
+
|
41
|
+
is_expected.to eq({title: "ST", color: "\e[33m", show_in_summary: true})
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns the same object every time" do
|
45
|
+
is_expected.to eq(XRayMachine::Config.for("some_thing").to_h)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "picks different colors for different things" do
|
49
|
+
colors = (1..3).to_a.map{|i| XRayMachine::Config.for("thing_#{i}").color }
|
50
|
+
expect(colors).to eq ["\e[31m", "\e[32m", "\e[33m"]
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe XRayMachine::LogSubscriber do
|
4
|
+
before { XRayMachine::LogSubscriber.reset_runtimes }
|
5
|
+
|
6
|
+
describe ".runtimes" do
|
7
|
+
subject { XRayMachine::LogSubscriber.runtimes }
|
8
|
+
|
9
|
+
it { is_expected.to be_a Hash }
|
10
|
+
it { is_expected.to eq({}) }
|
11
|
+
|
12
|
+
it "returns the same object all the time" do
|
13
|
+
other_object = XRayMachine::LogSubscriber.runtimes
|
14
|
+
|
15
|
+
is_expected.to be other_object
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#request" do
|
20
|
+
let(:subscriber) { XRayMachine::LogSubscriber.new }
|
21
|
+
let(:event) { double("Event", duration: 11, payload: payload) }
|
22
|
+
let(:payload) { {query: "some/query/data", cache: false, group: "external_api"} }
|
23
|
+
|
24
|
+
subject { subscriber.request(event) }
|
25
|
+
|
26
|
+
before do
|
27
|
+
def subscriber.debug(string=nil)
|
28
|
+
@debug ||= string
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "saves the duration in the runtimes list" do
|
33
|
+
expect{ subject }.to change{ XRayMachine::LogSubscriber.runtimes }.to({"external_api" => 11})
|
34
|
+
end
|
35
|
+
|
36
|
+
it "dumps the data in the debugging stream" do
|
37
|
+
expect{ subject }.to change{ subscriber.debug }
|
38
|
+
.to(" \e[1m\e[34mExternalApi (11.0ms)\e[0m some/query/data")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "marks things cached when the payload have a cache:true option" do
|
42
|
+
payload[:cache] = true
|
43
|
+
|
44
|
+
expect{ subject }.to change{ subscriber.debug }
|
45
|
+
.to(" \e[1m\e[34mExternalApi CACHE (11.0ms)\e[0m some/query/data")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe XRayMachine::Summary do
|
4
|
+
|
5
|
+
before do
|
6
|
+
XRayMachine.instance_eval { @options = nil }
|
7
|
+
XRayMachine::LogSubscriber.reset_runtimes
|
8
|
+
XRayMachine::LogSubscriber.runtimes.merge!({
|
9
|
+
one: 11, two: 22, three: 33
|
10
|
+
})
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ".add" do
|
14
|
+
let(:payload) { {view_runtime: 123} }
|
15
|
+
|
16
|
+
subject { XRayMachine::Summary.add(payload) }
|
17
|
+
|
18
|
+
it "substracts the custom runtime from the views runtime" do
|
19
|
+
expect{ subject }.to change{ payload }.to({view_runtime: 57})
|
20
|
+
end
|
21
|
+
|
22
|
+
it "doesn't change the view runtime when it's less than the recorded rintimes" do
|
23
|
+
payload[:view_runtime] = 10
|
24
|
+
|
25
|
+
expect{ subject }.not_to change{ payload }
|
26
|
+
end
|
27
|
+
|
28
|
+
it "doesn't explode when the view data is missing" do
|
29
|
+
payload.delete :view_runtime
|
30
|
+
|
31
|
+
expect{ subject }.not_to raise_error
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe ".messages" do
|
36
|
+
subject { XRayMachine::Summary.messages }
|
37
|
+
|
38
|
+
it "generates a list of summary messages from the recorded runtimes" do
|
39
|
+
is_expected.to eq ["One: 11.0ms", "Two: 22.0ms", "Three: 33.0ms"]
|
40
|
+
end
|
41
|
+
|
42
|
+
it "respect the title settings" do
|
43
|
+
XRayMachine.config{ |c| c.one = {title: "Custom One"} }
|
44
|
+
|
45
|
+
is_expected.to eq ["Custom One: 11.0ms", "Two: 22.0ms", "Three: 33.0ms"]
|
46
|
+
end
|
47
|
+
|
48
|
+
it "hides runtimes that are configured to be hidden from the summary" do
|
49
|
+
XRayMachine.config{ |c| c.one = {show_in_summary: false} }
|
50
|
+
|
51
|
+
is_expected.to eq ["Two: 22.0ms", "Three: 33.0ms"]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe XRay do
|
4
|
+
|
5
|
+
before do
|
6
|
+
ActiveSupport::Notifications.instance_eval do
|
7
|
+
def self.instrument(*args, &block)
|
8
|
+
@args = args
|
9
|
+
yield
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def active_support_args
|
15
|
+
ActiveSupport::Notifications.instance_eval { @args }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe ".method_missing" do
|
19
|
+
it "runs whatevers" do
|
20
|
+
XRay.whatevers "query/data" do
|
21
|
+
end
|
22
|
+
|
23
|
+
expect(active_support_args).to eq [
|
24
|
+
"request.xraymachine", {group: :whatevers, query: "query/data", cache: false}
|
25
|
+
]
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns whatever the block yields" do
|
29
|
+
result = XRay.whatevers("query/data") { "yielded result" }
|
30
|
+
expect(result).to eq "yielded result"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "sends a ray in and allows to mark it as cached" do
|
34
|
+
XRay.whatevers "query/data" do |ray|
|
35
|
+
ray.cached = true
|
36
|
+
end
|
37
|
+
|
38
|
+
expect(active_support_args).to eq [
|
39
|
+
"request.xraymachine", {group: :whatevers, query: "query/data", cache: true}
|
40
|
+
]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.dirname(__FILE__)+ '/lib/x_ray_machine/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "x-ray-machine"
|
5
|
+
spec.version = XRayMachine::VERSION
|
6
|
+
spec.authors = ["Nikolay Nemshilov"]
|
7
|
+
spec.email = ["nemshilov@gmail.com"]
|
8
|
+
spec.description = "Better instrumentation/logging utility for Rails"
|
9
|
+
spec.summary = "Better instrumentation/logging utility for Rails. Seriously"
|
10
|
+
spec.homepage = "https://github.com/MadRabbit/x-ray-machine"
|
11
|
+
spec.license = "MIT"
|
12
|
+
|
13
|
+
spec.files = `git ls-files`.split($/)
|
14
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
15
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
16
|
+
spec.require_paths = ["lib"]
|
17
|
+
|
18
|
+
spec.add_runtime_dependency 'rails', '~> 4.0', '>= 4.0.0'
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
21
|
+
spec.add_development_dependency "rspec", "~> 3.1"
|
22
|
+
spec.add_development_dependency "guard-rspec", "~> 4.3"
|
23
|
+
end
|
data/x-ray.jpg
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: x-ray-machine
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nikolay Nemshilov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 4.0.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 4.0.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: bundler
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.7'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.7'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '3.1'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '3.1'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: guard-rspec
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '4.3'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '4.3'
|
75
|
+
description: Better instrumentation/logging utility for Rails
|
76
|
+
email:
|
77
|
+
- nemshilov@gmail.com
|
78
|
+
executables:
|
79
|
+
- bundler
|
80
|
+
- coderay
|
81
|
+
- erubis
|
82
|
+
- guard
|
83
|
+
- htmldiff
|
84
|
+
- ldiff
|
85
|
+
- listen
|
86
|
+
- pry
|
87
|
+
- rackup
|
88
|
+
- rails
|
89
|
+
- rake
|
90
|
+
- rspec
|
91
|
+
- sprockets
|
92
|
+
- thor
|
93
|
+
- tilt
|
94
|
+
extensions: []
|
95
|
+
extra_rdoc_files: []
|
96
|
+
files:
|
97
|
+
- ".gitignore"
|
98
|
+
- ".rspec"
|
99
|
+
- Gemfile
|
100
|
+
- Gemfile.lock
|
101
|
+
- Guardfile
|
102
|
+
- README.md
|
103
|
+
- bin/bundler
|
104
|
+
- bin/coderay
|
105
|
+
- bin/erubis
|
106
|
+
- bin/guard
|
107
|
+
- bin/htmldiff
|
108
|
+
- bin/ldiff
|
109
|
+
- bin/listen
|
110
|
+
- bin/pry
|
111
|
+
- bin/rackup
|
112
|
+
- bin/rails
|
113
|
+
- bin/rake
|
114
|
+
- bin/rspec
|
115
|
+
- bin/sprockets
|
116
|
+
- bin/thor
|
117
|
+
- bin/tilt
|
118
|
+
- lib/x-ray-machine.rb
|
119
|
+
- lib/x_ray_machine.rb
|
120
|
+
- lib/x_ray_machine/config.rb
|
121
|
+
- lib/x_ray_machine/log_subscriber.rb
|
122
|
+
- lib/x_ray_machine/railtie.rb
|
123
|
+
- lib/x_ray_machine/summary.rb
|
124
|
+
- lib/x_ray_machine/version.rb
|
125
|
+
- lib/x_ray_machine/x_ray.rb
|
126
|
+
- spec/lib/x_ray_machine/config_spec.rb
|
127
|
+
- spec/lib/x_ray_machine/log_subscriber_spec.rb
|
128
|
+
- spec/lib/x_ray_machine/summary_spec.rb
|
129
|
+
- spec/lib/x_ray_machine/x_ray_spec.rb
|
130
|
+
- spec/spec_helper.rb
|
131
|
+
- x-ray-machine.gemspec
|
132
|
+
- x-ray.jpg
|
133
|
+
homepage: https://github.com/MadRabbit/x-ray-machine
|
134
|
+
licenses:
|
135
|
+
- MIT
|
136
|
+
metadata: {}
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 2.2.2
|
154
|
+
signing_key:
|
155
|
+
specification_version: 4
|
156
|
+
summary: Better instrumentation/logging utility for Rails. Seriously
|
157
|
+
test_files:
|
158
|
+
- spec/lib/x_ray_machine/config_spec.rb
|
159
|
+
- spec/lib/x_ray_machine/log_subscriber_spec.rb
|
160
|
+
- spec/lib/x_ray_machine/summary_spec.rb
|
161
|
+
- spec/lib/x_ray_machine/x_ray_spec.rb
|
162
|
+
- spec/spec_helper.rb
|