whoops_logger 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +38 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/lib/whoops_logger/configuration.rb +132 -0
- data/lib/whoops_logger/message.rb +26 -0
- data/lib/whoops_logger/message_creator.rb +24 -0
- data/lib/whoops_logger/sender.rb +83 -0
- data/lib/whoops_logger/strategies/basic.rb +11 -0
- data/lib/whoops_logger/strategy.rb +67 -0
- data/lib/whoops_logger.rb +45 -0
- data/spec/configuration_spec.rb +38 -0
- data/spec/fixtures/whoops_logger.yml +1 -0
- data/spec/message_creator_spec.rb +29 -0
- data/spec/sender_spec.rb +15 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/strategy_spec.rb +78 -0
- data/spec/whoops_logger_spec.rb +56 -0
- data/whoops_logger.gemspec +86 -0
- metadata +184 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
gem "json"
|
3
|
+
# Add dependencies required to use your gem here.
|
4
|
+
# Example:
|
5
|
+
# gem "activesupport", ">= 2.3.5"
|
6
|
+
|
7
|
+
# Add dependencies to develop your gem here.
|
8
|
+
# Include everything needed to run rake, tests, features, etc.
|
9
|
+
group :development do
|
10
|
+
gem "rspec", "~> 2.6.0"
|
11
|
+
gem "bundler", "~> 1.0.0"
|
12
|
+
gem "jeweler", "~> 1.5.2"
|
13
|
+
gem "ruby-debug"
|
14
|
+
gem "fakeweb"
|
15
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
columnize (0.3.2)
|
5
|
+
diff-lcs (1.1.2)
|
6
|
+
fakeweb (1.3.0)
|
7
|
+
git (1.2.5)
|
8
|
+
jeweler (1.5.2)
|
9
|
+
bundler (~> 1.0.0)
|
10
|
+
git (>= 1.2.5)
|
11
|
+
rake
|
12
|
+
json (1.5.1)
|
13
|
+
linecache (0.43)
|
14
|
+
rake (0.8.7)
|
15
|
+
rspec (2.6.0)
|
16
|
+
rspec-core (~> 2.6.0)
|
17
|
+
rspec-expectations (~> 2.6.0)
|
18
|
+
rspec-mocks (~> 2.6.0)
|
19
|
+
rspec-core (2.6.4)
|
20
|
+
rspec-expectations (2.6.0)
|
21
|
+
diff-lcs (~> 1.1.2)
|
22
|
+
rspec-mocks (2.6.0)
|
23
|
+
ruby-debug (0.10.4)
|
24
|
+
columnize (>= 0.1)
|
25
|
+
ruby-debug-base (~> 0.10.4.0)
|
26
|
+
ruby-debug-base (0.10.4)
|
27
|
+
linecache (>= 0.3)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
ruby
|
31
|
+
|
32
|
+
DEPENDENCIES
|
33
|
+
bundler (~> 1.0.0)
|
34
|
+
fakeweb
|
35
|
+
jeweler (~> 1.5.2)
|
36
|
+
json
|
37
|
+
rspec (~> 2.6.0)
|
38
|
+
ruby-debug
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Daniel Higginbotham
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= whoops_logger
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Contributing to whoops_logger
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
+
* Fork the project
|
10
|
+
* Start a feature/bugfix branch
|
11
|
+
* Commit and push until you are happy with your contribution
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2011 Daniel Higginbotham. See LICENSE.txt for
|
18
|
+
further details.
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "whoops_logger"
|
16
|
+
gem.homepage = "http://github.com/flyingmachine/whoops_logger"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{Handles basic notification responsibilities and allows creation of message creation strategies}
|
19
|
+
gem.description = %Q{Handles basic notification responsibilities and allows creation of message creation strategies}
|
20
|
+
gem.email = "daniel@flyingmachinestudios.com"
|
21
|
+
gem.authors = ["Daniel Higginbotham"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rspec/core'
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
32
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
36
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
37
|
+
spec.rcov = true
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => :spec
|
41
|
+
|
42
|
+
require 'rake/rdoctask'
|
43
|
+
Rake::RDocTask.new do |rdoc|
|
44
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
45
|
+
|
46
|
+
rdoc.rdoc_dir = 'rdoc'
|
47
|
+
rdoc.title = "whoops_logger #{version}"
|
48
|
+
rdoc.rdoc_files.include('README*')
|
49
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
50
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
# Borrows heavily from Hoptoad Notifier by Tammer Saleh
|
4
|
+
module WhoopsLogger
|
5
|
+
# Used to set up and modify settings for the notifier.
|
6
|
+
class Configuration
|
7
|
+
OPTIONS = [:host, :http_open_timeout, :http_read_timeout,
|
8
|
+
:port, :protocol, :proxy_host,
|
9
|
+
:proxy_pass, :proxy_port, :proxy_user, :secure].freeze
|
10
|
+
|
11
|
+
# The host to connect to
|
12
|
+
attr_accessor :host
|
13
|
+
|
14
|
+
# The port on which your Whoops server runs (defaults to 443 for secure
|
15
|
+
# connections, 80 for insecure connections).
|
16
|
+
attr_accessor :port
|
17
|
+
|
18
|
+
# +true+ for https connections, +false+ for http connections.
|
19
|
+
attr_accessor :secure
|
20
|
+
|
21
|
+
# The HTTP open timeout in seconds (defaults to 2).
|
22
|
+
attr_accessor :http_open_timeout
|
23
|
+
|
24
|
+
# The HTTP read timeout in seconds (defaults to 5).
|
25
|
+
attr_accessor :http_read_timeout
|
26
|
+
|
27
|
+
# The hostname of your proxy server (if using a proxy)
|
28
|
+
attr_accessor :proxy_host
|
29
|
+
|
30
|
+
# The port of your proxy server (if using a proxy)
|
31
|
+
attr_accessor :proxy_port
|
32
|
+
|
33
|
+
# The username to use when logging into your proxy server (if using a proxy)
|
34
|
+
attr_accessor :proxy_user
|
35
|
+
|
36
|
+
# The password to use when logging into your proxy server (if using a proxy)
|
37
|
+
attr_accessor :proxy_pass
|
38
|
+
|
39
|
+
# The logger used by WhoopsLogger
|
40
|
+
attr_accessor :logger
|
41
|
+
|
42
|
+
|
43
|
+
alias_method :secure?, :secure
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
@secure = false
|
47
|
+
@host = nil
|
48
|
+
@http_open_timeout = 2
|
49
|
+
@http_read_timeout = 5
|
50
|
+
end
|
51
|
+
|
52
|
+
# Allows config options to be read like a hash
|
53
|
+
#
|
54
|
+
# @param [Symbol] option Key for a given attribute
|
55
|
+
def [](option)
|
56
|
+
send(option)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns a hash of all configurable options
|
60
|
+
def to_hash
|
61
|
+
OPTIONS.inject({}) do |hash, option|
|
62
|
+
hash.merge(option.to_sym => send(option))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns a hash of all configurable options merged with +hash+
|
67
|
+
#
|
68
|
+
# @param [Hash] hash A set of configuration options that will take precedence over the defaults
|
69
|
+
def merge(hash)
|
70
|
+
to_hash.merge(hash)
|
71
|
+
end
|
72
|
+
|
73
|
+
def port
|
74
|
+
@port || default_port
|
75
|
+
end
|
76
|
+
|
77
|
+
def protocol
|
78
|
+
if secure?
|
79
|
+
'https'
|
80
|
+
else
|
81
|
+
'http'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def set(config)
|
86
|
+
case config
|
87
|
+
when Hash: set_with_hash(config)
|
88
|
+
when IO: set_with_io(config)
|
89
|
+
when String: set_with_string(config)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def set_with_hash(config)
|
94
|
+
OPTIONS.each do |option|
|
95
|
+
next unless self.respond_to?("#{option}=")
|
96
|
+
if config.has_key?(option)
|
97
|
+
self.send("#{option}=", config[option])
|
98
|
+
elsif config.has_key?(option.to_s)
|
99
|
+
self.send("#{option}=", config[option.to_s])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# String should be either a filename or YAML
|
105
|
+
def set_with_string(config)
|
106
|
+
if File.exists?(config)
|
107
|
+
set_with_yaml(File.read(config))
|
108
|
+
else
|
109
|
+
set_with_yaml(config)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def set_with_io(config)
|
114
|
+
set_with_yaml(config)
|
115
|
+
config.close
|
116
|
+
end
|
117
|
+
|
118
|
+
def set_with_yaml(config)
|
119
|
+
set_with_hash(YAML.load(config))
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def default_port
|
125
|
+
if secure?
|
126
|
+
443
|
127
|
+
else
|
128
|
+
80
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module WhoopsLogger
|
2
|
+
class Message
|
3
|
+
ATTRIBUTES = [:event_type, :service, :environment, :message, :event_group_identifier, :event_time, :details]
|
4
|
+
ATTRIBUTES.each do |attribute|
|
5
|
+
attr_accessor attribute
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_accessor :ignore
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
self.event_time = Time.now
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_hash
|
15
|
+
h = {}
|
16
|
+
ATTRIBUTES.each do |attribute|
|
17
|
+
h[attribute] = self.send(attribute)
|
18
|
+
end
|
19
|
+
h
|
20
|
+
end
|
21
|
+
|
22
|
+
def ignore?
|
23
|
+
ignore
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module WhoopsLogger
|
2
|
+
|
3
|
+
# A "glue" class which coordinates message creation
|
4
|
+
class MessageCreator
|
5
|
+
# get data from raw_data using a strategy to create a message and decide whether it should be ignored
|
6
|
+
attr_accessor :strategy, :message, :raw_data
|
7
|
+
|
8
|
+
def initialize(strategy, raw_data)
|
9
|
+
raise ArgumentError, "strategy can not be nil" if strategy.nil?
|
10
|
+
raise ArgumentError, "strategy must respond to 'call'" unless strategy.respond_to?(:call)
|
11
|
+
self.strategy = strategy
|
12
|
+
self.raw_data = raw_data
|
13
|
+
self.message = Message.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def create!
|
17
|
+
strategy.call(message, raw_data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def ignore_message?
|
21
|
+
message.ignore?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module WhoopsLogger
|
2
|
+
class Sender
|
3
|
+
NOTICES_URI = '/events/'.freeze
|
4
|
+
HTTP_ERRORS = [Timeout::Error,
|
5
|
+
Errno::EINVAL,
|
6
|
+
Errno::ECONNRESET,
|
7
|
+
EOFError,
|
8
|
+
Net::HTTPBadResponse,
|
9
|
+
Net::HTTPHeaderSyntaxError,
|
10
|
+
Net::ProtocolError,
|
11
|
+
Errno::ECONNREFUSED].freeze
|
12
|
+
|
13
|
+
HEADERS = {
|
14
|
+
'Content-type' => 'application/json',
|
15
|
+
'Accept' => 'application/json'
|
16
|
+
}
|
17
|
+
|
18
|
+
def initialize(options = {})
|
19
|
+
[:proxy_host, :proxy_port, :proxy_user, :proxy_pass, :protocol,
|
20
|
+
:host, :port, :secure, :http_open_timeout, :http_read_timeout].each do |option|
|
21
|
+
instance_variable_set("@#{option}", options[option])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Sends the notice data off to Whoops for processing.
|
26
|
+
#
|
27
|
+
# @param [Hash] data The notice to be sent off
|
28
|
+
def send_message(data)
|
29
|
+
# TODO: format
|
30
|
+
# TODO: validation
|
31
|
+
data = prepare_data(data)
|
32
|
+
logger.debug { "Sending request to #{url.to_s}:\n#{data}" } if logger
|
33
|
+
|
34
|
+
http =
|
35
|
+
Net::HTTP::Proxy(proxy_host, proxy_port, proxy_user, proxy_pass).
|
36
|
+
new(url.host, url.port)
|
37
|
+
|
38
|
+
http.read_timeout = http_read_timeout
|
39
|
+
http.open_timeout = http_open_timeout
|
40
|
+
http.use_ssl = secure
|
41
|
+
|
42
|
+
response = begin
|
43
|
+
http.post(url.path, data, HEADERS)
|
44
|
+
rescue *HTTP_ERRORS => e
|
45
|
+
log :error, "Timeout while contacting the Whoops server."
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
case response
|
50
|
+
when Net::HTTPSuccess then
|
51
|
+
log :info, "Success: #{response.class}", response
|
52
|
+
else
|
53
|
+
log :error, "Failure: #{response.class}", response
|
54
|
+
end
|
55
|
+
|
56
|
+
if response && response.respond_to?(:body)
|
57
|
+
error_id = response.body.match(%r{<error-id[^>]*>(.*?)</error-id>})
|
58
|
+
error_id[1] if error_id
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def prepare_data(data)
|
63
|
+
{:event => data}.to_json
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
attr_reader :proxy_host, :proxy_port, :proxy_user, :proxy_pass, :protocol,
|
69
|
+
:host, :port, :secure, :http_open_timeout, :http_read_timeout
|
70
|
+
|
71
|
+
def url
|
72
|
+
URI.parse("#{protocol}://#{host}:#{port}").merge(NOTICES_URI)
|
73
|
+
end
|
74
|
+
|
75
|
+
def log(level, message, response = nil)
|
76
|
+
logger.send level, message if logger
|
77
|
+
end
|
78
|
+
|
79
|
+
def logger
|
80
|
+
WhoopsLogger.config.logger
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
strategy = WhoopsLogger::Strategy.new("default::basic")
|
2
|
+
|
3
|
+
strategy.add_message_builder(:use_basic_hash) do |message, raw_data|
|
4
|
+
message.event_type = raw_data[:event_type]
|
5
|
+
message.service = raw_data[:service]
|
6
|
+
message.environment = raw_data[:environment]
|
7
|
+
message.message = raw_data[:message]
|
8
|
+
message.event_group_identifier = raw_data[:event_group_identifier]
|
9
|
+
message.event_time = raw_data[:event_time] if raw_data[:event_time]
|
10
|
+
message.details = raw_data[:details]
|
11
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module WhoopsLogger
|
2
|
+
|
3
|
+
# Strategies are responsible for building messages and determining whether a
|
4
|
+
# a message should be ignored.
|
5
|
+
#
|
6
|
+
# Each strategy contains any number of message builders and ignore criteria.
|
7
|
+
#
|
8
|
+
# Each message builder and ignore criteria takes a name. This makes adding a
|
9
|
+
# message builder or ignore criteria more like adding a method - the name
|
10
|
+
# makes it easier to see the intention of the code. It also makes it easier
|
11
|
+
# to get useful info when you inspect the strategy.
|
12
|
+
#
|
13
|
+
# Strategies use call to actually apply modifiers and criteria for the same
|
14
|
+
# reason that Rack uses call. Conceivably, you could add a strategy to the
|
15
|
+
# notifier with
|
16
|
+
# WhoopsLogger.strategies[:lambda_stragey] = lambda{ |message, raw_data|
|
17
|
+
# message.details = raw_data[:detail]
|
18
|
+
# }
|
19
|
+
# or something along those lines.
|
20
|
+
class Strategy
|
21
|
+
attr_accessor :name, :ignore_criteria, :message_builders
|
22
|
+
|
23
|
+
def initialize(name)
|
24
|
+
self.name = name
|
25
|
+
self.ignore_criteria = []
|
26
|
+
self.message_builders = []
|
27
|
+
WhoopsLogger.strategies[name] = self
|
28
|
+
end
|
29
|
+
|
30
|
+
def call(message, raw_data)
|
31
|
+
message_builders.each do |message_modifier|
|
32
|
+
message_modifier.call(message, raw_data)
|
33
|
+
end
|
34
|
+
|
35
|
+
ignore_criteria.each do |ignore_criterion|
|
36
|
+
if ignore_criterion.call(message, raw_data)
|
37
|
+
message.ignore = true
|
38
|
+
break
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# block should take two params, the message and the raw_data
|
44
|
+
# use raw_data to build the message
|
45
|
+
def add_message_builder(name, &block)
|
46
|
+
give_name(name, block)
|
47
|
+
@message_builders << block
|
48
|
+
end
|
49
|
+
|
50
|
+
# block takes one param, the message_creator's message
|
51
|
+
def add_ignore_criteria(name, &block)
|
52
|
+
give_name(name, block)
|
53
|
+
@ignore_criteria << block
|
54
|
+
end
|
55
|
+
|
56
|
+
def give_name(name, block)
|
57
|
+
class << block
|
58
|
+
attr_accessor :name
|
59
|
+
end
|
60
|
+
block.name = name
|
61
|
+
end
|
62
|
+
|
63
|
+
def inspect
|
64
|
+
"#{name}\nmessage builders: #{message_builders.collect{|r| r.name}.join(", ")}\nignore criteria: #{ignore_criteria.collect{|i| i.name}.join(", ")}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module WhoopsLogger
|
6
|
+
autoload :Configuration, 'whoops_logger/configuration'
|
7
|
+
autoload :MessageCreator, 'whoops_logger/message_creator'
|
8
|
+
autoload :Message, 'whoops_logger/message'
|
9
|
+
autoload :Sender, 'whoops_logger/sender'
|
10
|
+
autoload :Strategy, 'whoops_logger/strategy'
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_accessor :strategies, :config
|
14
|
+
|
15
|
+
# @overload notify(raw_data)
|
16
|
+
# Notify using the default basic strategy
|
17
|
+
# @param [Hash] raw_data the raw_data expected by the basic strategy, used by strategy to build message
|
18
|
+
# @overload notify(strategy_name, raw_data)
|
19
|
+
# @param [Symbol, String] strategy_name
|
20
|
+
# @param [Hash] raw_data same as above
|
21
|
+
def notify(strategy_name, raw_data = {})
|
22
|
+
if strategy_name.is_a? Hash
|
23
|
+
notify("default::basic", strategy_name)
|
24
|
+
else
|
25
|
+
message_creator = MessageCreator.new(strategies[strategy_name], raw_data)
|
26
|
+
message_creator.create!
|
27
|
+
send_message(message_creator.message) unless message_creator.ignore_message?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def send_message(message)
|
32
|
+
Sender.new(WhoopsLogger.config.to_hash).send_message(message.to_hash)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.config
|
37
|
+
@config ||= Configuration.new
|
38
|
+
end
|
39
|
+
|
40
|
+
self.strategies = {}
|
41
|
+
end
|
42
|
+
|
43
|
+
Dir[File.join(File.dirname(__FILE__),"whoops_logger/strategies/*.rb")].each do |strategy_file|
|
44
|
+
require strategy_file
|
45
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
describe "WhoopsLogger::Configuration" do
|
2
|
+
describe "#set" do
|
3
|
+
before(:each) {
|
4
|
+
@real_config = WhoopsLogger.config.to_hash
|
5
|
+
WhoopsLogger::Configuration::OPTIONS.each do |option|
|
6
|
+
WhoopsLogger.config.send("#{option}=", nil) if WhoopsLogger.config.respond_to?("#{option}=".to_sym)
|
7
|
+
end
|
8
|
+
}
|
9
|
+
after(:each) {
|
10
|
+
WhoopsLogger.config.set(@real_config)
|
11
|
+
}
|
12
|
+
|
13
|
+
let(:config_path) { File.join(File.dirname(__FILE__), "fixtures/whoops_logger.yml") }
|
14
|
+
it "should set the config from a yaml filename" do
|
15
|
+
WhoopsLogger.config.set(config_path)
|
16
|
+
WhoopsLogger.config.host.should == "whoops.com"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should set the config from a file" do
|
20
|
+
WhoopsLogger.config.set(File.open(config_path))
|
21
|
+
WhoopsLogger.config.host.should == "whoops.com"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should set the config from a hash" do
|
25
|
+
WhoopsLogger.config.set({
|
26
|
+
:host => "whoops.com",
|
27
|
+
})
|
28
|
+
WhoopsLogger.config.host.should == "whoops.com"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should allow string keys" do
|
32
|
+
WhoopsLogger.config.set({
|
33
|
+
"host" => "whoops.com",
|
34
|
+
})
|
35
|
+
WhoopsLogger.config.host.should == "whoops.com"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
:host: whoops.com
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "WhoopsLogger::MessageCreator" do
|
4
|
+
describe "#initialize" do
|
5
|
+
it "should raise an exception if strategy is nil" do
|
6
|
+
lambda{WhoopsLogger::MessageCreator.new(nil, {})}.should raise_exception(ArgumentError)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should raise an exception if strategy argument does not respond to call" do
|
10
|
+
lambda{WhoopsLogger::MessageCreator.new(true, {})}.should raise_exception(ArgumentError)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should not raise an exception if strategy argument responds to call" do
|
14
|
+
lambda{WhoopsLogger::MessageCreator.new(Proc.new{}, {})}.should_not raise_exception
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#create!" do
|
19
|
+
it "should not send message if ignore_message? is true" do
|
20
|
+
strategy = lambda{}
|
21
|
+
message_creator = WhoopsLogger::MessageCreator.new(strategy, {})
|
22
|
+
message_creator.stub(:ignore_message?).and_return(true)
|
23
|
+
|
24
|
+
message_creator.should_not_receive(:send_message)
|
25
|
+
|
26
|
+
message_creator.create!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/sender_spec.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe WhoopsLogger::Sender do
|
4
|
+
describe "#send_message" do
|
5
|
+
it "should send a message to the configured URL when given a config object" do
|
6
|
+
FakeWeb.register_uri(:post, "http://whoops.com/events/", :body => "success")
|
7
|
+
|
8
|
+
sender = WhoopsLogger::Sender.new(WhoopsLogger.config)
|
9
|
+
sender.send_message({:test => true})
|
10
|
+
|
11
|
+
request = FakeWeb.last_request
|
12
|
+
request.body.should =~ /"test"/
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
rspec_dir = File.dirname(__FILE__)
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.join(rspec_dir, '..', 'lib'))
|
4
|
+
$LOAD_PATH.unshift(rspec_dir)
|
5
|
+
require 'rspec'
|
6
|
+
require 'whoops_logger'
|
7
|
+
require 'fakeweb'
|
8
|
+
|
9
|
+
# Requires supporting files with custom matchers and macros, etc,
|
10
|
+
# in ./support/ and its subdirectories.
|
11
|
+
Dir["#{rspec_dir}/support/**/*.rb"].each {|f| require f}
|
12
|
+
|
13
|
+
WhoopsLogger.config.set(File.join(rspec_dir, "fixtures", "whoops_logger.yml"))
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "WhoopsLogger::Strategy" do
|
4
|
+
describe "#initialize" do
|
5
|
+
it "adds a strategy to WhoopsLogger.strategies" do
|
6
|
+
s = WhoopsLogger::Strategy.new(:test)
|
7
|
+
WhoopsLogger.strategies[:test].should == s
|
8
|
+
end
|
9
|
+
|
10
|
+
it "creates empty arrays for ignore criteria and message_builders" do
|
11
|
+
s = WhoopsLogger::Strategy.new(:test)
|
12
|
+
s.ignore_criteria.should == []
|
13
|
+
s.message_builders.should == []
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#add_message_builder" do
|
18
|
+
it "adds a named block" do
|
19
|
+
s = WhoopsLogger::Strategy.new(:test)
|
20
|
+
s.add_message_builder(:add_message) { |message, raw_data| }
|
21
|
+
|
22
|
+
s.message_builders.first.name.should == :add_message
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#add_ignore_criteria" do
|
27
|
+
it "adds a named ignore criteria block" do
|
28
|
+
s = WhoopsLogger::Strategy.new(:test)
|
29
|
+
s.add_ignore_criteria(:ignore_if_empty) { |message| }
|
30
|
+
|
31
|
+
s.ignore_criteria.first.name.should == :ignore_if_empty
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#call" do
|
36
|
+
it "should change the message_creator's 'ignore' attribute to true if any ignore criteria are true" do
|
37
|
+
strategy = WhoopsLogger::Strategy.new(:test)
|
38
|
+
message_creator = WhoopsLogger::MessageCreator.new(strategy, nil)
|
39
|
+
|
40
|
+
strategy.add_ignore_criteria(:always_ignore) do |message|
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
strategy.call(message_creator.message, message_creator.raw_data)
|
45
|
+
message_creator.ignore_message?.should == true
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should modify the message_creator's message according to the message modifiers" do
|
49
|
+
strategy = WhoopsLogger::Strategy.new(:test)
|
50
|
+
message_creator = WhoopsLogger::MessageCreator.new(strategy, {:service => "service"})
|
51
|
+
strategy.add_message_builder(:add_details){ |message, raw_data|
|
52
|
+
message.service = raw_data[:service] + " test"
|
53
|
+
}
|
54
|
+
|
55
|
+
strategy.call(message_creator.message, message_creator.raw_data)
|
56
|
+
|
57
|
+
message_creator.message.service.should == "service test"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#inspect" do
|
62
|
+
it "should list name, message modifier names, and ignore criteria names" do
|
63
|
+
strategy = WhoopsLogger::Strategy.new(:awesome_strategy)
|
64
|
+
message_creator = WhoopsLogger::MessageCreator.new(strategy, nil)
|
65
|
+
|
66
|
+
strategy.add_message_builder(:message1){ }
|
67
|
+
strategy.add_message_builder(:message2){ }
|
68
|
+
|
69
|
+
strategy.add_ignore_criteria(:ignore1){ true }
|
70
|
+
strategy.add_ignore_criteria(:ignore2){ true }
|
71
|
+
|
72
|
+
strategy.inspect.should == "awesome_strategy
|
73
|
+
message builders: message1, message2
|
74
|
+
ignore criteria: ignore1, ignore2"
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "WhoopsLogger" do
|
4
|
+
before(:each) { FakeWeb.clean_registry }
|
5
|
+
|
6
|
+
describe ".strategies" do
|
7
|
+
it "is a hash with keys of strategy names and values of strategy objects" do
|
8
|
+
WhoopsLogger.strategies.each do |key, value|
|
9
|
+
(key.instance_of?(Symbol) || key.instance_of?(String)).should be_true
|
10
|
+
value.should be_a WhoopsLogger::Strategy
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ".config" do
|
16
|
+
it "returns a WhoopsLogger::Configuration object" do
|
17
|
+
WhoopsLogger.config.should be_a(WhoopsLogger::Configuration)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe ".notify" do
|
22
|
+
let(:message_creator){ double(:message_creator, :create! => nil, :message => nil) }
|
23
|
+
|
24
|
+
it "uses the basic strategy if no strategy name is provided" do
|
25
|
+
WhoopsLogger.stub(:send_message)
|
26
|
+
message_creator.stub(:ignore_message?).and_return(false)
|
27
|
+
WhoopsLogger::MessageCreator.should_receive(:new).with(WhoopsLogger.strategies["default::basic"], {}).and_return(message_creator)
|
28
|
+
WhoopsLogger.notify({})
|
29
|
+
end
|
30
|
+
|
31
|
+
it "sends a message when the message_creator is not ignoring the event" do
|
32
|
+
message_creator.should_receive(:ignore_message?).and_return(false)
|
33
|
+
WhoopsLogger::MessageCreator.stub(:new).and_return(message_creator)
|
34
|
+
|
35
|
+
WhoopsLogger.should_receive(:send_message)
|
36
|
+
WhoopsLogger.notify({})
|
37
|
+
end
|
38
|
+
|
39
|
+
it "does not sned a request if the message_creator is ignoring the event" do
|
40
|
+
message_creator.should_receive(:ignore_message?).and_return(true)
|
41
|
+
WhoopsLogger::MessageCreator.stub(:new).and_return(message_creator)
|
42
|
+
|
43
|
+
WhoopsLogger.should_not_receive(:send_message)
|
44
|
+
WhoopsLogger.notify({})
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe ".send_message" do
|
49
|
+
it "should send a message to the configured URL" do
|
50
|
+
FakeWeb.register_uri(:post, "http://whoops.com/events/", :body => "success")
|
51
|
+
WhoopsLogger.notify({})
|
52
|
+
request = FakeWeb.last_request
|
53
|
+
request.body.should =~ /"event"/
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{whoops_logger}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Daniel Higginbotham"]
|
12
|
+
s.date = %q{2011-07-12}
|
13
|
+
s.description = %q{Handles basic notification responsibilities and allows creation of message creation strategies}
|
14
|
+
s.email = %q{daniel@flyingmachinestudios.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"lib/whoops_logger.rb",
|
29
|
+
"lib/whoops_logger/configuration.rb",
|
30
|
+
"lib/whoops_logger/message.rb",
|
31
|
+
"lib/whoops_logger/message_creator.rb",
|
32
|
+
"lib/whoops_logger/sender.rb",
|
33
|
+
"lib/whoops_logger/strategies/basic.rb",
|
34
|
+
"lib/whoops_logger/strategy.rb",
|
35
|
+
"spec/configuration_spec.rb",
|
36
|
+
"spec/fixtures/whoops_logger.yml",
|
37
|
+
"spec/message_creator_spec.rb",
|
38
|
+
"spec/sender_spec.rb",
|
39
|
+
"spec/spec_helper.rb",
|
40
|
+
"spec/strategy_spec.rb",
|
41
|
+
"spec/whoops_logger_spec.rb",
|
42
|
+
"whoops_logger.gemspec"
|
43
|
+
]
|
44
|
+
s.homepage = %q{http://github.com/flyingmachine/whoops_logger}
|
45
|
+
s.licenses = ["MIT"]
|
46
|
+
s.require_paths = ["lib"]
|
47
|
+
s.rubygems_version = %q{1.3.7}
|
48
|
+
s.summary = %q{Handles basic notification responsibilities and allows creation of message creation strategies}
|
49
|
+
s.test_files = [
|
50
|
+
"spec/configuration_spec.rb",
|
51
|
+
"spec/message_creator_spec.rb",
|
52
|
+
"spec/sender_spec.rb",
|
53
|
+
"spec/spec_helper.rb",
|
54
|
+
"spec/strategy_spec.rb",
|
55
|
+
"spec/whoops_logger_spec.rb"
|
56
|
+
]
|
57
|
+
|
58
|
+
if s.respond_to? :specification_version then
|
59
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
60
|
+
s.specification_version = 3
|
61
|
+
|
62
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
63
|
+
s.add_runtime_dependency(%q<json>, [">= 0"])
|
64
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
|
65
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
66
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
67
|
+
s.add_development_dependency(%q<ruby-debug>, [">= 0"])
|
68
|
+
s.add_development_dependency(%q<fakeweb>, [">= 0"])
|
69
|
+
else
|
70
|
+
s.add_dependency(%q<json>, [">= 0"])
|
71
|
+
s.add_dependency(%q<rspec>, ["~> 2.6.0"])
|
72
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
73
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
74
|
+
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
75
|
+
s.add_dependency(%q<fakeweb>, [">= 0"])
|
76
|
+
end
|
77
|
+
else
|
78
|
+
s.add_dependency(%q<json>, [">= 0"])
|
79
|
+
s.add_dependency(%q<rspec>, ["~> 2.6.0"])
|
80
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
81
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
82
|
+
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
83
|
+
s.add_dependency(%q<fakeweb>, [">= 0"])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
metadata
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: whoops_logger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Daniel Higginbotham
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-07-12 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
prerelease: false
|
23
|
+
type: :runtime
|
24
|
+
name: json
|
25
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
version: "0"
|
34
|
+
requirement: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
prerelease: false
|
37
|
+
type: :development
|
38
|
+
name: rspec
|
39
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 23
|
45
|
+
segments:
|
46
|
+
- 2
|
47
|
+
- 6
|
48
|
+
- 0
|
49
|
+
version: 2.6.0
|
50
|
+
requirement: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
prerelease: false
|
53
|
+
type: :development
|
54
|
+
name: bundler
|
55
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 23
|
61
|
+
segments:
|
62
|
+
- 1
|
63
|
+
- 0
|
64
|
+
- 0
|
65
|
+
version: 1.0.0
|
66
|
+
requirement: *id003
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
prerelease: false
|
69
|
+
type: :development
|
70
|
+
name: jeweler
|
71
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 7
|
77
|
+
segments:
|
78
|
+
- 1
|
79
|
+
- 5
|
80
|
+
- 2
|
81
|
+
version: 1.5.2
|
82
|
+
requirement: *id004
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
prerelease: false
|
85
|
+
type: :development
|
86
|
+
name: ruby-debug
|
87
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 3
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
version: "0"
|
96
|
+
requirement: *id005
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
prerelease: false
|
99
|
+
type: :development
|
100
|
+
name: fakeweb
|
101
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
hash: 3
|
107
|
+
segments:
|
108
|
+
- 0
|
109
|
+
version: "0"
|
110
|
+
requirement: *id006
|
111
|
+
description: Handles basic notification responsibilities and allows creation of message creation strategies
|
112
|
+
email: daniel@flyingmachinestudios.com
|
113
|
+
executables: []
|
114
|
+
|
115
|
+
extensions: []
|
116
|
+
|
117
|
+
extra_rdoc_files:
|
118
|
+
- LICENSE.txt
|
119
|
+
- README.rdoc
|
120
|
+
files:
|
121
|
+
- .document
|
122
|
+
- .rspec
|
123
|
+
- Gemfile
|
124
|
+
- Gemfile.lock
|
125
|
+
- LICENSE.txt
|
126
|
+
- README.rdoc
|
127
|
+
- Rakefile
|
128
|
+
- VERSION
|
129
|
+
- lib/whoops_logger.rb
|
130
|
+
- lib/whoops_logger/configuration.rb
|
131
|
+
- lib/whoops_logger/message.rb
|
132
|
+
- lib/whoops_logger/message_creator.rb
|
133
|
+
- lib/whoops_logger/sender.rb
|
134
|
+
- lib/whoops_logger/strategies/basic.rb
|
135
|
+
- lib/whoops_logger/strategy.rb
|
136
|
+
- spec/configuration_spec.rb
|
137
|
+
- spec/fixtures/whoops_logger.yml
|
138
|
+
- spec/message_creator_spec.rb
|
139
|
+
- spec/sender_spec.rb
|
140
|
+
- spec/spec_helper.rb
|
141
|
+
- spec/strategy_spec.rb
|
142
|
+
- spec/whoops_logger_spec.rb
|
143
|
+
- whoops_logger.gemspec
|
144
|
+
has_rdoc: true
|
145
|
+
homepage: http://github.com/flyingmachine/whoops_logger
|
146
|
+
licenses:
|
147
|
+
- MIT
|
148
|
+
post_install_message:
|
149
|
+
rdoc_options: []
|
150
|
+
|
151
|
+
require_paths:
|
152
|
+
- lib
|
153
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
154
|
+
none: false
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
hash: 3
|
159
|
+
segments:
|
160
|
+
- 0
|
161
|
+
version: "0"
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
|
+
none: false
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
hash: 3
|
168
|
+
segments:
|
169
|
+
- 0
|
170
|
+
version: "0"
|
171
|
+
requirements: []
|
172
|
+
|
173
|
+
rubyforge_project:
|
174
|
+
rubygems_version: 1.3.7
|
175
|
+
signing_key:
|
176
|
+
specification_version: 3
|
177
|
+
summary: Handles basic notification responsibilities and allows creation of message creation strategies
|
178
|
+
test_files:
|
179
|
+
- spec/configuration_spec.rb
|
180
|
+
- spec/message_creator_spec.rb
|
181
|
+
- spec/sender_spec.rb
|
182
|
+
- spec/spec_helper.rb
|
183
|
+
- spec/strategy_spec.rb
|
184
|
+
- spec/whoops_logger_spec.rb
|