project_106 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in project_106.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 WeboniseLab
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # Project106
2
+
3
+ Project 106 is a errors and exception tracking system
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'project_106'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ ## Usage
16
+
17
+ Go to Terminal and Run
18
+
19
+ project_106
20
+
21
+ This will install node_js in your system
22
+ Skip this if you have node js already install.
23
+
24
+
25
+ Then run
26
+
27
+ rails generate project106:install yourapikey
28
+
29
+ This will add issential files to your rails app.
30
+
31
+ ## Contributing
32
+
33
+ 1. Fork it
34
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
35
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
36
+ 4. Push to the branch (`git push origin my-new-feature`)
37
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,7 @@
1
+ module Project106
2
+ class ErrorController < ::ApplicationController
3
+ def routing
4
+ render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
5
+ end
6
+ end
7
+ end
data/bin/project_106 ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/project_106
2
+
3
+ require "project_106"
4
+ Project106.install_nodejs
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ match '*a', :to => 'project106/error#routing'
3
+ end
@@ -0,0 +1,46 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/named_base'
3
+
4
+ module Project106
5
+ class InstallGenerator < Rails::Generators::Base
6
+ argument :access_token, :type => :string, :banner => 'access_token', :default => :use_env_sentinel
7
+
8
+ source_root File.expand_path("../templates", __FILE__)
9
+
10
+ def create_initializer
11
+ say "creating initializer..."
12
+ if access_token_configured?
13
+ say "It looks like you've already configured Project106."
14
+ say "To re-create the config file, remove it first: config/initializers/project_106.rb"
15
+ exit
16
+ end
17
+
18
+ if access_token === :use_env_sentinel
19
+ say "Generator run without an access token; assuming you want to configure using an environment variable."
20
+ say "You'll need to add an environment variable PROJECT106_ACCESS_TOKEN with your access token:"
21
+ say "\n$ export PROJECT106_ACCESS_TOKEN=yourtokenhere"
22
+ say "\nIf that's not what you wanted to do:"
23
+ say "\n$ rm config/initializers/project_106.rb"
24
+ say "$ rails generate project106:install yourtokenhere"
25
+ say "\n"
26
+ else
27
+ say "access token: " << access_token
28
+ end
29
+
30
+ template 'initializer.rb', 'config/initializers/project_106.rb',
31
+ :assigns => { :access_token => access_token_expr }
32
+ end
33
+
34
+ def access_token_expr
35
+ if access_token === :use_env_sentinel
36
+ "ENV['PROJECT106_ACCESS_TOKEN']"
37
+ else
38
+ "'#{access_token}'"
39
+ end
40
+ end
41
+
42
+ def access_token_configured?
43
+ File.exists?('config/initializers/project_106.rb')
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ Project106.configure do |config|
2
+ config.access_token = <%= access_token_expr %>
3
+ end
@@ -0,0 +1,54 @@
1
+ var http = require('http');
2
+
3
+ // catch the data from command line argument
4
+ var data = process.argv[2]
5
+
6
+ // parsing data
7
+ jdata = JSON.parse(data);
8
+
9
+ // create the JSON object
10
+ jsonObject = JSON.stringify(jdata);
11
+
12
+ // prepare the header
13
+ var postheaders = {
14
+     'Content-Type' : 'application/json',
15
+     'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
16
+ };
17
+
18
+ // the post options
19
+ var optionspost = {
20
+     host : 'beta.erreport.io',
21
+     path : '/api/v1/error_reports',
22
+     method : 'POST',
23
+     headers : postheaders
24
+ };
25
+
26
+ console.info('Options prepared:');
27
+ console.info(optionspost);
28
+ console.info('Do the POST call');
29
+
30
+ // do the POST call
31
+ var reqPost = http.request(optionspost, function(res) {
32
+     console.log("statusCode: ", res.statusCode);
33
+   console.log("headers: ", res.headers);
34
+  
35
+     res.on('data', function(d) {
36
+         console.info('POST result:\n');
37
+ data = JSON.parse(d)
38
+ console.error('\n[Project-106] Response status');
39
+         console.error(data['status']);
40
+ console.error('\n[Project-106] Response Message');
41
+         console.error(data['message']);
42
+         console.info('\n\nPOST completed');
43
+ console.error("\n\n[Project-106] Exception Reporting Finished to Project-106 server using node js");
44
+     });
45
+ });
46
+  
47
+ // write the json data
48
+ reqPost.write(jsonObject);
49
+ reqPost.end();
50
+ // handle error
51
+ reqPost.on('error', function(e) {
52
+ console.error("[Project-106] Error while reporting exception to project-106 in node support");
53
+     console.error(e);
54
+ });
@@ -0,0 +1,112 @@
1
+ require 'net/http'
2
+ require "json"
3
+ require "shellwords"
4
+ require "fileutils"
5
+ require 'benchmark'
6
+ require "project_106/version"
7
+ require "project_106/configuration"
8
+ require 'project_106/exception_reporter'
9
+ require 'project_106/log_reporter'
10
+ require 'rails'
11
+ require "project_106/railtie" if defined? Rails
12
+ require "active_support/dependencies"
13
+
14
+ module Project106
15
+ include LogReporter
16
+
17
+ # install nodeJS on client machine
18
+ def self.install_nodejs
19
+ puts "Installing nodejs dependencies\n"
20
+ `sudo apt-get install python-software-properties python g++ make`
21
+ puts "Adding nodejs ppa\n"
22
+ `sudo add-apt-repository ppa:chris-lea/node.js`
23
+ puts "Updating system\n"
24
+ `sudo apt-get update`
25
+ puts "Installing nodeJS\n"
26
+ `sudo apt-get install nodejs`
27
+ puts "NodeJS Installed ...\n"
28
+ end
29
+
30
+ class << self
31
+ attr_writer :configuration
32
+ include LogReporter
33
+
34
+ def configure
35
+ yield(configuration)
36
+ end
37
+
38
+ def configuration
39
+ @configuration ||= Configuration.new
40
+ end
41
+
42
+ # give memory usage of process using unix shell command
43
+ # def get_memory_usage
44
+ # `ps -o rss= -p #{Process.pid}`.to_i
45
+ # end
46
+
47
+ def append_access_token_to_data(data)
48
+ data[:api_key] = configuration.access_token
49
+ data
50
+ end
51
+
52
+ # Making api call to send error report to project-106 server
53
+ def report_exception_to_project_106_server(data)
54
+
55
+ # Append api_key to data
56
+ data = append_access_token_to_data(data)
57
+
58
+ # If handler == node then request data will be pass to nodejs to make api call
59
+ # If handler == ruby then request data will be directly pass through ruby api call
60
+ handler = "node"
61
+ begin
62
+ # benchmarking code
63
+ # Benchmark.bm do |bm|
64
+
65
+ if handler == "node"
66
+ # bm.report("Node") do
67
+
68
+ # before = get_memory_usage
69
+ # report_log "BEFORE: " + before.to_s
70
+
71
+
72
+ # Pass request data to node_handler.js which will make api call to project-106-server
73
+ # Stringifing data
74
+ jdata = data.to_json
75
+ # Get node_handler path
76
+ node_handler = File.join(File.dirname(__FILE__), "node_handler.js")
77
+ report_log "[Project-106] Calling NODE script to send data to project-106 server"
78
+ `node #{node_handler} #{Shellwords.escape(jdata)}`
79
+
80
+ # after = get_memory_usage
81
+ # report_log "AFTER: " + (after).to_s
82
+ # report_log "Node Memory Usage: " + (after-before).to_s
83
+
84
+ # end
85
+ else
86
+ # bm.report("Ruby") do
87
+
88
+ # before = get_memory_usage
89
+ # report_log "BEFORE: " + before.to_s
90
+
91
+ # Ruby api call to pass request data to project-106-server
92
+ report_log "[Project-106] Calling RUBY script to send data to project-106 server"
93
+ url = URI.parse('http://localhost:3000/api/v1/error_reports')
94
+ resp = Net::HTTP.post_form(url, data)
95
+ report_log "[Project-106] Exception Reported to Project-106 server"
96
+ # after = get_memory_usage
97
+ # report_log "AFTER: " + (after).to_s
98
+ # report_log "Ruby Memory Usage: " + (after-before).to_s
99
+
100
+ # end
101
+ end
102
+
103
+ # end
104
+ rescue => e
105
+ report_log "[Project-106] Error reporting exception to Project-106: #{e}"
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ # Require engine
112
+ require "project_106/engine"
@@ -0,0 +1,13 @@
1
+ module Project106
2
+ class Configuration
3
+
4
+ attr_accessor :access_token
5
+ attr_accessor :endpoint
6
+
7
+ DEFAULT_ENDPOINT = 'http://stage106.weboapps.com/api/v1/error_requests/'
8
+
9
+ def initialize
10
+ @endpoint = DEFAULT_ENDPOINT
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module Project106
2
+ class Engine < Rails::Engine; end
3
+ end
@@ -0,0 +1,14 @@
1
+ require 'project_106/log_reporter'
2
+ require 'project_106/request_data_extractor'
3
+
4
+ module Project106
5
+ module ExceptionReporter
6
+ include LogReporter
7
+ include RequestDataExtractor
8
+ def report_exception_to_project_106(env, exception)
9
+ report_log "[Project106] Reporting Exception: #{exception}", :error
10
+ req_data = extract_request_data_from_rack(env, exception)
11
+ Project106.report_exception_to_project_106_server(req_data)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module Project106
2
+ module LogReporter
3
+ # Call to the rails default logger method with message and level
4
+ # level can be error, debug, info, etc
5
+ def report_log(message, level = :debug)
6
+ if defined?(Rails)
7
+ ::Rails.logger.send(level, message)
8
+ else
9
+ puts message
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,37 @@
1
+ module Project106
2
+ module Middleware
3
+ module Rails
4
+ module ShowExceptions
5
+ include ExceptionReporter
6
+
7
+ # catching rails middleware render_exception method call and
8
+ # doing project-106 error catching task and
9
+ # again continue with rails render_exception method
10
+ def render_exception_with_project_106(env, exception)
11
+ key = 'action_dispatch.show_detailed_exceptions'
12
+
13
+ # don't report production exceptions here as it is done below
14
+ # in call_with_project_106() when show_detailed_exception is false
15
+ if not env.has_key?(key) or env[key]
16
+ # sending exception to project-106 to collect exception data
17
+ report_exception_to_project_106(env, exception)
18
+ end
19
+ render_exception_without_project_106(env, exception)
20
+ end
21
+
22
+ def call_with_project_106(env)
23
+ call_without_project_106(env)
24
+ rescue => exception
25
+ # won't reach here if show_detailed_exceptions is true
26
+ report_exception_to_project_106(env, exception)
27
+ raise exception
28
+ end
29
+
30
+ def self.included(base)
31
+ base.send(:alias_method_chain, :call, :project_106)
32
+ base.send(:alias_method_chain, :render_exception, :project_106)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,35 @@
1
+ require 'active_support/all'
2
+ require 'rails'
3
+ require 'project_106/log_reporter'
4
+ require 'project_106/request_data_extractor'
5
+
6
+ module Project106
7
+ class Railtie < Rails::Railtie
8
+ include RequestDataExtractor
9
+ include LogReporter
10
+
11
+ config.after_initialize do
12
+ # Catch uninitialized typed errors in ErrorController#routing
13
+ ActiveSupport::Notifications.subscribe "process_action.action_controller" do |name, start, finish, id, payload|
14
+ if payload[:exception].present?
15
+ elsif payload[:controller] == "Project106::ErrorController"
16
+ req_data = extract_request_data_from_payload(payload)
17
+ Project106.report_exception_to_project_106_server(req_data)
18
+ report_log "[Project-106] Uninitialized Routing Error"
19
+ end
20
+ end
21
+
22
+ # Catch all other rails error except routing error in the same way as rails did
23
+ if defined?(ActionDispatch::DebugExceptions)
24
+ # Rails 3.2.x
25
+ require 'project_106/middleware/rails/show_exceptions'
26
+ ActionDispatch::DebugExceptions.send(:include, Project106::Middleware::Rails::ShowExceptions)
27
+ elsif defined?(ActionDispatch::ShowExceptions)
28
+ # Rails 3.0.x and 3.1.x
29
+ require 'project_106/middleware/rails/show_exceptions'
30
+ ActionDispatch::ShowExceptions.send(:include, Project106::Middleware::Rails::ShowExceptions)
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,134 @@
1
+ module Project106
2
+ module RequestDataExtractor
3
+ # Collecting data from rack to be send to project-106 server
4
+ def extract_request_data_from_rack(env, exception)
5
+ rack_req = Rack::Request.new(env)
6
+ request_params = project_106_request_params(env)
7
+
8
+ get_params = project_106_get_params(rack_req)
9
+ post_params = project_106_post_params(rack_req)
10
+ cookies = project_106_request_cookies(rack_req)
11
+ session = env['rack.session.options']
12
+
13
+ params = request_params.merge(get_params).merge(post_params)
14
+
15
+ # Collect data from rails env.
16
+ request_data = {
17
+ :params => params,
18
+ :url => project_106_url(env),
19
+ :user_ip => project_106_user_ip(env),
20
+ :headers => project_106_headers(env),
21
+ :method => project_106_request_method(env),
22
+ :error => {
23
+ :message => exception.message,
24
+ :backtrace => exception.backtrace,
25
+ :error_controller => params[:controller],
26
+ :error_action => params[:action]
27
+ }
28
+ }
29
+ # Excluding session and cookies from request data
30
+ # :cookies => cookies,
31
+ # :session => session,
32
+
33
+ # Data to be sent to project-106 server through api call in case of rails error except routing
34
+ # sorting out data from request_data which might have extra data.
35
+ # note : remove this once finalize data to be send to project-106 server
36
+ # req_data = {
37
+ # "error_controller" => request_data[:params][:controller],
38
+ # "error_action" => request_data[:params][:action],
39
+ # "error_format" => "Not Assigned",
40
+ # "method" => request_data[:method],
41
+ # "path" => request_data[:url],
42
+ # "error" => "Not Assigned",
43
+ # "error_info" => exception.inspect
44
+ # }
45
+ end
46
+
47
+ # Data to be sent to project-106 server through api call in case of routing error
48
+ def extract_request_data_from_payload(payload)
49
+
50
+ # Note : remove this once finalize data to be send to project-106 server
51
+
52
+ # {
53
+ # "error_controller" => payload[:controller],
54
+ # "error_action" => payload[:action],
55
+ # "error_format" => payload[:format],
56
+ # "method" => payload[:method],
57
+ # "path" => payload[:path],
58
+ # "error" => "routing error",
59
+ # "error_info" => "It may be that the user have misspelled or devs have forgot to ensure the path"
60
+ # }
61
+
62
+ request_data = {
63
+ :params => "",
64
+ :url => payload[:path],
65
+ :user_ip => "",
66
+ :headers => "",
67
+ :method => payload[:method],
68
+ :error => {
69
+ :message => "routing error",
70
+ :backtrace => "",
71
+ :error_controller => payload[:controller],
72
+ :error_action => payload[:action],
73
+ }
74
+ }
75
+ end
76
+
77
+ private
78
+
79
+ # Methods for collecting data required in method "extract_request_data_from_rack"
80
+ # from rack
81
+ def project_106_request_params(env)
82
+ route = ::Rails.application.routes.recognize_path(env['PATH_INFO']) rescue {}
83
+ {
84
+ :controller => route[:controller],
85
+ :action => route[:action],
86
+ :format => route[:format],
87
+ }.merge(env['action_dispatch.request.parameters'] || {})
88
+ end
89
+
90
+ def project_106_get_params(rack_req)
91
+ rack_req.GET
92
+ rescue
93
+ {}
94
+ end
95
+
96
+ def project_106_post_params(rack_req)
97
+ rack_req.POST
98
+ rescue
99
+ {}
100
+ end
101
+
102
+ def project_106_request_cookies(rack_req)
103
+ rack_req.cookies
104
+ rescue
105
+ {}
106
+ end
107
+
108
+ def project_106_url(env)
109
+ scheme = env['rack.url_scheme']
110
+ host = env['HTTP_HOST'] || env['SERVER_NAME']
111
+ path = env['ORIGINAL_FULLPATH'] || env['REQUEST_URI']
112
+ unless path.nil? || path.empty?
113
+ path = '/' + path.to_s if path.to_s.slice(0, 1) != '/'
114
+ end
115
+
116
+ [scheme, '://', host, path].join
117
+ end
118
+
119
+ def project_106_user_ip(env)
120
+ (env['action_dispatch.remote_ip'] || env['HTTP_X_REAL_IP'] || env['HTTP_X_FORWARDED_FOR'] || env['REMOTE_ADDR']).to_s
121
+ end
122
+
123
+ def project_106_headers(env)
124
+ env.keys.grep(/^HTTP_/).map do |header|
125
+ name = header.gsub(/^HTTP_/, '').split('_').map(&:capitalize).join('-')
126
+ { name => env[header] }
127
+ end.inject(:merge)
128
+ end
129
+
130
+ def project_106_request_method(env)
131
+ env['REQUEST_METHOD'] || env[:method]
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,3 @@
1
+ module Project106
2
+ VERSION = "1.0.0"
3
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: project_106
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Webonise Lab
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-04-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: activesupport
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 3.0.0
54
+ - - <
55
+ - !ruby/object:Gem::Version
56
+ version: '4.0'
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: 3.0.0
65
+ - - <
66
+ - !ruby/object:Gem::Version
67
+ version: '4.0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rails
70
+ requirement: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: 3.0.0
76
+ - - <
77
+ - !ruby/object:Gem::Version
78
+ version: '4.0'
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: 3.0.0
87
+ - - <
88
+ - !ruby/object:Gem::Version
89
+ version: '4.0'
90
+ description: Error and Exception Tracking.
91
+ email:
92
+ - apurva@weboniselab.com
93
+ - ketan@weboniselab.com
94
+ executables:
95
+ - project_106
96
+ extensions: []
97
+ extra_rdoc_files: []
98
+ files:
99
+ - app/controllers/project106/error_controller.rb
100
+ - lib/node_handler.js
101
+ - lib/project_106/version.rb
102
+ - lib/project_106/configuration.rb
103
+ - lib/project_106/exception_reporter.rb
104
+ - lib/project_106/request_data_extractor.rb
105
+ - lib/project_106/railtie.rb
106
+ - lib/project_106/middleware/rails/show_exceptions.rb
107
+ - lib/project_106/log_reporter.rb
108
+ - lib/project_106/engine.rb
109
+ - lib/project_106.rb
110
+ - lib/generators/project106/templates/initializer.rb
111
+ - lib/generators/project106/install_generator.rb
112
+ - config/routes.rb
113
+ - LICENSE.txt
114
+ - Rakefile
115
+ - Gemfile
116
+ - README.md
117
+ - bin/project_106
118
+ homepage: http://git.weboniselab.com/webonise-lab/project-106
119
+ licenses:
120
+ - MIT
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ none: false
127
+ requirements:
128
+ - - ! '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ! '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 1.8.24
140
+ signing_key:
141
+ specification_version: 3
142
+ summary: Project 106 is a errors and exception tracking system
143
+ test_files: []
144
+ has_rdoc: