fluoride-collector 0.0.3 → 0.0.4

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: cf7c03aa82878bb35ce0803cf3fafc97821809aa
4
- data.tar.gz: 6011f540fff63c4babdbf8e449c20f634c227113
3
+ metadata.gz: 2c5a859fb19f96aa3640e06ba654c5fbe887ea06
4
+ data.tar.gz: 0a295ed1d22617b187be2a446fcf58042edadb06
5
5
  SHA512:
6
- metadata.gz: d296dd8d97c1d6d85750cb366588bbd9cb6f29fc701a7a04c9e12c99c9b707e7b8eb9565287b394d16d2ef9a485948c3194e7b8f86a20579da69a7a42b730934
7
- data.tar.gz: 54fb62bc45b2300147f71920cc804860e7f99ad399d9913bd1efae8237ce7692201ff95b1597b1edbf0bc4fa2234d36a9a924f05ceaa16321fb536e1fe061eff
6
+ metadata.gz: da0889ab97c77b64a3ccdc2489a8a85c2262397fb5c57aa250b90e7c27ba05116de989da726bd2e5083a159aaa2ecf316971555ba33cec5cab46caee7882c7fb
7
+ data.tar.gz: 795e63f92f12646eb040715c87d1338bd86309dabd95def0982c153f864345dd720efe8cdd8f5b3d29d573a4e3bf8baa665a9afedcd3fb0672697d03cfbd47f8
@@ -0,0 +1,37 @@
1
+ require 'fluoride-collector'
2
+ module Fluoride
3
+ module Collector
4
+ class Config
5
+ attr_accessor :tags
6
+
7
+ def persister(type, record)
8
+ persister_class.new(self, type, record)
9
+ end
10
+
11
+ class FS < Config
12
+ attr_accessor :directory, :storage_limit
13
+
14
+ def initialize
15
+ require 'fluoride-collector/storage/fs'
16
+ @storage_limit = 250_000_000
17
+ end
18
+
19
+ def persister_class
20
+ Storage::FS
21
+ end
22
+ end
23
+
24
+ class S3 < Config
25
+ attr_accessor :bucket, :key_id, :access_secret
26
+
27
+ def initialize
28
+ require 'fluoride-collector/storage/s3'
29
+ end
30
+
31
+ def persister_class
32
+ Storage::S3
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,34 @@
1
+ require 'fluoride-collector/middleware'
2
+ module Fluoride
3
+ module Collector
4
+ class Middleware
5
+ class CollectExceptions < Middleware
6
+ def call(env)
7
+ @app.call(env)
8
+ rescue Object => ex
9
+ store( clean_hash(
10
+ "type" => "exception_raised",
11
+ "tags" => @tagging,
12
+ "request" => request_hash(env),
13
+ "response" => exception_hash(ex)
14
+ ))
15
+ raise
16
+ end
17
+
18
+ private
19
+
20
+ def collection_type
21
+ :exception
22
+ end
23
+
24
+ def exception_hash(ex)
25
+ {
26
+ "type" => ex.class.name,
27
+ "message" => ex.message,
28
+ "backtrace" => ex.backtrace[0..10]
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,44 @@
1
+ require 'fluoride-collector/middleware'
2
+ module Fluoride
3
+ module Collector
4
+ class Middleware
5
+ class CollectExchanges < Middleware
6
+ def call(env)
7
+ @app.call(env).tap do |response|
8
+ store( clean_hash(
9
+ "type" => "normal_exchange",
10
+ "tags" => @tagging,
11
+ "request" => request_hash(env),
12
+ "response" => response_hash(response)
13
+ ))
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def collection_type
20
+ :exchange
21
+ end
22
+
23
+ def extract_body(body)
24
+ array = []
25
+ body.each do |chunk|
26
+ array << chunk
27
+ end
28
+ body.rewind if body.respond_to?(:rewind)
29
+ array
30
+ end
31
+
32
+ def response_hash(response)
33
+ status, headers, body = *response
34
+
35
+ {
36
+ "status" => status,
37
+ "headers" => headers.to_hash,
38
+ "body" => extract_body(body)
39
+ }
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,48 +1,24 @@
1
1
  require 'uri'
2
-
2
+ require 'fluoride-collector'
3
3
  module Fluoride
4
4
  module Collector
5
5
  class Middleware
6
- def initialize(app, directory, storage_limit = 250_000_000, tagging = nil)
6
+ attr_reader :config
7
+
8
+ def initialize(app, config)
7
9
  @app = app
8
- @directory = directory
9
- @storage_limit = storage_limit
10
- @tagging = tagging
10
+ @config = config
11
+ @tagging = config.tags
11
12
  end
12
13
 
13
14
  private
14
15
 
15
- def thread_locals
16
- Thread.current[:fluoride_collector] ||= {}
17
- end
18
-
19
- def storage_path
20
- thread_locals[collection_type] ||= File::join(@directory, "#{collection_type}-#{Process.pid}-#{Thread.current.object_id}.yml")
21
- end
22
-
23
- def storage_file
24
- FileUtils.mkdir_p(File::dirname(storage_path))
25
- return if storage_used > @storage_limit
26
- File::open(storage_path, "a") do |file|
27
- yield file
28
- end
29
- end
30
-
31
- def storage_used
32
- dir = Dir.new(@directory)
33
- dir.inject(0) do |sum, file|
34
- if file =~ %r{\A\.}
35
- sum
36
- else
37
- sum + File.size(File::join(@directory, file))
38
- end
39
- end
40
- end
41
-
42
16
  def store(record)
43
- storage_file do |file|
44
- file.write(YAML::dump(record))
45
- end
17
+ #take only pictures
18
+ @config.persister(collection_type, record).write
19
+ rescue Exception => ex
20
+ #leave only footprints
21
+ $stderr.puts "#{ex.inspect}" if $stderr.respond_to? :puts
46
22
  end
47
23
 
48
24
  def clean_hash(hash)
@@ -50,7 +26,7 @@ module Fluoride
50
26
  value = hash[key]
51
27
  case value
52
28
  when String
53
- if value.ascii_only?
29
+ if value.respond_to?(:ascii_only?) and value.ascii_only? and value.respond_to?(:force_encoding)
54
30
  value = value.dup
55
31
  value.force_encoding("US-ASCII")
56
32
  hash[key] = value
@@ -78,75 +54,9 @@ module Fluoride
78
54
  "host" => env['HTTP_HOST'] || "#{env['SERVER_NAME'] || env['SERVER_ADDR']}:#{env['SERVER_PORT']}",
79
55
  "path" => URI.unescape(env["SCRIPT_NAME"].to_s + env["PATH_INFO"].to_s),
80
56
  "query_string" => env["QUERY_STRING"].to_s,
81
- "body" => body,
57
+ "body" => body
82
58
  )
