fluoride-collector 0.0.3 → 0.0.4

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 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