fluoride-collector 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/fluoride-collector/middleware.rb +85 -50
- data/lib/fluoride-collector/rails/railtie.rb +10 -2
- data/spec/middleware.rb +19 -12
- data/spec/railtie.rb +8 -3
- data/spec_help/spec_helper.rb +3 -3
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e105ac67bef95d43c62790318839abbd6fe991eb
|
4
|
+
data.tar.gz: 888928f7e2a84edab100ca809c51788bf1ece05f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc2e0053d0b0cdbe700dffa08514b38990a88640bd059d6c01ab9bc56d3f654b0cff179889eae9585133c0d7fe89b4e0feed935e38d4da8df7094627cce5d56e
|
7
|
+
data.tar.gz: e07ceb9cfde86ead95d37a32f5e621c2555f0f8a33fa6278ca224ad3f31ec3f1314f6cae95f9d18c86d822921f6a3e82d7585406b21bb9b14ba40b40eb9ec778
|
@@ -1,39 +1,46 @@
|
|
1
1
|
module Fluoride
|
2
2
|
module Collector
|
3
3
|
class Middleware
|
4
|
-
def initialize(app, directory, tagging = nil)
|
4
|
+
def initialize(app, directory, storage_limit = 250_000_000, tagging = nil)
|
5
5
|
@app = app
|
6
6
|
@directory = directory
|
7
|
+
@storage_limit = storage_limit
|
7
8
|
@tagging = tagging
|
8
9
|
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
rescue Object => ex
|
15
|
-
record_exception(env, ex)
|
16
|
-
raise
|
11
|
+
private
|
12
|
+
|
13
|
+
def thread_locals
|
14
|
+
Thread.current[:fluoride_collector] ||= {}
|
17
15
|
end
|
18
16
|
|
19
|
-
|
17
|
+
def storage_path
|
18
|
+
thread_locals[collection_type] ||= File::join(@directory, "#{collection_type}-#{Process.pid}-#{Thread.current.object_id}.yml")
|
19
|
+
end
|
20
|
+
|
21
|
+
def storage_file
|
22
|
+
FileUtils.mkdir_p(File::dirname(storage_path))
|
23
|
+
return if storage_used > @storage_limit
|
24
|
+
File::open(storage_path, "a") do |file|
|
25
|
+
yield file
|
26
|
+
end
|
27
|
+
end
|
20
28
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
29
|
+
def storage_used
|
30
|
+
dir = Dir.new(@directory)
|
31
|
+
dir.inject(0) do |sum, file|
|
32
|
+
if file =~ %r{\A\.}
|
33
|
+
sum
|
34
|
+
else
|
35
|
+
sum + File.size(File::join(@directory, file))
|
36
|
+
end
|
37
|
+
end
|
28
38
|
end
|
29
39
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
"request" => request_hash(env),
|
35
|
-
"response" => exception_hash(ex)
|
36
|
-
)
|
40
|
+
def store(record)
|
41
|
+
storage_file do |file|
|
42
|
+
file.write(YAML::dump(record))
|
43
|
+
end
|
37
44
|
end
|
38
45
|
|
39
46
|
def request_hash(env)
|
@@ -56,41 +63,69 @@ module Fluoride
|
|
56
63
|
}
|
57
64
|
end
|
58
65
|
|
59
|
-
|
60
|
-
|
66
|
+
class CollectExceptions < Middleware
|
67
|
+
def call(env)
|
68
|
+
@app.call(env)
|
69
|
+
rescue Object => ex
|
70
|
+
store(
|
71
|
+
"type" => "exception_raised",
|
72
|
+
"tags" => @tagging,
|
73
|
+
"request" => request_hash(env),
|
74
|
+
"response" => exception_hash(ex)
|
75
|
+
)
|
76
|
+
raise
|
77
|
+
end
|
61
78
|
|
62
|
-
|
63
|
-
"status" => status,
|
64
|
-
"headers" => headers,
|
65
|
-
"body" => body.to_a.join("") #every body? all of it?
|
66
|
-
}
|
67
|
-
end
|
79
|
+
private
|
68
80
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
"message" => ex.message,
|
73
|
-
"backtrace" => ex.backtrace[0..10]
|
74
|
-
}
|
75
|
-
end
|
81
|
+
def collection_type
|
82
|
+
:exception
|
83
|
+
end
|
76
84
|
|
77
|
-
|
78
|
-
|
85
|
+
def exception_hash(ex)
|
86
|
+
{
|
87
|
+
"type" => ex.class.name,
|
88
|
+
"message" => ex.message,
|
89
|
+
"backtrace" => ex.backtrace[0..10]
|
90
|
+
}
|
91
|
+
end
|
79
92
|
end
|
80
93
|
|
81
|
-
|
82
|
-
|
83
|
-
|
94
|
+
class CollectExchanges < Middleware
|
95
|
+
def call(env)
|
96
|
+
@app.call(env).tap do |response|
|
97
|
+
store(
|
98
|
+
"type" => "normal_exchange",
|
99
|
+
"tags" => @tagging,
|
100
|
+
"request" => request_hash(env),
|
101
|
+
"response" => response_hash(response)
|
102
|
+
)
|
103
|
+
end
|
104
|
+
end
|
84
105
|
|
85
|
-
|
86
|
-
|
87
|
-
|
106
|
+
private
|
107
|
+
|
108
|
+
def collection_type
|
109
|
+
:exchange
|
88
110
|
end
|
89
|
-
end
|
90
111
|
|
91
|
-
|
92
|
-
|
93
|
-
|
112
|
+
def extract_body(body)
|
113
|
+
array = []
|
114
|
+
body.each do |chunk|
|
115
|
+
array << chunk
|
116
|
+
end
|
117
|
+
body.rewind if body.respond_to?(:rewind)
|
118
|
+
array
|
119
|
+
end
|
120
|
+
|
121
|
+
def response_hash(response)
|
122
|
+
status, headers, body = *response
|
123
|
+
|
124
|
+
{
|
125
|
+
"status" => status,
|
126
|
+
"headers" => headers,
|
127
|
+
"body" => extract_body(body)
|
128
|
+
}
|
94
129
|
end
|
95
130
|
end
|
96
131
|
end
|
@@ -2,12 +2,20 @@ module Fluoride
|
|
2
2
|
module Collector
|
3
3
|
class Railtie < ::Rails::Railtie
|
4
4
|
config.fluoride = ActiveSupport::OrderedOptions.new
|
5
|
+
config.fluoride.storage_limit = 250_000_000
|
5
6
|
config.fluoride.tags = nil
|
6
7
|
config.fluoride.directory = "fluoride-collector"
|
7
8
|
|
8
9
|
initializer "fluoride-collector.add_middleware" do |app|
|
9
|
-
app.middleware.
|
10
|
-
|
10
|
+
app.middleware.use( Fluoride::Collector::Middleware::CollectExceptions,
|
11
|
+
config.fluoride.directory,
|
12
|
+
config.fluoride.storage_limit,
|
13
|
+
config.fluoride.tags)
|
14
|
+
app.middleware.insert("Rack::Sendfile",
|
15
|
+
Fluoride::Collector::Middleware::CollectExchanges,
|
16
|
+
config.fluoride.directory,
|
17
|
+
config.fluoride.storage_limit,
|
18
|
+
config.fluoride.tags)
|
11
19
|
end
|
12
20
|
end
|
13
21
|
end
|
data/spec/middleware.rb
CHANGED
@@ -11,8 +11,9 @@ describe Fluoride::Collector::Middleware do
|
|
11
11
|
|
12
12
|
let :app do
|
13
13
|
run_app = test_app
|
14
|
+
klass = middleware_class
|
14
15
|
Rack::Builder.app do
|
15
|
-
use
|
16
|
+
use klass, "collections", 1500, "TEST"
|
16
17
|
run run_app
|
17
18
|
end
|
18
19
|
end
|
@@ -26,6 +27,10 @@ describe Fluoride::Collector::Middleware do
|
|
26
27
|
Class.new(Exception)
|
27
28
|
end
|
28
29
|
|
30
|
+
let :middleware_class do
|
31
|
+
Fluoride::Collector::Middleware::CollectExceptions
|
32
|
+
end
|
33
|
+
|
29
34
|
let :test_app do
|
30
35
|
lambda{|env| raise test_ex_class, "test exception"}
|
31
36
|
end
|
@@ -42,7 +47,7 @@ describe Fluoride::Collector::Middleware do
|
|
42
47
|
app.call(env)
|
43
48
|
rescue test_ex_class
|
44
49
|
end
|
45
|
-
end.to change{collection_directory.each.to_a.grep(/
|
50
|
+
end.to change{collection_directory.each.to_a.grep(/[a-z].*/).size}
|
46
51
|
end
|
47
52
|
|
48
53
|
it "should keep using the same collection file" do
|
@@ -56,8 +61,7 @@ describe Fluoride::Collector::Middleware do
|
|
56
61
|
app.call(env)
|
57
62
|
rescue test_ex_class
|
58
63
|
end
|
59
|
-
|
60
|
-
end.not_to change{collection_directory.each.to_a.grep(/collection.*/).size}
|
64
|
+
end.not_to change{collection_directory.each.to_a.grep(/[a-z].*/).size}
|
61
65
|
end
|
62
66
|
|
63
67
|
describe "creates a file" do
|
@@ -66,12 +70,12 @@ describe Fluoride::Collector::Middleware do
|
|
66
70
|
app.call(env)
|
67
71
|
rescue test_ex_class
|
68
72
|
end
|
69
|
-
path = File::join(collection_directory.path, collection_directory.each.to_a.grep(/
|
73
|
+
path = File::join(collection_directory.path, collection_directory.each.to_a.grep(/[a-z].*/).first)
|
70
74
|
YAML.load_stream(File.read(path)).first
|
71
75
|
end
|
72
76
|
|
73
77
|
it "should have tags" do
|
74
|
-
yaml["tags"].
|
78
|
+
expect(yaml["tags"]).to eq "TEST"
|
75
79
|
end
|
76
80
|
end
|
77
81
|
end
|
@@ -85,33 +89,36 @@ describe Fluoride::Collector::Middleware do
|
|
85
89
|
[200, {'Content-Type' => 'text/plain'}, ['Just a test']]
|
86
90
|
end
|
87
91
|
|
92
|
+
let :middleware_class do
|
93
|
+
Fluoride::Collector::Middleware::CollectExchanges
|
94
|
+
end
|
95
|
+
|
88
96
|
it "should not change the response" do
|
89
|
-
app.call(env).
|
97
|
+
expect(app.call(env)).to eq response
|
90
98
|
end
|
91
99
|
|
92
100
|
it "should create a collection file" do
|
93
101
|
expect do
|
94
102
|
app.call(env)
|
95
|
-
end.to change{collection_directory.each.to_a.grep(/
|
103
|
+
end.to change{collection_directory.each.to_a.grep(/[a-z].*/).size}
|
96
104
|
end
|
97
105
|
|
98
106
|
it "should keep using the same collection file" do
|
99
107
|
app.call(env)
|
100
108
|
expect do
|
101
109
|
app.call(env)
|
102
|
-
|
103
|
-
end.not_to change{collection_directory.each.to_a.grep(/collection.*/).size}
|
110
|
+
end.not_to change{collection_directory.each.to_a.grep(/[a-z].*/).size}
|
104
111
|
end
|
105
112
|
|
106
113
|
describe "creates a file" do
|
107
114
|
let :yaml do
|
108
115
|
app.call(env)
|
109
|
-
path = File::join(collection_directory.path, collection_directory.each.to_a.grep(/
|
116
|
+
path = File::join(collection_directory.path, collection_directory.each.to_a.grep(/[a-z].*/).first)
|
110
117
|
YAML.load_stream(File.read(path)).first
|
111
118
|
end
|
112
119
|
|
113
120
|
it "should have tags" do
|
114
|
-
yaml["tags"].
|
121
|
+
expect(yaml["tags"]).to eq "TEST"
|
115
122
|
end
|
116
123
|
end
|
117
124
|
end
|
data/spec/railtie.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
require 'railtie-help'
|
2
2
|
|
3
3
|
describe Fluoride::Collector::Railtie do
|
4
|
-
it "should
|
5
|
-
|
4
|
+
it "should add exception collection to the middleware stack" do
|
5
|
+
expect(Rails.application.middleware.middlewares).to include(Fluoride::Collector::Middleware::CollectExceptions)
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
+
it "should add exchange collection to the middleware stack" do
|
9
|
+
expect(Rails.application.middleware.middlewares).to include(Fluoride::Collector::Middleware::CollectExchanges)
|
8
10
|
end
|
9
11
|
|
12
|
+
it "should put exchange collection at top of stack" do
|
13
|
+
expect(Rails.application.middleware.middlewares.first).to eq(Fluoride::Collector::Middleware::CollectExchanges)
|
14
|
+
end
|
10
15
|
end
|
data/spec_help/spec_helper.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'rspec'
|
2
2
|
require 'rspec/core/formatters/base_formatter'
|
3
|
-
require 'cadre/rspec'
|
4
3
|
require 'file-sandbox'
|
4
|
+
require 'cadre/rspec3'
|
5
5
|
|
6
6
|
RSpec.configure do |config|
|
7
7
|
config.run_all_when_everything_filtered = true
|
8
|
-
config.add_formatter(Cadre::
|
9
|
-
config.add_formatter(Cadre::
|
8
|
+
config.add_formatter(Cadre::RSpec3::NotifyOnCompleteFormatter)
|
9
|
+
config.add_formatter(Cadre::RSpec3::QuickfixFormatter)
|
10
10
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluoride-collector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Judson Lester
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
14
|
Part of the Fluoride suite - tools for making your black box a bit whiter
|
@@ -38,7 +38,7 @@ rdoc_options:
|
|
38
38
|
- --main
|
39
39
|
- doc/README
|
40
40
|
- --title
|
41
|
-
- fluoride-collector-0.0.
|
41
|
+
- fluoride-collector-0.0.2 Documentation
|
42
42
|
require_paths:
|
43
43
|
- lib/
|
44
44
|
required_ruby_version: !ruby/object:Gem::Requirement
|