83
59
  end
84
-
85
- class CollectExceptions < Middleware
86
- def call(env)
87
- @app.call(env)
88
- rescue Object => ex
89
- store( clean_hash(
90
- "type" => "exception_raised",
91
- "tags" => @tagging,
92
- "request" => request_hash(env),
93
- "response" => exception_hash(ex)
94
- ))
95
- raise
96
- end
97
-
98
- private
99
-
100
- def collection_type
101
- :exception
102
- end
103
-
104
- def exception_hash(ex)
105
- {
106
- "type" => ex.class.name,
107
- "message" => ex.message,
108
- "backtrace" => ex.backtrace[0..10]
109
- }
110
- end
111
- end
112
-
113
- class CollectExchanges < Middleware
114
- def call(env)
115
- @app.call(env).tap do |response|
116
- store( clean_hash(
117
- "type" => "normal_exchange",
118
- "tags" => @tagging,
119
- "request" => request_hash(env),
120
- "response" => response_hash(response)
121
- ))
122
- end
123
- end
124
-
125
- private
126
-
127
- def collection_type
128
- :exchange
129
- end
130
-
131
- def extract_body(body)
132
- array = []
133
- body.each do |chunk|
134
- array << chunk
135
- end
136
- body.rewind if body.respond_to?(:rewind)
137
- array
138
- end
139
-
140
- def response_hash(response)
141
- status, headers, body = *response
142
-
143
- {
144
- "status" => status,
145
- "headers" => headers.to_hash,
146
- "body" => extract_body(body)
147
- }
148
- end
149
- end
150
60
  end
