bugloco 0.0.1 → 0.0.2
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 +4 -4
- data/.travis.yml +6 -0
- data/Gemfile +2 -0
- data/README.md +10 -4
- data/bugloco.gemspec +4 -1
- data/lib/bugloco/configuration.rb +16 -0
- data/lib/bugloco/notice.rb +186 -0
- data/lib/bugloco/protobuf/bugloco.pb.rb +110 -36
- data/lib/bugloco/rack.rb +17 -0
- data/lib/bugloco/rails/middleware.rb +22 -0
- data/lib/bugloco/railtie.rb +21 -0
- data/lib/bugloco/version.rb +1 -1
- data/lib/bugloco.rb +60 -17
- data/protobufs/bugloco.proto +56 -19
- data/spec/bugloco/configuration_spec.rb +8 -0
- data/spec/bugloco/notice_spec.rb +217 -0
- data/spec/bugloco_spec.rb +32 -17
- data/spec/spec_helper.rb +27 -0
- metadata +56 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47458d1e986e645aa899ce0f91d9285b36e9c88f
|
4
|
+
data.tar.gz: 27fc2e6fa0eb66513114f8aa4c23ab31f795adcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac1236859a8495ce7f27485fb7169bf585f25ac6eae524d1574b942499e71243645ea32e9f9f5b2e528ab9c943fd375ab15121381a2b2174be4dadf6618f2396
|
7
|
+
data.tar.gz: 7b18d5dbf10f446744fc6793504ec248e082e2e265959290474ac5e42799dc5e8394ac15d56f176d627d7c8e95ed92183c3324a7ea19e8508bb6e5b6fed2001f
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Bugloco
|
1
|
+
# Bugloco [](https://travis-ci.org/bugloco/bugloco-rb) [](https://coveralls.io/r/bugloco/bugloco-rb)
|
2
2
|
|
3
3
|
TODO: Write a gem description
|
4
4
|
|
@@ -6,15 +6,21 @@ TODO: Write a gem description
|
|
6
6
|
|
7
7
|
Add this line to your application's Gemfile:
|
8
8
|
|
9
|
-
|
9
|
+
```
|
10
|
+
gem 'bugloco'
|
11
|
+
```
|
10
12
|
|
11
13
|
And then execute:
|
12
14
|
|
13
|
-
|
15
|
+
```
|
16
|
+
$ bundle
|
17
|
+
```
|
14
18
|
|
15
19
|
Or install it yourself as:
|
16
20
|
|
17
|
-
|
21
|
+
```
|
22
|
+
$ gem install bugloco
|
23
|
+
```
|
18
24
|
|
19
25
|
## Usage
|
20
26
|
|
data/bugloco.gemspec
CHANGED
@@ -21,6 +21,9 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.6"
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "rspec", ">= 3.0.0"
|
24
|
+
spec.add_development_dependency "rack"
|
25
|
+
spec.add_development_dependency "coveralls"
|
26
|
+
spec.add_development_dependency "fakeweb"
|
24
27
|
|
25
|
-
spec.add_dependency "ruby_protobuf"
|
28
|
+
spec.add_dependency "ruby_protobuf", "~> 0.4.11"
|
26
29
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
|
3
|
+
module Bugloco
|
4
|
+
class Configuration < OpenStruct
|
5
|
+
|
6
|
+
def initialize(hash = {})
|
7
|
+
super
|
8
|
+
|
9
|
+
self.api_url = "https://bugloco.com/api/v1/notices"
|
10
|
+
end
|
11
|
+
|
12
|
+
def configured?
|
13
|
+
self.project_id && self.api_key
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require "bugloco/protobuf/bugloco.pb"
|
2
|
+
require "rack"
|
3
|
+
require "socket"
|
4
|
+
|
5
|
+
module Bugloco
|
6
|
+
class Notice
|
7
|
+
|
8
|
+
EXCEPTION_REGEX = /^(?<path>[^:]*):(?<line_number>[0-9]*):in `(?<function_name>[^']*)'$/
|
9
|
+
|
10
|
+
def initialize(exception, options = {})
|
11
|
+
@exception = exception
|
12
|
+
@options = options
|
13
|
+
@rack_env = @options[:rack_env] if @options[:rack_env]
|
14
|
+
@proto_message = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_pb
|
18
|
+
@pb ||= proto_message.serialize_to_string
|
19
|
+
end
|
20
|
+
|
21
|
+
def proto_message
|
22
|
+
return @proto_message unless @proto_message.nil?
|
23
|
+
|
24
|
+
@proto_message = Bugloco::Proto::Notice.new
|
25
|
+
|
26
|
+
load_company
|
27
|
+
load_project
|
28
|
+
load_exception_class_and_message
|
29
|
+
load_info_about_notifier
|
30
|
+
load_request
|
31
|
+
load_running_mode
|
32
|
+
load_server_info
|
33
|
+
load_backtrace
|
34
|
+
load_stack
|
35
|
+
|
36
|
+
@proto_message
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def load_stack
|
42
|
+
@proto_message.stack = Bugloco.config.stack
|
43
|
+
end
|
44
|
+
|
45
|
+
def load_company
|
46
|
+
@proto_message.company = Bugloco::Proto::Company.new(
|
47
|
+
api_key: Bugloco.config.api_key)
|
48
|
+
end
|
49
|
+
|
50
|
+
def load_project
|
51
|
+
@proto_message.project = Bugloco::Proto::Project.new(
|
52
|
+
id: Bugloco.config.project_id)
|
53
|
+
end
|
54
|
+
|
55
|
+
def load_backtrace
|
56
|
+
return unless Bugloco.config.project_root
|
57
|
+
|
58
|
+
@exception.backtrace.each do |trace|
|
59
|
+
matches = trace.match(EXCEPTION_REGEX)
|
60
|
+
next unless matches
|
61
|
+
backtrace_entry = Bugloco::Proto::BacktraceEntry.new(
|
62
|
+
line_number: matches[:line_number].to_i,
|
63
|
+
function_name: matches[:function_name])
|
64
|
+
|
65
|
+
backtrace_entry.location_type = path_location_type(matches[:path])
|
66
|
+
backtrace_entry.full_path = matches[:path]
|
67
|
+
backtrace_entry.path = filter_path(matches[:path])
|
68
|
+
|
69
|
+
@proto_message.backtrace << backtrace_entry
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def path_location_type(path)
|
74
|
+
type = nil
|
75
|
+
|
76
|
+
if path.start_with?(Bugloco.config.project_root.to_s)
|
77
|
+
type = Bugloco::Proto::LocationType::PROJECT
|
78
|
+
else
|
79
|
+
Gem.path.each do |gem_path|
|
80
|
+
if path.start_with?(gem_path)
|
81
|
+
type = Bugloco::Proto::LocationType::GEM
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
if type.nil?
|
86
|
+
type = Bugloco::Proto::LocationType::UNKNOWN
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
type
|
91
|
+
end
|
92
|
+
|
93
|
+
def filter_path(path)
|
94
|
+
if Bugloco.config.project_root
|
95
|
+
path.gsub!("#{Bugloco.config.project_root}/", "")
|
96
|
+
end
|
97
|
+
|
98
|
+
Gem.path.each do |gem_path|
|
99
|
+
path.gsub!("#{gem_path}/", "")
|
100
|
+
end
|
101
|
+
|
102
|
+
path
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
def load_server_info
|
107
|
+
@proto_message.server = Bugloco::Proto::Server.new(
|
108
|
+
hostname: Socket.gethostname,
|
109
|
+
os: RUBY_PLATFORM)
|
110
|
+
end
|
111
|
+
|
112
|
+
def load_running_mode
|
113
|
+
running_env = ENV["RAILS_ENV"] || ENV["RACK_ENV"]
|
114
|
+
|
115
|
+
running_mode = case running_env
|
116
|
+
when "test"
|
117
|
+
Bugloco::Proto::RunningMode::TEST
|
118
|
+
when "staging"
|
119
|
+
Bugloco::Proto::RunningMode::STAGING
|
120
|
+
when "production"
|
121
|
+
Bugloco::Proto::RunningMode::PRODUCTION
|
122
|
+
end
|
123
|
+
|
124
|
+
@proto_message.running_mode = running_mode
|
125
|
+
end
|
126
|
+
|
127
|
+
def load_exception_class_and_message
|
128
|
+
@proto_message.error_class = @exception.class.to_s
|
129
|
+
@proto_message.error_message = @exception.message
|
130
|
+
end
|
131
|
+
|
132
|
+
def load_info_about_notifier
|
133
|
+
@proto_message.notifier = Bugloco::Proto::Notifier.new(
|
134
|
+
name: "bugloco-rb",
|
135
|
+
version: Bugloco::VERSION
|
136
|
+
)
|
137
|
+
end
|
138
|
+
|
139
|
+
def load_request
|
140
|
+
@request = Bugloco::Proto::Request.new
|
141
|
+
@proto_message.request = @request
|
142
|
+
|
143
|
+
load_environment
|
144
|
+
load_rack_env unless @options[:rack_env].nil?
|
145
|
+
end
|
146
|
+
|
147
|
+
def load_environment
|
148
|
+
ENV.each do |k, v|
|
149
|
+
@request.environment_variables <<
|
150
|
+
Bugloco::Proto::Pair.new(key: k.to_s, value: v)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def load_rack_env
|
155
|
+
@rack_request = ::Rack::Request.new(@rack_env)
|
156
|
+
|
157
|
+
# load the parameters
|
158
|
+
request_parameters.each do |k, v|
|
159
|
+
@request.parameters << Bugloco::Proto::Pair.new(key: k.to_s, value: v.to_s)
|
160
|
+
end
|
161
|
+
|
162
|
+
# load the controller/action
|
163
|
+
@request.controller = request_parameters["controller"]
|
164
|
+
@request.action = request_parameters["action"]
|
165
|
+
|
166
|
+
load_user_from_rack_env
|
167
|
+
|
168
|
+
# Load the URL/Referer
|
169
|
+
@request.url = @rack_env["REQUEST_URI"]
|
170
|
+
@request.referer = @rack_env["HTTP_REFERER"]
|
171
|
+
end
|
172
|
+
|
173
|
+
def request_parameters
|
174
|
+
@rack_env["action_dispatch.request.parameters"] ||
|
175
|
+
@rack_request.params
|
176
|
+
end
|
177
|
+
|
178
|
+
def load_user_from_rack_env
|
179
|
+
@request.user = Bugloco::Proto::User.new(
|
180
|
+
remote_ip: @rack_env["REMOTE_IP"],
|
181
|
+
remote_host: @rack_env["REMOTE_HOST"],
|
182
|
+
user_agent: @rack_env["HTTP_USER_AGENT"]
|
183
|
+
)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -1,13 +1,12 @@
|
|
1
1
|
### Generated by rprotoc. DO NOT EDIT!
|
2
2
|
### <proto file: /home/wmn/code/bug-loco/bugloco-rb/protobufs/bugloco.proto>
|
3
|
-
# package bugloco.proto;
|
4
|
-
#
|
5
3
|
# syntax = "proto2";
|
6
|
-
# option bugloco_proto_version = 1;
|
7
4
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
5
|
+
# package bugloco.proto;
|
6
|
+
#
|
7
|
+
# enum LocationType {
|
8
|
+
# UNKNOWN = 0;
|
9
|
+
# PROJECT = 1;
|
11
10
|
# GEM = 2;
|
12
11
|
# }
|
13
12
|
#
|
@@ -17,21 +16,34 @@
|
|
17
16
|
# PRODUCTION = 2;
|
18
17
|
# }
|
19
18
|
#
|
19
|
+
# enum Status {
|
20
|
+
# SUCCESS = 0;
|
21
|
+
# FAILURE = 1;
|
22
|
+
# }
|
23
|
+
#
|
24
|
+
# enum ErrorCode {
|
25
|
+
# API_KEY_INVALID = 0;
|
26
|
+
# PROJECT_NOT_FOUND = 1;
|
27
|
+
# UNKNOWN_ERROR = 2;
|
28
|
+
# }
|
29
|
+
#
|
20
30
|
# message BacktraceEntry {
|
21
|
-
# required bugloco.proto.
|
31
|
+
# required bugloco.proto.LocationType location_type = 1;
|
22
32
|
# required string full_path = 2;
|
23
33
|
# required string path = 3;
|
24
|
-
# required
|
34
|
+
# required int32 line_number = 4;
|
25
35
|
# required string function_name = 5;
|
26
36
|
# }
|
27
37
|
#
|
28
38
|
# message Company {
|
29
|
-
# required
|
30
|
-
#
|
39
|
+
# required string api_key = 1;
|
40
|
+
# optional int64 id = 2;
|
31
41
|
# }
|
32
42
|
#
|
33
43
|
# message Project {
|
34
|
-
# required
|
44
|
+
# required int64 id = 1;
|
45
|
+
# optional string framework = 2;
|
46
|
+
# optional string version = 3;
|
35
47
|
# }
|
36
48
|
#
|
37
49
|
# message Pair {
|
@@ -42,22 +54,47 @@
|
|
42
54
|
# message Server {
|
43
55
|
# required string hostname = 1;
|
44
56
|
# optional string os = 2;
|
45
|
-
# optional string version = 3;
|
46
57
|
# }
|
47
58
|
#
|
48
|
-
# message
|
59
|
+
# message Notifier {
|
60
|
+
# required string name = 1;
|
61
|
+
# required string version = 2;
|
62
|
+
# }
|
63
|
+
#
|
64
|
+
# message User {
|
65
|
+
# optional string remote_ip = 1;
|
66
|
+
# optional string remote_host = 2;
|
67
|
+
# optional string user_agent = 3;
|
68
|
+
# }
|
69
|
+
#
|
70
|
+
# message Request {
|
71
|
+
# repeated bugloco.proto.Pair environment_variables = 1;
|
72
|
+
# repeated bugloco.proto.Pair parameters = 2;
|
73
|
+
# optional string controller = 3;
|
74
|
+
# optional string action = 4;
|
75
|
+
# optional bugloco.proto.User user = 5;
|
76
|
+
# optional string url = 6;
|
77
|
+
# optional string referer = 7;
|
78
|
+
# }
|
79
|
+
#
|
80
|
+
# message Notice {
|
49
81
|
# required bugloco.proto.Company company = 1;
|
50
82
|
# required bugloco.proto.Project project = 2;
|
51
|
-
# required string
|
83
|
+
# required string error_class = 3;
|
52
84
|
# required string error_message = 4;
|
53
|
-
#
|
54
|
-
#
|
55
|
-
# repeated bugloco.proto.
|
85
|
+
# required bugloco.proto.Notifier notifier = 5;
|
86
|
+
# required bugloco.proto.Request request = 6;
|
87
|
+
# repeated bugloco.proto.BacktraceEntry backtrace = 7;
|
56
88
|
# optional string stack = 8;
|
57
89
|
# optional bugloco.proto.RunningMode running_mode = 9;
|
58
90
|
# optional bugloco.proto.Server server = 10;
|
59
|
-
#
|
60
|
-
#
|
91
|
+
# }
|
92
|
+
#
|
93
|
+
# message Response {
|
94
|
+
# required bugloco.proto.Status status = 1;
|
95
|
+
# optional int64 notice_id = 2;
|
96
|
+
# optional bugloco.proto.ErrorCode error_code = 3;
|
97
|
+
# optional string error_message = 4;
|
61
98
|
# }
|
62
99
|
|
63
100
|
require 'protobuf/message/message'
|
@@ -67,11 +104,10 @@ require 'protobuf/message/extend'
|
|
67
104
|
|
68
105
|
module Bugloco
|
69
106
|
module Proto
|
70
|
-
::Protobuf::
|
71
|
-
class FilelocationType < ::Protobuf::Enum
|
107
|
+
class LocationType < ::Protobuf::Enum
|
72
108
|
defined_in __FILE__
|
73
|
-
|
74
|
-
|
109
|
+
UNKNOWN = value(:UNKNOWN, 0)
|
110
|
+
PROJECT = value(:PROJECT, 1)
|
75
111
|
GEM = value(:GEM, 2)
|
76
112
|
end
|
77
113
|
class RunningMode < ::Protobuf::Enum
|
@@ -80,22 +116,35 @@ module Bugloco
|
|
80
116
|
STAGING = value(:STAGING, 1)
|
81
117
|
PRODUCTION = value(:PRODUCTION, 2)
|
82
118
|
end
|
119
|
+
class Status < ::Protobuf::Enum
|
120
|
+
defined_in __FILE__
|
121
|
+
SUCCESS = value(:SUCCESS, 0)
|
122
|
+
FAILURE = value(:FAILURE, 1)
|
123
|
+
end
|
124
|
+
class ErrorCode < ::Protobuf::Enum
|
125
|
+
defined_in __FILE__
|
126
|
+
API_KEY_INVALID = value(:API_KEY_INVALID, 0)
|
127
|
+
PROJECT_NOT_FOUND = value(:PROJECT_NOT_FOUND, 1)
|
128
|
+
UNKNOWN_ERROR = value(:UNKNOWN_ERROR, 2)
|
129
|
+
end
|
83
130
|
class BacktraceEntry < ::Protobuf::Message
|
84
131
|
defined_in __FILE__
|
85
|
-
required :'bugloco::proto::
|
132
|
+
required :'bugloco::proto::LocationType', :location_type, 1
|
86
133
|
required :string, :full_path, 2
|
87
134
|
required :string, :path, 3
|
88
|
-
required :
|
135
|
+
required :int32, :line_number, 4
|
89
136
|
required :string, :function_name, 5
|
90
137
|
end
|
91
138
|
class Company < ::Protobuf::Message
|
92
139
|
defined_in __FILE__
|
93
|
-
required :
|
94
|
-
|
140
|
+
required :string, :api_key, 1
|
141
|
+
optional :int64, :id, 2
|
95
142
|
end
|
96
143
|
class Project < ::Protobuf::Message
|
97
144
|
defined_in __FILE__
|
98
|
-
required :
|
145
|
+
required :int64, :id, 1
|
146
|
+
optional :string, :framework, 2
|
147
|
+
optional :string, :version, 3
|
99
148
|
end
|
100
149
|
class Pair < ::Protobuf::Message
|
101
150
|
defined_in __FILE__
|
@@ -106,22 +155,47 @@ module Bugloco
|
|
106
155
|
defined_in __FILE__
|
107
156
|
required :string, :hostname, 1
|
108
157
|
optional :string, :os, 2
|
109
|
-
optional :string, :version, 3
|
110
158
|
end
|
111
|
-
class
|
159
|
+
class Notifier < ::Protobuf::Message
|
160
|
+
defined_in __FILE__
|
161
|
+
required :string, :name, 1
|
162
|
+
required :string, :version, 2
|
163
|
+
end
|
164
|
+
class User < ::Protobuf::Message
|
165
|
+
defined_in __FILE__
|
166
|
+
optional :string, :remote_ip, 1
|
167
|
+
optional :string, :remote_host, 2
|
168
|
+
optional :string, :user_agent, 3
|
169
|
+
end
|
170
|
+
class Request < ::Protobuf::Message
|
171
|
+
defined_in __FILE__
|
172
|
+
repeated :'bugloco::proto::Pair', :environment_variables, 1
|
173
|
+
repeated :'bugloco::proto::Pair', :parameters, 2
|
174
|
+
optional :string, :controller, 3
|
175
|
+
optional :string, :action, 4
|
176
|
+
optional :'bugloco::proto::User', :user, 5
|
177
|
+
optional :string, :url, 6
|
178
|
+
optional :string, :referer, 7
|
179
|
+
end
|
180
|
+
class Notice < ::Protobuf::Message
|
112
181
|
defined_in __FILE__
|
113
182
|
required :'bugloco::proto::Company', :company, 1
|
114
183
|
required :'bugloco::proto::Project', :project, 2
|
115
|
-
required :string, :
|
184
|
+
required :string, :error_class, 3
|
116
185
|
required :string, :error_message, 4
|
117
|
-
|
118
|
-
|
119
|
-
repeated :'bugloco::proto::
|
186
|
+
required :'bugloco::proto::Notifier', :notifier, 5
|
187
|
+
required :'bugloco::proto::Request', :request, 6
|
188
|
+
repeated :'bugloco::proto::BacktraceEntry', :backtrace, 7
|
120
189
|
optional :string, :stack, 8
|
121
190
|
optional :'bugloco::proto::RunningMode', :running_mode, 9
|
122
191
|
optional :'bugloco::proto::Server', :server, 10
|
123
|
-
|
124
|
-
|
192
|
+
end
|
193
|
+
class Response < ::Protobuf::Message
|
194
|
+
defined_in __FILE__
|
195
|
+
required :'bugloco::proto::Status', :status, 1
|
196
|
+
optional :int64, :notice_id, 2
|
197
|
+
optional :'bugloco::proto::ErrorCode', :error_code, 3
|
198
|
+
optional :string, :error_message, 4
|
125
199
|
end
|
126
200
|
end
|
127
201
|
end
|
data/lib/bugloco/rack.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Bugloco
|
2
|
+
class Rack
|
3
|
+
def initialize(app)
|
4
|
+
@app = app
|
5
|
+
# TODO: Set the framework
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
response = @app.call(env)
|
10
|
+
|
11
|
+
response
|
12
|
+
rescue Exception => exception
|
13
|
+
env["bugloco.error_id"] = Bugloco.report_notice(exception, rack_env: env)
|
14
|
+
raise exception
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Bugloco
|
2
|
+
module Rails
|
3
|
+
class Middleware
|
4
|
+
def initialize(app)
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
response = @app.call(env)
|
10
|
+
|
11
|
+
if framework_exception = env["action_dispatch.exception"]
|
12
|
+
env["bugloco.error_id"] = Bugloco.report_notice(framework_exception, rack_env: env)
|
13
|
+
end
|
14
|
+
|
15
|
+
response
|
16
|
+
rescue Exception => exception
|
17
|
+
env["bugloco.error_id"] = Bugloco.report_notice(exception, rack_env: env)
|
18
|
+
raise exception
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "bugloco"
|
2
|
+
require "bugloco/rails/middleware"
|
3
|
+
|
4
|
+
module Bugloco
|
5
|
+
class Railtie < ::Rails::Railtie
|
6
|
+
initializer "bugloco.middleware" do |app|
|
7
|
+
app.config.middleware.insert_after("ActionDispatch::DebugExceptions",
|
8
|
+
"Bugloco::Rails::Middleware")
|
9
|
+
end
|
10
|
+
|
11
|
+
config.after_initialize do
|
12
|
+
Bugloco.config do |config|
|
13
|
+
config.framework = "Rails"
|
14
|
+
config.framework_version = ::Rails::VERSION::STRING
|
15
|
+
config.project_root = ::Rails.root
|
16
|
+
config.environment = ::Rails.env
|
17
|
+
config.logger = ::Rails.logger
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/bugloco/version.rb
CHANGED
data/lib/bugloco.rb
CHANGED
@@ -1,31 +1,74 @@
|
|
1
1
|
require "bugloco/version"
|
2
|
-
require "bugloco/
|
2
|
+
require "bugloco/rack"
|
3
|
+
require "bugloco/notice"
|
4
|
+
require "bugloco/configuration"
|
5
|
+
require "net/http"
|
6
|
+
require "net/https"
|
7
|
+
|
8
|
+
require 'bugloco/railtie' if defined?(Rails::Railtie)
|
3
9
|
|
4
10
|
module Bugloco
|
5
|
-
class
|
6
|
-
|
7
|
-
|
8
|
-
|
11
|
+
class << self
|
12
|
+
HTTP_ERRORS = [
|
13
|
+
Timeout::Error,
|
14
|
+
Errno::EINVAL,
|
15
|
+
Errno::ECONNRESET,
|
16
|
+
EOFError,
|
17
|
+
Net::HTTPBadResponse,
|
18
|
+
Net::HTTPHeaderSyntaxError,
|
19
|
+
Net::ProtocolError,
|
20
|
+
Errno::ECONNREFUSED,
|
21
|
+
OpenSSL::SSL::SSLError].freeze
|
22
|
+
|
23
|
+
def report_notice(exception, options = {})
|
24
|
+
# TODO: We need to inform the user if api_key/project_id were not given
|
25
|
+
encoded_notice = Bugloco::Notice.new(exception, options).to_pb
|
26
|
+
encoded_response = send_notice(encoded_notice, options)
|
27
|
+
|
28
|
+
if encoded_response
|
29
|
+
response = Bugloco::Proto::Response.new.
|
30
|
+
parse_from_string(encoded_response)
|
31
|
+
|
32
|
+
response.notice_id if response.status == Bugloco::Proto::Status::SUCCESS
|
33
|
+
else
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def config
|
39
|
+
@configuration ||= Bugloco::Configuration.new
|
40
|
+
yield(@configuration) if block_given?
|
41
|
+
@configuration
|
9
42
|
end
|
10
43
|
|
11
|
-
|
12
|
-
|
44
|
+
private
|
45
|
+
|
46
|
+
def send_notice(encoded_notice, options = {})
|
47
|
+
response = http_connection.post(api_url.path, encoded_notice, headers)
|
48
|
+
response.body
|
49
|
+
rescue *HTTP_ERRORS => e
|
50
|
+
# log e
|
51
|
+
|
52
|
+
nil
|
53
|
+
end
|
13
54
|
|
14
|
-
|
55
|
+
def http_connection
|
56
|
+
http = Net::HTTP.new(api_url.host, api_url.port)
|
15
57
|
|
16
|
-
|
58
|
+
# do some SSL magic
|
17
59
|
|
18
|
-
|
60
|
+
http
|
19
61
|
end
|
20
62
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
63
|
+
def headers
|
64
|
+
{
|
65
|
+
"Content-type" => "application/octet-stream",
|
66
|
+
"Accept" => "application/octet-stream"
|
67
|
+
}.freeze
|
68
|
+
end
|
26
69
|
|
27
|
-
|
28
|
-
|
70
|
+
def api_url
|
71
|
+
URI.parse(Bugloco.config.api_url)
|
29
72
|
end
|
30
73
|
end
|
31
74
|
end
|
data/protobufs/bugloco.proto
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
package bugloco.proto;
|
2
|
-
|
3
1
|
syntax = "proto2";
|
4
|
-
option bugloco_proto_version = 1;
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
package bugloco.proto;
|
4
|
+
|
5
|
+
enum LocationType {
|
6
|
+
UNKNOWN = 0;
|
7
|
+
PROJECT = 1;
|
9
8
|
GEM = 2;
|
10
9
|
}
|
11
10
|
|
@@ -15,21 +14,34 @@ enum RunningMode {
|
|
15
14
|
PRODUCTION = 2;
|
16
15
|
}
|
17
16
|
|
17
|
+
enum Status {
|
18
|
+
SUCCESS = 0;
|
19
|
+
FAILURE = 1;
|
20
|
+
}
|
21
|
+
|
22
|
+
enum ErrorCode {
|
23
|
+
API_KEY_INVALID = 0;
|
24
|
+
PROJECT_NOT_FOUND = 1;
|
25
|
+
UNKNOWN_ERROR = 2;
|
26
|
+
}
|
27
|
+
|
18
28
|
message BacktraceEntry {
|
19
|
-
required bugloco.proto.
|
29
|
+
required bugloco.proto.LocationType location_type = 1;
|
20
30
|
required string full_path = 2;
|
21
31
|
required string path = 3;
|
22
|
-
required
|
32
|
+
required int32 line_number = 4;
|
23
33
|
required string function_name = 5;
|
24
34
|
}
|
25
35
|
|
26
36
|
message Company {
|
27
|
-
required
|
28
|
-
|
37
|
+
required string api_key = 1;
|
38
|
+
optional int64 id = 2;
|
29
39
|
}
|
30
40
|
|
31
41
|
message Project {
|
32
|
-
required
|
42
|
+
required int64 id = 1;
|
43
|
+
optional string framework = 2;
|
44
|
+
optional string version = 3;
|
33
45
|
}
|
34
46
|
|
35
47
|
message Pair {
|
@@ -40,20 +52,45 @@ message Pair {
|
|
40
52
|
message Server {
|
41
53
|
required string hostname = 1;
|
42
54
|
optional string os = 2;
|
43
|
-
optional string version = 3;
|
44
55
|
}
|
45
56
|
|
46
|
-
message
|
57
|
+
message Notifier {
|
58
|
+
required string name = 1;
|
59
|
+
required string version = 2;
|
60
|
+
}
|
61
|
+
|
62
|
+
message User {
|
63
|
+
optional string remote_ip = 1;
|
64
|
+
optional string remote_host = 2;
|
65
|
+
optional string user_agent = 3;
|
66
|
+
}
|
67
|
+
|
68
|
+
message Request {
|
69
|
+
repeated bugloco.proto.Pair environment_variables = 1;
|
70
|
+
repeated bugloco.proto.Pair parameters = 2;
|
71
|
+
optional string controller = 3;
|
72
|
+
optional string action = 4;
|
73
|
+
optional bugloco.proto.User user = 5;
|
74
|
+
optional string url = 6;
|
75
|
+
optional string referer = 7;
|
76
|
+
}
|
77
|
+
|
78
|
+
message Notice {
|
47
79
|
required bugloco.proto.Company company = 1;
|
48
80
|
required bugloco.proto.Project project = 2;
|
49
|
-
required string
|
81
|
+
required string error_class = 3;
|
50
82
|
required string error_message = 4;
|
51
|
-
|
52
|
-
|
53
|
-
repeated bugloco.proto.
|
83
|
+
required bugloco.proto.Notifier notifier = 5;
|
84
|
+
required bugloco.proto.Request request = 6;
|
85
|
+
repeated bugloco.proto.BacktraceEntry backtrace = 7;
|
54
86
|
optional string stack = 8;
|
55
87
|
optional bugloco.proto.RunningMode running_mode = 9;
|
56
88
|
optional bugloco.proto.Server server = 10;
|
57
|
-
|
58
|
-
|
89
|
+
}
|
90
|
+
|
91
|
+
message Response {
|
92
|
+
required bugloco.proto.Status status = 1;
|
93
|
+
optional int64 notice_id = 2;
|
94
|
+
optional bugloco.proto.ErrorCode error_code = 3;
|
95
|
+
optional string error_message = 4;
|
59
96
|
}
|
@@ -0,0 +1,217 @@
|
|
1
|
+
describe Bugloco::Notice do
|
2
|
+
def run_rack_app(params_type = :query_string)
|
3
|
+
@extra_env.each {|k, v| ENV[k] = v}
|
4
|
+
|
5
|
+
@request_options = {
|
6
|
+
"action_dispatch.request.parameters" => @params,
|
7
|
+
}
|
8
|
+
|
9
|
+
if params_type == :action_dispatch
|
10
|
+
@rack_env = Rack::MockRequest.env_for(@url, @request_options)
|
11
|
+
else
|
12
|
+
@rack_env = Rack::MockRequest.env_for(@url)
|
13
|
+
end
|
14
|
+
|
15
|
+
@rack_env.merge! @rack_env_extra
|
16
|
+
|
17
|
+
@app = lambda do |env|
|
18
|
+
raise CustomBacktraceException, @error_message
|
19
|
+
end
|
20
|
+
|
21
|
+
begin
|
22
|
+
@stack = Bugloco::Rack.new(@app)
|
23
|
+
@stack.call(@rack_env)
|
24
|
+
rescue CustomBacktraceException => exception
|
25
|
+
@exception = mock_backtrace(exception)
|
26
|
+
@notice = Bugloco::Notice.new(@exception, rack_env: @rack_env)
|
27
|
+
@notice_proto_message = @notice.proto_message
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
before do
|
32
|
+
allow(Bugloco).to receive(:report_notice)
|
33
|
+
|
34
|
+
@extra_env = {}
|
35
|
+
|
36
|
+
@error_message = "Fake error needed for the builder"
|
37
|
+
@url = "http://www.google.com?name=John%20Doe"
|
38
|
+
|
39
|
+
@params = {
|
40
|
+
"name" => "John Doe",
|
41
|
+
"controller" => "home",
|
42
|
+
"action" => "greet",
|
43
|
+
}
|
44
|
+
|
45
|
+
@rack_env_extra = {}
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
after do
|
52
|
+
@extra_env.each {|k, _| ENV[k] = nil}
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should include the company" do
|
56
|
+
@api_key = "secret_key"
|
57
|
+
Bugloco.config do |config|
|
58
|
+
config.api_key = @api_key
|
59
|
+
end
|
60
|
+
expected = Bugloco::Proto::Company.new(api_key: @api_key)
|
61
|
+
|
62
|
+
run_rack_app
|
63
|
+
expect(@notice_proto_message.company).to eq(expected)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should include the project" do
|
67
|
+
@project_id = 123
|
68
|
+
Bugloco.config do |config|
|
69
|
+
config.project_id = @project_id
|
70
|
+
end
|
71
|
+
expected = Bugloco::Proto::Project.new(id: @project_id)
|
72
|
+
|
73
|
+
run_rack_app
|
74
|
+
expect(@notice_proto_message.project).to eq(expected)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should include the stack" do
|
78
|
+
@stack_name = "sysadmin"
|
79
|
+
Bugloco.config do |config|
|
80
|
+
config.stack = @stack_name
|
81
|
+
end
|
82
|
+
|
83
|
+
run_rack_app
|
84
|
+
expect(@notice_proto_message.stack).to eq(@stack_name)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should collect the environment" do
|
88
|
+
@extra_env["BUGLOCO_KEY"] = "VAR"
|
89
|
+
|
90
|
+
run_rack_app
|
91
|
+
expected = Bugloco::Proto::Pair.new(key: "BUGLOCO_KEY", value: "VAR")
|
92
|
+
env_vars = @notice_proto_message.request.environment_variables
|
93
|
+
expect(env_vars).to include(expected)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should collect the class/message of the notice" do
|
97
|
+
run_rack_app
|
98
|
+
expect(@notice_proto_message.error_class).to eq("CustomBacktraceException")
|
99
|
+
expect(@notice_proto_message.error_message).to eq(@error_message)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should include information about the notifier" do
|
103
|
+
run_rack_app
|
104
|
+
|
105
|
+
expected = Bugloco::Proto::Notifier.new(
|
106
|
+
name: "Bugloco",
|
107
|
+
version: Bugloco::VERSION
|
108
|
+
)
|
109
|
+
|
110
|
+
expect(@notice_proto_message.notifier).to eq(expected)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should include information about the current server" do
|
114
|
+
run_rack_app
|
115
|
+
expected = Bugloco::Proto::Server.new(
|
116
|
+
hostname: `hostname`.chomp,
|
117
|
+
os: RUBY_PLATFORM)
|
118
|
+
|
119
|
+
expect(@notice_proto_message.server).to eq(expected)
|
120
|
+
end
|
121
|
+
|
122
|
+
context "rack" do
|
123
|
+
it "should extract the parameters from action dispatch" do
|
124
|
+
run_rack_app :action_dispatch
|
125
|
+
expected = Bugloco::Proto::Pair.new(key: "name", value: "John Doe")
|
126
|
+
expect(@notice_proto_message.request.parameters).to include(expected)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should extract the parameters from the query string" do
|
130
|
+
run_rack_app
|
131
|
+
expected = Bugloco::Proto::Pair.new(key: "name", value: "John Doe")
|
132
|
+
expect(@notice_proto_message.request.parameters).to include(expected)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should extract the controller/action from the rack_env" do
|
136
|
+
run_rack_app :action_dispatch
|
137
|
+
expect(@notice_proto_message.request.controller).to eq("home")
|
138
|
+
expect(@notice_proto_message.request.action).to eq("greet")
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should collect info about the user (IP/user_agent)" do
|
142
|
+
@rack_env_extra.merge!({
|
143
|
+
"REMOTE_IP" => "8.8.8.8",
|
144
|
+
"REMOTE_HOST" => "google-public-dns-a.google.com",
|
145
|
+
"HTTP_USER_AGENT" => "Mozilla something :)",
|
146
|
+
})
|
147
|
+
|
148
|
+
run_rack_app
|
149
|
+
expected = Bugloco::Proto::User.new(
|
150
|
+
remote_ip: @rack_env_extra["REMOTE_IP"],
|
151
|
+
remote_host: @rack_env_extra["REMOTE_HOST"],
|
152
|
+
user_agent: @rack_env_extra["HTTP_USER_AGENT"]
|
153
|
+
)
|
154
|
+
|
155
|
+
expect(@notice_proto_message.request.user).to eq(expected)
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should collect the URL" do
|
159
|
+
@rack_env_extra["REQUEST_URI"] = @url
|
160
|
+
run_rack_app
|
161
|
+
expect(@notice_proto_message.request.url).to eq(@rack_env_extra["REQUEST_URI"])
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should collect the REFERER" do
|
165
|
+
@rack_env_extra["HTTP_REFERER"] = "http://www.google.com"
|
166
|
+
run_rack_app
|
167
|
+
expect(@notice_proto_message.request.referer).to eq(@rack_env_extra["HTTP_REFERER"])
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should include information about RACK_ENV" do
|
171
|
+
@extra_env["RACK_ENV"] = "production"
|
172
|
+
run_rack_app
|
173
|
+
expected = Bugloco::Proto::RunningMode::PRODUCTION
|
174
|
+
expect(@notice_proto_message.running_mode).to eq(expected)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context "rails" do
|
179
|
+
before do
|
180
|
+
Bugloco.config do |config|
|
181
|
+
config.project_root = File.expand_path("../../../", __FILE__)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should record the backtrace" do
|
186
|
+
project_root = Bugloco.config.project_root
|
187
|
+
first = Bugloco::Proto::BacktraceEntry.new(
|
188
|
+
location_type: Bugloco::Proto::LocationType::PROJECT,
|
189
|
+
full_path: File.join(project_root, "spec/bugloco/notice_spec.rb"),
|
190
|
+
path: "spec/bugloco/notice_spec.rb",
|
191
|
+
line_number: 18,
|
192
|
+
function_name: "block in run_rack_app")
|
193
|
+
second = Bugloco::Proto::BacktraceEntry.new(
|
194
|
+
location_type: Bugloco::Proto::LocationType::PROJECT,
|
195
|
+
full_path: File.join(project_root, "lib/bugloco/rack.rb"),
|
196
|
+
path: "lib/bugloco/rack.rb",
|
197
|
+
line_number: 9,
|
198
|
+
function_name: "call")
|
199
|
+
third = Bugloco::Proto::BacktraceEntry.new(
|
200
|
+
location_type: Bugloco::Proto::LocationType::GEM,
|
201
|
+
full_path: "#{Gem.path.last}/gems/rspec-core-3.0.2/lib/rspec/core/example.rb",
|
202
|
+
path: "gems/rspec-core-3.0.2/lib/rspec/core/example.rb",
|
203
|
+
line_number: 148,
|
204
|
+
function_name: "instance_exec")
|
205
|
+
|
206
|
+
run_rack_app
|
207
|
+
expect(@notice_proto_message.backtrace).to eq([first, second, third])
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should include information about RAILS_ENV" do
|
211
|
+
@extra_env["RAILS_ENV"] = "staging"
|
212
|
+
run_rack_app
|
213
|
+
expected = Bugloco::Proto::RunningMode::STAGING
|
214
|
+
expect(@notice_proto_message.running_mode).to eq(expected)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
data/spec/bugloco_spec.rb
CHANGED
@@ -1,26 +1,41 @@
|
|
1
|
-
describe Bugloco
|
2
|
-
|
3
|
-
|
1
|
+
describe Bugloco do
|
2
|
+
context "#config" do
|
3
|
+
it "should be configurable" do
|
4
|
+
project_id = 123
|
5
|
+
api_key = "secret_key"
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
Bugloco.config do |config|
|
8
|
+
config.project_id = project_id
|
9
|
+
config.api_key = api_key
|
10
|
+
end
|
11
|
+
|
12
|
+
expect(Bugloco.config.project_id).to eq(project_id)
|
13
|
+
expect(Bugloco.config.api_key).to eq(api_key)
|
10
14
|
end
|
11
|
-
end
|
12
15
|
|
13
|
-
|
14
|
-
|
16
|
+
it "should include the API url" do
|
17
|
+
expect(Bugloco.config.api_url).to eq("https://bugloco.com/api/v1/notices")
|
18
|
+
end
|
15
19
|
end
|
16
20
|
|
17
|
-
context "
|
18
|
-
it "should
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
context "#report_notice" do
|
22
|
+
it "should return success when the proto gets built and sent" do
|
23
|
+
pending "FakeWeb cannot receive binary, how to test this?"
|
24
|
+
|
25
|
+
response = Bugloco::Proto::Response.new(
|
26
|
+
status: Bugloco::Proto::Status::SUCCESS,
|
27
|
+
notice_id: 123)
|
28
|
+
FakeWeb.register_uri(:post, Bugloco.config.api_url,
|
29
|
+
body: response.serialize_to_string)
|
30
|
+
|
31
|
+
begin
|
32
|
+
raise CustomBacktraceException, "Fake web"
|
33
|
+
rescue CustomBacktraceException => exception
|
34
|
+
exception = mock_backtrace(exception)
|
35
|
+
api_response = Bugloco.report_notice(exception)
|
36
|
+
end
|
22
37
|
|
23
|
-
expect(
|
38
|
+
expect(api_response).to eq(response)
|
24
39
|
end
|
25
40
|
end
|
26
41
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,32 @@
|
|
1
|
+
if ENV["CI"]
|
2
|
+
require "coveralls"
|
3
|
+
Coveralls.wear!
|
4
|
+
end
|
5
|
+
|
6
|
+
require "fakeweb"
|
1
7
|
require "bugloco"
|
2
8
|
|
9
|
+
def mock_backtrace(exception)
|
10
|
+
project_root = File.expand_path("../../", __FILE__)
|
11
|
+
backtrace = [
|
12
|
+
"#{project_root}/spec/bugloco/notice_spec.rb:18:in `block in run_rack_app'",
|
13
|
+
"#{project_root}/lib/bugloco/rack.rb:9:in `call'",
|
14
|
+
"#{Gem.path.last}/gems/rspec-core-3.0.2/lib/rspec/core/example.rb:148:in `instance_exec'"
|
15
|
+
]
|
16
|
+
|
17
|
+
exception.backtrace = backtrace
|
18
|
+
|
19
|
+
exception
|
20
|
+
end
|
21
|
+
|
22
|
+
class CustomBacktraceException < Exception
|
23
|
+
attr_accessor :backtrace
|
24
|
+
end
|
25
|
+
|
3
26
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
4
27
|
RSpec.configure do |config|
|
28
|
+
config.before(:each) do
|
29
|
+
ENV["RACK_ENV"] = nil
|
30
|
+
ENV["RAILS_ENV"] = nil
|
31
|
+
end
|
5
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bugloco
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wael M. Nasreddine
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-07-
|
11
|
+
date: 2014-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -53,19 +53,61 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 3.0.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rack
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
|
-
type: :
|
62
|
+
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: coveralls
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: fakeweb
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: ruby_protobuf
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.4.11
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.4.11
|
69
111
|
description: Bugloco ruby gem for sending exceptions to Bugloco
|
70
112
|
email:
|
71
113
|
- wael.nasreddine@gmail.com
|
@@ -75,15 +117,23 @@ extra_rdoc_files: []
|
|
75
117
|
files:
|
76
118
|
- ".gitignore"
|
77
119
|
- ".rspec"
|
120
|
+
- ".travis.yml"
|
78
121
|
- Gemfile
|
79
122
|
- LICENSE.txt
|
80
123
|
- README.md
|
81
124
|
- Rakefile
|
82
125
|
- bugloco.gemspec
|
83
126
|
- lib/bugloco.rb
|
127
|
+
- lib/bugloco/configuration.rb
|
128
|
+
- lib/bugloco/notice.rb
|
84
129
|
- lib/bugloco/protobuf/bugloco.pb.rb
|
130
|
+
- lib/bugloco/rack.rb
|
131
|
+
- lib/bugloco/rails/middleware.rb
|
132
|
+
- lib/bugloco/railtie.rb
|
85
133
|
- lib/bugloco/version.rb
|
86
134
|
- protobufs/bugloco.proto
|
135
|
+
- spec/bugloco/configuration_spec.rb
|
136
|
+
- spec/bugloco/notice_spec.rb
|
87
137
|
- spec/bugloco_spec.rb
|
88
138
|
- spec/spec_helper.rb
|
89
139
|
homepage: https://bugloco.com
|
@@ -111,5 +161,7 @@ signing_key:
|
|
111
161
|
specification_version: 4
|
112
162
|
summary: Bugloco ruby gem for sending exceptions to Bugloco
|
113
163
|
test_files:
|
164
|
+
- spec/bugloco/configuration_spec.rb
|
165
|
+
- spec/bugloco/notice_spec.rb
|
114
166
|
- spec/bugloco_spec.rb
|
115
167
|
- spec/spec_helper.rb
|