errplane 0.2.0 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -40,7 +40,7 @@ This will automatically pull your API key from the Rails initializer and notify
40
40
  Resque Integration With Multiple Failure Backends
41
41
  -------------------------------------------------
42
42
 
43
- This gem also supports notifications from failed Resque jobs. Just add the following to the an initializer:
43
+ This gem also supports notifications from failed Resque jobs. Just add the following to the an initializer, such as `config/initializers/resque.rb`:
44
44
 
45
45
  require 'resque/failure/multiple'
46
46
  require 'resque/failure/redis'
@@ -49,7 +49,21 @@ This gem also supports notifications from failed Resque jobs. Just add the follo
49
49
  Resque::Failure::Multiple.classes = [Resque::Failure::Redis, Resque::Failure::Errplane]
50
50
  Resque::Failure.backend = Resque::Failure::Multiple
51
51
 
52
- Don't forget that you can refer to `config/initializers/errplane.rb` for the relevant configuration values.
52
+ Assuming this is running from within a normal Rails projects, the values provided in `config/initializers/errplane.rb` will make sure that the Resque backend is set up correctly.
53
+
54
+ Rails Remote Logger
55
+ -------------------
56
+
57
+ This gem supports remotely sending rails logs to Errplane to be alerted and monitored in our web console. To use this, run the generator above and uncomment the following line in `config/initializers/errplane.rb`.
58
+
59
+ # config.syslogd_port = "<port here>"
60
+
61
+ Chef Support
62
+ ------------
63
+
64
+ We currently only support Exception notification on Chef, we will be releasing remote logging for chef soon. See our wiki(https://github.com/errplane/docs/wiki/Chef-Integration) for details.
65
+
66
+
53
67
 
54
68
  Contributing
55
69
  ------------
data/lib/errplane.rb CHANGED
@@ -42,17 +42,17 @@ module Errplane
42
42
  configuration.logger.info("\nEnvironment: #{ENV.to_hash}") if configuration.debug?
43
43
 
44
44
  transmitter.relay(black_box) unless ignorable_exception?(e)
45
- rescue
46
- configuration.logger.info("[Errplane] Something went terribly wrong. Exception failed to take off.")
45
+ rescue => e
46
+ configuration.logger.info("[Errplane] Something went terribly wrong. Exception failed to take off. 2-" + e.inspect)
47
47
  end
48
48
  end
49
49
 
50
- def transmit(e)
50
+ def transmit(e, env = {})
51
51
  begin
52
52
  black_box = if e.is_a?(String)
53
- assemble_black_box_for(Exception.new(e))
53
+ assemble_black_box_for(Exception.new(e), env)
54
54
  else
55
- assemble_black_box_for(e)
55
+ assemble_black_box_for(e, env)
56
56
  end
57
57
 
58
58
  configuration.logger.info("\nTransmitter: #{transmitter.inspect}") if configuration.debug?
@@ -60,8 +60,8 @@ module Errplane
60
60
  configuration.logger.info("\nIgnorable Exception? #{ignorable_exception?(e)}") if configuration.debug?
61
61
  configuration.logger.info("\nEnvironment: #{ENV.to_hash}") if configuration.debug?
62
62
  transmitter.relay(black_box)
63
- rescue
64
- configuration.logger.info("[Errplane] Something went terribly wrong. Exception failed to take off.")
63
+ rescue => e
64
+ configuration.logger.info("[Errplane] Something went terribly wrong. Exception failed to take off. 1-" + e.inspect)
65
65
  end
66
66
  end
67
67
 
@@ -71,6 +71,7 @@ module Errplane
71
71
 
72
72
  private
73
73
  def assemble_black_box_for(e, opts = {})
74
+ opts ||= {}
74
75
  configuration.logger.info("OPTS: #{opts}")
75
76
  e = e.continued_exception if e.respond_to?(:continued_exception)
76
77
  e = e.original_exception if e.respond_to?(:original_exception)
@@ -7,18 +7,30 @@ Capistrano::Configuration.instance(:must_exist).load do
7
7
  namespace :deploy do
8
8
  desc 'Notify Errplane of the deployment'
9
9
  task :notify_errplane, :except => {:no_release => true} do
10
+ set(:deploying_user) { `whoami`.strip }
11
+ set(:deploying_user_name) { `bash -c 'git config --get user.name'`.strip }
12
+ set(:deploying_user_email) { `bash -c 'git config --get user.email'`.strip }
13
+
10
14
  puts "Notifying Errplane of the deployment.."
11
15
  framework_env = fetch(:rails_env, fetch(:errplane_env, 'production'))
12
16
  load File.join(Dir.pwd, "config/initializers/errplane.rb")
17
+
18
+ Errplane.configuration.logger = Logger.new("/dev/null")
13
19
  Errplane.configuration.rails_environment = framework_env
14
20
 
15
21
  deploy_options = {
16
22
  :environment => framework_env,
17
23
  :revision => current_revision,
18
24
  :repository => repository,
25
+ :branch => (branch rescue nil),
19
26
  :scm => scm,
20
- :host => host
27
+ :host => host,
28
+ :remote_user => (user rescue nil),
29
+ :local_user => deploying_user,
30
+ :scm_user_name => deploying_user_name,
31
+ :scm_user_email => deploying_user_email
21
32
  }
33
+
22
34
  Errplane::Transmitter.new.relay(deploy_options, true)
23
35
  puts 'Done.'
24
36
  end
@@ -2,9 +2,11 @@ module Errplane
2
2
  class Configuration
3
3
  attr_accessor :api_key
4
4
  attr_accessor :api_host
5
+ attr_accessor :app_host
5
6
  attr_accessor :application_id
6
7
  attr_accessor :application_name
7
8
  attr_accessor :application_root
9
+ attr_accessor :syslogd_port
8
10
 
9
11
  attr_accessor :logger
10
12
  attr_accessor :rails_environment
@@ -20,6 +22,7 @@ module Errplane
20
22
 
21
23
  DEFAULTS = {
22
24
  :api_host => "api.errplane.com",
25
+ :app_host => "app.errplane.com",
23
26
  :ignored_exceptions => %w{ActiveRecord::RecordNotFound
24
27
  ActionController::RoutingError},
25
28
  :ignored_environments => %w{development test cucumber selenium}
@@ -27,6 +30,7 @@ module Errplane
27
30
 
28
31
  def initialize
29
32
  @api_host = DEFAULTS[:api_host]
33
+ @app_host = DEFAULTS[:app_host]
30
34
  @ignored_exceptions = DEFAULTS[:ignored_exceptions].dup
31
35
  @ignored_environments = DEFAULTS[:ignored_environments].dup
32
36
  @debug = false
@@ -39,5 +43,31 @@ module Errplane
39
43
  def ignore_current_environment?
40
44
  self.ignored_environments.include?(self.rails_environment)
41
45
  end
46
+
47
+ def get_logport
48
+ puts "Acquiring port information from errplane"
49
+ http = initialize_http_connection
50
+ response = begin
51
+ url = "/api/v1/syslogds.txt?api_key=#{@api_key}"
52
+ http.get(url)
53
+ rescue Exception => e
54
+ puts e
55
+ end
56
+
57
+
58
+ case response
59
+ when Net::HTTPSuccess
60
+ # Success
61
+ response.body
62
+ else
63
+ # Failure
64
+ ""
65
+ end
66
+ end
67
+
68
+ private
69
+ def initialize_http_connection
70
+ Net::HTTP.new(@app_host, "80")
71
+ end
42
72
  end
43
73
  end
@@ -0,0 +1,65 @@
1
+ #Forked from https://github.com/morgoth/airbrake_handler/blob/master/lib/airbrake_handler.rb
2
+ #Apache license please see above url for more details
3
+
4
+ require "chef/handler"
5
+ require "errplane"
6
+ require 'logger'
7
+
8
+ class ErrplaneChefHandler < Chef::Handler
9
+
10
+ attr_accessor :options, :api_key, :ignore, :notify_host, :environment
11
+
12
+ def initialize(options = {})
13
+ @api_key = options.delete(:api_key)
14
+ @ignore = options.delete(:ignore) || []
15
+ @options = options
16
+ @environment = options.delete(:env) || "production"
17
+ end
18
+
19
+ def report
20
+ if run_status.failed? && !ignore_exception?(run_status.exception)
21
+ Chef::Log.error("Creating Errplane exception report")
22
+
23
+ excep = run_status.exception
24
+ setup_errplane
25
+ Errplane.transmit(excep, errplane_params)
26
+ end
27
+ end
28
+
29
+ def ignore_exception?(exception)
30
+ ignore.any? do |ignore_case|
31
+ ignore_case[:class] == exception.class.name && (!ignore_case.key?(:message) || !!ignore_case[:message].match(exception.message))
32
+ end
33
+ end
34
+
35
+ def errplane_params
36
+ {
37
+ :notifier_name => "Chef Errplane Notifier",
38
+ :notifier_version => Errplane::VERSION,
39
+ :notifier_url => "https://github.com/errplane/gem",
40
+ :component => run_status.node.name,
41
+ :url => nil,
42
+ :environment => @environment,
43
+ :params => {
44
+ :start_time => run_status.start_time,
45
+ :end_time => run_status.end_time,
46
+ :elapsed_time => run_status.elapsed_time,
47
+ :run_list => run_status.node.run_list.to_s
48
+ }
49
+ }.merge(options)
50
+ end
51
+
52
+ def setup_errplane
53
+ raise ArgumentError.new("You must specify Errplane api key") unless api_key
54
+ Errplane.configure do |config|
55
+ config.api_key = api_key
56
+ config.application_id = "chef"
57
+ config.application_name = "chef"
58
+ # config.syslogd_port = "4445"
59
+ config.logger = Chef::Log
60
+ #config.logger = Logger.new(STDOUT)
61
+ config.debug = false
62
+ config.rails_environment = @environment
63
+ end
64
+ end
65
+ end
@@ -10,7 +10,7 @@ module Errplane
10
10
  controller = env["action_controller.instance"]
11
11
  Errplane.configuration.logger.info("Controller: #{controller}")
12
12
  Errplane.configuration.logger.info("Request Data: #{controller.try(:errplane_request_data)}")
13
- Errplane.transmit_unless_ignorable(e, controller.try(:errplane_request_data))
13
+ Errplane.transmit_unless_ignorable(e, controller.try(:errplane_request_data))
14
14
  render_exception_without_errplane(env, e)
15
15
  end
16
16
  end
@@ -0,0 +1,54 @@
1
+ module Errplane
2
+ class UdpLogger
3
+ def initialize(port)
4
+ @host = "syslogd.errplane.com"
5
+ @port = port
6
+
7
+ @syslog_p = SyslogProto::Packet.new
8
+
9
+ local_hostname = (Socket.gethostname rescue `hostname`.chomp)
10
+ local_hostname = 'localhost' if local_hostname.nil? || local_hostname.empty?
11
+ @syslog_p.hostname = local_hostname
12
+
13
+ @syslog_p.facility = 'user'
14
+ @syslog_p.severity = 'notice'
15
+ @udpsocket = UDPSocket.new
16
+ puts "Setting up Errplane remote logger on port -#{@host}:#{@port}"
17
+ end
18
+
19
+ def write(message)
20
+ message.split(/\r?\n/).each do |line|
21
+ begin
22
+ next if line =~ /^\s*$/
23
+ pak = @syslog_p.dup
24
+ pak.msg = line
25
+ @udpsocket.send(pak.assemble, 0, @host, @port)
26
+ rescue => e
27
+ puts e
28
+ puts e.backtrace
29
+ #ignore errors
30
+ end
31
+ end
32
+ end
33
+
34
+ def close
35
+ @udpsocket.close
36
+ end
37
+ end
38
+ end
39
+
40
+ begin
41
+ if( Errplane.configuration.syslogd_port && Errplane.configuration.syslogd_port != "")
42
+ require "uri"
43
+ require 'socket'
44
+ require 'errplane/syslogproto'
45
+
46
+ logger = Logger.new(Errplane::UdpLogger.new( Errplane.configuration.syslogd_port.to_i))
47
+ logger.level = Logger::INFO
48
+
49
+ logger.error "TEST"
50
+ Rails.logger = Rails.application.config.logger = ActionController::Base.logger = Rails.cache.logger = logger
51
+ end
52
+ rescue => e
53
+ puts "Failed to setup remote logger for Errplane! -#{e}"
54
+ end
@@ -11,6 +11,11 @@ module Errplane
11
11
  exit
12
12
  end
13
13
 
14
+ Errplane.configuration.syslogd_port = Errplane.configuration.get_logport
15
+ if(Errplane.configuration.syslogd_port && Errplane.configuration.syslogd_port.to_s != "")
16
+ require 'errplane/rails/udp_logger'
17
+ end
18
+
14
19
  Errplane.configure do |config|
15
20
  config.ignored_environments = []
16
21
  end
@@ -75,6 +80,10 @@ module Errplane
75
80
  config.framework_version = ::Rails::VERSION::STRING
76
81
  end
77
82
 
83
+ if(Errplane.configuration.syslogd_port && Errplane.configuration.syslogd_port.to_s != "")
84
+ require 'errplane/rails/udp_logger'
85
+ end
86
+
78
87
  ActiveSupport.on_load(:action_controller) do
79
88
  require 'errplane/rails/air_traffic_controller'
80
89
  include Errplane::Rails::AirTrafficController
@@ -11,7 +11,7 @@ module Resque
11
11
  ::Errplane.transmit_unless_ignorable(exception, :custom_data => {
12
12
  :resque => {
13
13
  :payload => payload,
14
- :worker => worker,
14
+ :worker => worker.to_s,
15
15
  :queue => queue
16
16
  }
17
17
  })
@@ -0,0 +1,7 @@
1
+ $:.unshift File.expand_path(File.dirname(File.expand_path(__FILE__)))
2
+ require 'syslogproto/common'
3
+ require 'syslogproto/packet'
4
+ require 'syslogproto/logger'
5
+ require 'syslogproto/parser'
6
+
7
+ #THIS was forked from https://github.com/jakedouglas/syslog
@@ -0,0 +1,81 @@
1
+ module SyslogProto
2
+
3
+ # These hashes stolen from Syslog.pm
4
+
5
+ FACILITIES = {
6
+ 'kern' => 0,
7
+ 'user' => 1,
8
+ 'mail' => 2,
9
+ 'daemon' => 3,
10
+ 'auth' => 4,
11
+ 'syslog' => 5,
12
+ 'lpr' => 6,
13
+ 'news' => 7,
14
+ 'uucp' => 8,
15
+ 'cron' => 9,
16
+ 'authpriv' => 10,
17
+ 'ftp' => 11,
18
+ 'ntp' => 12,
19
+ 'audit' => 13,
20
+ 'alert' => 14,
21
+ 'at' => 15,
22
+ 'local0' => 16,
23
+ 'local1' => 17,
24
+ 'local2' => 18,
25
+ 'local3' => 19,
26
+ 'local4' => 20,
27
+ 'local5' => 21,
28
+ 'local6' => 22,
29
+ 'local7' => 23
30
+ }
31
+
32
+ FACILITY_INDEX = {
33
+ 0 => 'kern',
34
+ 1 => 'user',
35
+ 2 => 'mail',
36
+ 3 => 'daemon',
37
+ 4 => 'auth',
38
+ 5 => 'syslog',
39
+ 6 => 'lpr',
40
+ 7 => 'news',
41
+ 8 => 'uucp',
42
+ 9 => 'cron',
43
+ 10 => 'authpriv',
44
+ 11 => 'ftp',
45
+ 12 => 'ntp',
46
+ 13 => 'audit',
47
+ 14 => 'alert',
48
+ 15 => 'at',
49
+ 16 => 'local0',
50
+ 17 => 'local1',
51
+ 18 => 'local2',
52
+ 19 => 'local3',
53
+ 20 => 'local4',
54
+ 21 => 'local5',
55
+ 22 => 'local6',
56
+ 23 => 'local7'
57
+ }
58
+
59
+ SEVERITIES = {
60
+ 'emerg' => 0,
61
+ 'alert' => 1,
62
+ 'crit' => 2,
63
+ 'err' => 3,
64
+ 'warn' => 4,
65
+ 'notice' => 5,
66
+ 'info' => 6,
67
+ 'debug' => 7
68
+ }
69
+
70
+ SEVERITY_INDEX = {
71
+ 0 => 'emerg',
72
+ 1 => 'alert',
73
+ 2 => 'crit',
74
+ 3 => 'err',
75
+ 4 => 'warn',
76
+ 5 => 'notice',
77
+ 6 => 'info',
78
+ 7 => 'debug'
79
+ }
80
+
81
+ end
@@ -0,0 +1,24 @@
1
+ module SyslogProto
2
+
3
+ class Logger
4
+
5
+ def initialize(hostname, facility)
6
+ @packet = Packet.new
7
+ @packet.hostname = hostname
8
+ @packet.facility = facility
9
+ end
10
+
11
+ SEVERITIES.each do |k,v|
12
+ define_method(k) do |*args|
13
+ msg = args.shift
14
+ raise ArgumentError.new "MSG may not be omitted" unless msg and msg.length > 0
15
+ p = @packet.dup
16
+ p.severity = k
17
+ p.msg = msg
18
+ p.assemble
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,107 @@
1
+ module SyslogProto
2
+
3
+ class Packet
4
+
5
+ attr_reader :facility, :severity, :hostname
6
+ attr_accessor :time, :msg
7
+
8
+ def to_s
9
+ assemble
10
+ end
11
+
12
+ def assemble
13
+ unless @hostname and @facility and @severity
14
+ return "I AM A JUNK PACKET CUZ MY USER DIDNT SET ME"
15
+ end
16
+ data = "<#{pri}>#{generate_timestamp} #{@hostname} #{@msg}"
17
+ while data.bytesize > 1024
18
+ data = data[0..(data.length-2)]
19
+ end
20
+ data
21
+ end
22
+
23
+ def facility=(f)
24
+ if f.is_a? Integer
25
+ if (0..23).include?(f)
26
+ @facility = f
27
+ else
28
+ raise ArgumentError.new "Facility must be within 0-23"
29
+ end
30
+ elsif f.is_a? String
31
+ if facility = FACILITIES[f]
32
+ @facility = facility
33
+ else
34
+ raise ArgumentError.new "'#{f}' is not a designated facility"
35
+ end
36
+ else
37
+ raise ArgumentError.new "Facility must be a designated number or string"
38
+ end
39
+ end
40
+
41
+ def severity=(s)
42
+ if s.is_a? Integer
43
+ if (0..7).include?(s)
44
+ @severity = s
45
+ else
46
+ raise ArgumentError.new "Severity must be within 0-7"
47
+ end
48
+ elsif s.is_a? String
49
+ if severity = SEVERITIES[s]
50
+ @severity = severity
51
+ else
52
+ raise ArgumentError.new "'#{s}' is not a designated severity"
53
+ end
54
+ else
55
+ raise ArgumentError.new "Severity must be a designated number or string"
56
+ end
57
+ end
58
+
59
+ def hostname=(h)
60
+ unless h and h.is_a? String and h.length > 0
61
+ raise ArgumentError.new("Hostname may not be omitted")
62
+ end
63
+ if h =~ /\s/
64
+ raise ArgumentError.new("Hostname may not contain spaces")
65
+ end
66
+ if h =~ /[^\x21-\x7E]/
67
+ raise ArgumentError.new("Hostname may only contain ASCII characters 33-126")
68
+ end
69
+ @hostname = h
70
+ end
71
+
72
+ def facility_name
73
+ FACILITY_INDEX[@facility]
74
+ end
75
+
76
+ def severity_name
77
+ SEVERITY_INDEX[@severity]
78
+ end
79
+
80
+ def pri
81
+ (@facility * 8) + @severity
82
+ end
83
+
84
+ def pri=(p)
85
+ unless p.is_a? Integer and (0..191).include?(p)
86
+ raise ArgumentError.new "PRI must be a number between 0 and 191"
87
+ end
88
+ @facility = p / 8
89
+ @severity = p - (@facility * 8)
90
+ end
91
+
92
+ def generate_timestamp
93
+ time = @time || Time.now
94
+ # The timestamp format requires that a day with fewer than 2 digits have
95
+ # what would normally be a preceding zero, be instead an extra space.
96
+ day = time.strftime("%d")
97
+ day = day.sub(/^0/, ' ') if day =~ /^0\d/
98
+ time.strftime("%b #{day} %H:%M:%S")
99
+ end
100
+
101
+ SEVERITIES.each do |k,v|
102
+ define_method("#{k}?") {SEVERITIES[k] == @severity}
103
+ end
104
+
105
+ end
106
+
107
+ end
@@ -0,0 +1,51 @@
1
+ require 'time'
2
+
3
+ module SyslogProto
4
+
5
+ def self.parse(msg, origin=nil)
6
+ packet = Packet.new
7
+ original_msg = msg.dup
8
+ pri = parse_pri(msg)
9
+ if pri and (pri = pri.to_i).is_a? Integer and (0..191).include?(pri)
10
+ packet.pri = pri
11
+ else
12
+ # If there isn't a valid PRI, treat the entire message as content
13
+ packet.pri = 13
14
+ packet.time = Time.now
15
+ packet.hostname = origin || 'unknown'
16
+ packet.msg = original_msg
17
+ return packet
18
+ end
19
+ time = parse_time(msg)
20
+ if time
21
+ packet.time = Time.parse(time)
22
+ else
23
+ packet.time = Time.now
24
+ end
25
+ hostname = parse_hostname(msg)
26
+ packet.hostname = hostname || origin
27
+ packet.msg = msg
28
+ packet
29
+ end
30
+
31
+ private
32
+
33
+ def self.parse_pri(msg)
34
+ pri = msg.slice!(/<(\d\d?\d?)>/)
35
+ pri = pri.slice(/\d\d?\d?/) if pri
36
+ if !pri or (pri =~ /^0/ and pri !~ /^0$/)
37
+ return nil
38
+ else
39
+ return pri
40
+ end
41
+ end
42
+
43
+ def self.parse_time(msg)
44
+ msg.slice!(/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\s|[1-9])\d\s\d\d:\d\d:\d\d\s/)
45
+ end
46
+
47
+ def self.parse_hostname(msg)
48
+ msg.slice!(/^[\x21-\x7E]+\s/).rstrip
49
+ end
50
+
51
+ end
@@ -1,3 +1,3 @@
1
1
  module Errplane
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.3"
3
3
  end
@@ -1,4 +1,7 @@
1
1
  Errplane.configure do |config|
2
2
  config.api_key = "<%= api_key %>"
3
3
  config.application_id = "<%= application_id %>"
4
+ #uncomment this if you want to push rails logs to errplane also
5
+ #config.syslogd_port = "<%= Errplane.configuration.get_logport %>"
4
6
  end
7
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: errplane
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-03 00:00:00.000000000 Z
12
+ date: 2012-07-05 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: This gem provides exception reporting with Errplane for Rails 3.x applications.
15
15
  email:
@@ -29,12 +29,19 @@ files:
29
29
  - lib/errplane/black_box.rb
30
30
  - lib/errplane/capistrano.rb
31
31
  - lib/errplane/configuration.rb
32
+ - lib/errplane/errplane_chef_handler.rb
32
33
  - lib/errplane/rack.rb
33
34
  - lib/errplane/rails/air_traffic_controller.rb
34
35
  - lib/errplane/rails/middleware/hijack_render_exception.rb
36
+ - lib/errplane/rails/udp_logger.rb
35
37
  - lib/errplane/railtie.rb
36
38
  - lib/errplane/resque.rb
37
39
  - lib/errplane/sinatra.rb
40
+ - lib/errplane/syslogproto.rb
41
+ - lib/errplane/syslogproto/common.rb
42
+ - lib/errplane/syslogproto/logger.rb
43
+ - lib/errplane/syslogproto/packet.rb
44
+ - lib/errplane/syslogproto/parser.rb
38
45
  - lib/errplane/transmitter.rb
39
46
  - lib/errplane/version.rb
40
47
  - lib/rails/generators/errplane/errplane_generator.rb
@@ -74,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
81
  version: '0'
75
82
  requirements: []
76
83
  rubyforge_project: errplane
77
- rubygems_version: 1.8.24
84
+ rubygems_version: 1.8.19
78
85
  signing_key:
79
86
  specification_version: 3
80
87
  summary: Rails exception reporting for Errplane.