151
61
  end
152
62
  end
@@ -1,3 +1,5 @@
1
+ require 'fluoride-collector'
2
+
1
3
  module Fluoride
2
4
  module Collector
3
5
  class Railtie < ::Rails::Railtie
@@ -5,17 +7,27 @@ module Fluoride
5
7
  config.fluoride.storage_limit = 250_000_000
6
8
  config.fluoride.tags = nil
7
9
  config.fluoride.directory = "fluoride-collector"
10
+ config.fluoride.store_to = :file
8
11
 
9
12
  initializer "fluoride-collector.add_middleware" do |app|
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)
13
+ cfg = nil
14
+ case config.fluoride.store_to
15
+ when :file
16
+ cfg = Fluoride::Collector::Config::FS.new
17
+ cfg.directory = config.fluoride.directory
18
+ cfg.storage_limit = config.fluoride.storage_limit
19
+ when :s3
20
+ cfg = Fluoride::Collector::Config::S3.new
21
+ cfg.bucket = config.fluoride.bucket
22
+ cfg.key_id = config.fluoride.key_id
23
+ cfg.access_secret = config.fluoride.access_secret
24
+ else
25
+ raise Fluoride::Collector::ConfigurationError, "Don't know how to store to #{config.fluoride.store_to}!"
26
+ end
27
+ cfg.tags = config.fluoride.tags
28
+
29
+ app.middleware.use(Fluoride::Collector::Middleware::CollectExceptions, cfg)
30
+ app.middleware.insert(0, Fluoride::Collector::Middleware::CollectExchanges, cfg)
19
31
  end
20
32
  end
21
33
  end
@@ -0,0 +1,46 @@
1
+ require 'fluoride-collector'
2
+ require 'fluoride-collector/storage'
3
+ module Fluoride
4
+ module Collector
5
+ class Storage
6
+ class FS < Storage
7
+ def directory
8
+ @config.directory
9
+ end
10
+
11
+ def storage_limit
12
+ @config.storage_limit
13
+ end
14
+
15
+ def write
16
+ storage_file do |file|
17
+ file.write(record_yaml)
18
+ end
19
+ end
20
+
21
+ def storage_used
22
+ dir = Dir.new(directory)
23
+ dir.inject(0) do |sum, file|
24
+ if file =~ %r{\A\.}
25
+ sum
26
+ else
27
+ sum + File.size(File::join(directory, file))
28
+ end
29
+ end
30
+ end
31
+
32
+ def storage_path
33
+ thread_locals[collection_type] ||= File::join(directory, "#{collection_type}-#{Process.pid}-#{Thread.current.object_id}.yml")
34
+ end
35
+
36
+ def storage_file
37
+ FileUtils.mkdir_p(File::dirname(storage_path))
38
+ return if storage_used > storage_limit
39
+ File::open(storage_path, "a") do |file|
40
+ yield file
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,87 @@
1
+ require 'fluoride-collector'
2
+ require 'fluoride-collector/storage'
3
+ require 'net/http'
4
+ require 'openssl'
5
+ require 'base64'
6
+ module Fluoride
7
+ module Collector
8
+ class Storage
9
+ class S3 < Storage
10
+ def write
11
+ Net::HTTP.start(host, port) do |http|
12
+ res = http.request(put_request)
13
+ end
14
+ end
15
+
16
+ def bucket
17
+ @config.bucket
18
+ end
19
+
20
+ def key_id
21
+ @config.key_id
22
+ end
23
+
24
+ def access_secret
25
+ @config.access_secret
26
+ end
27
+
28
+ def host
29
+ "#{bucket}.s3.amazonaws.com"
30
+ end
31
+
32
+ def port
33
+ 443
34
+ end
35
+
36
+ def request_index
37
+ @request_index ||=
38
+ begin
39
+ thread_locals[:request_index] ||= 0
40
+ thread_locals[:request_index] += 1
41
+ end
42
+ end
43
+
44
+ def remote_path
45
+ @remote_path ||= "#{collection_type}-#{Process.pid}-#{Thread.current.object_id}-#{request_index}.yml"
46
+ end
47
+
48
+ def uri
49
+ "https://#{host}/#{remote_path}"
50
+ end
51
+
52
+ def authorization
53
+ hmac = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, string_to_sign, access_secret)
54
+ signature = Base64.strict_encode64(hmac)
55
+
56
+ "AWS #{key_id}:#{signature}"
57
+ end
58
+
59
+ def string_to_sign
60
+ "PUT\n#{content_md5}\n#{content_type}\n#{date}\n/#{bucket}/#{remote_path}"
61
+ end
62
+
63
+ def content_md5
64
+ @context_md5 ||= Base64.strict_encode64(OpenSSL::Digest::MD5.digest(record_yaml))
65
+ end
66
+
67
+ def content_type
68
+ "text/yaml"
69
+ end
70
+
71
+ def date
72
+ @date ||= Time.now.strftime("+%a, %d %h %Y %T %z")
73
+ end
74
+
75
+ def put_request
76
+ req = Net::HTTP::Put.new(uri)
77
+ req["Authorization"] = authorization
78
+ req["Date"] = date
79
+ req["Content-MD5"] = content_md5
80
+ req["Content-Type"] = content_type
81
+ req.body = record_yaml
82
+ return req
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,22 @@
1
+ require 'fluoride-collector'
2
+ module Fluoride
3
+ module Collector
4
+ class Storage
5
+ attr_reader :collection_type, :record
6
+
7
+ def initialize(config, type, record)
8
+ @record = record
9
+ @collection_type = type
10
+ @config = config
11
+ end
12
+
13
+ def thread_locals
14
+ Thread.current[:fluoride_collector] ||= {}
15
+ end
16
+
17
+ def record_yaml
18
+ @record_yaml ||= YAML::dump(record)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,2 +1,11 @@
1
- require 'fluoride-collector/middleware'
1
+ module Fluoride
2
+ module Collector
3
+ class ConfigurationError < ::StandardError
4
+ end
5
+ end
6
+ end
7
+
8
+ require 'fluoride-collector/config'
9
+ require 'fluoride-collector/middleware/collect-exceptions'
10
+ require 'fluoride-collector/middleware/collect-exchanges'
2
11
  require 'fluoride-collector/rails' if defined?(Rails)
