bugloco 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/bugloco/bugloco-rb.svg?branch=master)](https://travis-ci.org/bugloco/bugloco-rb) [![Coverage Status](https://coveralls.io/repos/bugloco/bugloco-rb/badge.png)](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
|