data/spec/middleware.rb CHANGED
@@ -9,11 +9,20 @@ describe Fluoride::Collector::Middleware do
9
9
  Dir.new(dir.path)
10
10
  end
11
11
 
12
+ let :config do
13
+ Fluoride::Collector::Config::FS.new.tap do |cfg|
14
+ cfg.directory = "collections"
15
+ cfg.storage_limit = 1500
16
+ cfg.tags = "TEST"
17
+ end
18
+ end
19
+
12
20
  let :app do
13
21
  run_app = test_app
14
22
  klass = middleware_class
23
+ cfg = config
15
24
  Rack::Builder.app do
16
- use klass, "collections", 1500, "TEST"
25
+ use klass, cfg
17
26
  run run_app
18
27
  end
19
28
  end
@@ -71,7 +80,8 @@ describe Fluoride::Collector::Middleware do
71
80
  rescue test_ex_class
72
81
  end
73
82
  path = File::join(collection_directory.path, collection_directory.each.to_a.grep(/[a-z].*/).first)
74
- YAML.load_stream(File.read(path)).first
83
+ stream = YAML.load_stream(File.read(path))
84
+ stream[0]
75
85
  end
76
86
 
77
87
  it "should have tags" do
@@ -114,7 +124,7 @@ describe Fluoride::Collector::Middleware do
114
124
  let :yaml do
115
125
  app.call(env)
116
126
  path = File::join(collection_directory.path, collection_directory.each.to_a.grep(/[a-z].*/).first)
117
- YAML.load_stream(File.read(path)).first
127
+ YAML.load_stream(File.read(path))[0]
118
128
  end
119
129
 
120
130
  it "should have tags" do
data/spec/railtie.rb CHANGED
@@ -1,15 +1,58 @@
1
- require 'railtie-help'
1
+ require "action_controller/railtie"
2
+ require "rails/test_unit/railtie"
3
+ require 'fluoride-collector/rails'
2
4
 
3
5
  describe Fluoride::Collector::Railtie do
6
+
7
+ ENV["RAILS_ENV"] ||= 'test'
8
+
9
+ def config(app)
10
+
11
+ end
12
+
13
+ let :rails_application do
14
+ Class.new(::Rails::Application) do
15
+ config.active_support.deprecation = :stderr
16
+ config.eager_load = false
17
+ end.tap do |app|
18
+ config(app)
19
+ app.initialize!
20
+ end
21
+ end
22
+
23
+ after :each do
24
+ Rails.application = nil #because Rails has ideas of it's own, silly thing
25
+ end
26
+
4
27
  it "should add exception collection to the middleware stack" do
5
- expect(Rails.application.middleware.middlewares).to include(Fluoride::Collector::Middleware::CollectExceptions)
28
+ expect(rails_application.middleware.middlewares).to include(Fluoride::Collector::Middleware::CollectExceptions)
6
29
  end
7
30
 
8
31
  it "should add exchange collection to the middleware stack" do
9
- expect(Rails.application.middleware.middlewares).to include(Fluoride::Collector::Middleware::CollectExchanges)
32
+ expect(rails_application.middleware.middlewares).to include(Fluoride::Collector::Middleware::CollectExchanges)
10
33
  end
11
34
 
12
35
  it "should put exchange collection at top of stack" do
13
- expect(Rails.application.middleware.middlewares.first).to eq(Fluoride::Collector::Middleware::CollectExchanges)
36
+ expect(rails_application.middleware.middlewares.first).to eq(Fluoride::Collector::Middleware::CollectExchanges)
37
+ end
38
+
39
+ describe "configured to use S3" do
40
+ def config(app)
41
+ app.configure do
42
+ config.fluoride.store_to = :s3
43
+ config.fluoride.bucket = "nowhere-really"
44
+ config.fluoride.key_id = "testtest"
45
+ config.fluoride.access_secrety = "donttellnobody"
46
+ end
47
+ end
48
+
49
+ it "should put exchange collection at top of stack" do
50
+ expect(rails_application.middleware.middlewares.first).to eq(Fluoride::Collector::Middleware::CollectExchanges)
51
+ end
52
+
53
+ it "should configured collector with S3Storage" do
54
+ collector = rails_application.middleware.middlewares.first.build(proc{})
55
+ expect(collector.config.persister("exchange", {})).to be_a(Fluoride::Collector::Storage::S3)
56
+ end
14
57
  end
15
58
  end
metadata CHANGED
@@ -1,25 +1,33 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluoride-collector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Judson Lester
8
+ - Evan Down
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2014-06-16 00:00:00.000000000 Z
12
+ date: 2014-06-19 00:00:00.000000000 Z
12
13
  dependencies: []
13
14
  description: |2
14
15
  Part of the Fluoride suite - tools for making your black box a bit whiter
15
16
  email:
16
17
  - nyarly@gmail.com
18
+ - evan@lrdesign.com
17
19
  executables: []
18
20
  extensions: []
19
21
  extra_rdoc_files: []
20
22
  files:
21
23
  - lib/fluoride-collector/rails/railtie.rb
24
+ - lib/fluoride-collector/config.rb
25
+ - lib/fluoride-collector/middleware/collect-exchanges.rb
26
+ - lib/fluoride-collector/middleware/collect-exceptions.rb
22
27
  - lib/fluoride-collector/rails.rb
28
+ - lib/fluoride-collector/storage/fs.rb
29
+ - lib/fluoride-collector/storage/s3.rb
30
+ - lib/fluoride-collector/storage.rb
23
31
  - lib/fluoride-collector/middleware.rb
24
32
  - lib/fluoride-collector.rb
25
33
  - spec/railtie.rb
@@ -38,7 +46,7 @@ rdoc_options:
38
46
  - --main
39
47
  - doc/README
40
48
  - --title
41
- - fluoride-collector-0.0.3 Documentation
49
+ - fluoride-collector-0.0.4 Documentation
42
50
  require_paths:
43
51
  - lib/
44
52
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -52,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
60
  - !ruby/object:Gem::Version
53
61
  version: '0'
54
62
  requirements: []
55
- rubyforge_project: fluoride-collector
63
+ rubyforge_project:
56
64
  rubygems_version: 2.0.14
57
65
  signing_key:
58
66
  specification_version: 4