justlogging-rails 0.0.1
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.
- data/.gitignore +16 -0
- data/.rvmrc +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +103 -0
- data/README.md +2 -0
- data/config/justlogging.yml +4 -0
- data/doc/justlogging-mongo.markdown +15 -0
- data/justlogging-rails.gemspec +22 -0
- data/lib/justlogging/agent.rb +68 -0
- data/lib/justlogging/exception_notification.rb +29 -0
- data/lib/justlogging/middleware.rb +25 -0
- data/lib/justlogging/railtie.rb +20 -0
- data/lib/justlogging/transaction.rb +91 -0
- data/lib/justlogging/version.rb +3 -0
- data/lib/justlogging.rb +30 -0
- data/spec/justlogging/agent_spec.rb +74 -0
- data/spec/justlogging/exception_notification_spec.rb +12 -0
- data/spec/justlogging/middleware_spec.rb +80 -0
- data/spec/justlogging/railtie_spec.rb +47 -0
- data/spec/justlogging/transaction_spec.rb +190 -0
- data/spec/justlogging_spec.rb +35 -0
- data/spec/spec_helper.rb +19 -0
- metadata +169 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.9.3
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
justlogging-rails (0.0.1)
|
5
|
+
activesupport
|
6
|
+
rails
|
7
|
+
rake
|
8
|
+
rspec
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
actionmailer (3.2.7)
|
14
|
+
actionpack (= 3.2.7)
|
15
|
+
mail (~> 2.4.4)
|
16
|
+
actionpack (3.2.7)
|
17
|
+
activemodel (= 3.2.7)
|
18
|
+
activesupport (= 3.2.7)
|
19
|
+
builder (~> 3.0.0)
|
20
|
+
erubis (~> 2.7.0)
|
21
|
+
journey (~> 1.0.4)
|
22
|
+
rack (~> 1.4.0)
|
23
|
+
rack-cache (~> 1.2)
|
24
|
+
rack-test (~> 0.6.1)
|
25
|
+
sprockets (~> 2.1.3)
|
26
|
+
activemodel (3.2.7)
|
27
|
+
activesupport (= 3.2.7)
|
28
|
+
builder (~> 3.0.0)
|
29
|
+
activerecord (3.2.7)
|
30
|
+
activemodel (= 3.2.7)
|
31
|
+
activesupport (= 3.2.7)
|
32
|
+
arel (~> 3.0.2)
|
33
|
+
tzinfo (~> 0.3.29)
|
34
|
+
activeresource (3.2.7)
|
35
|
+
activemodel (= 3.2.7)
|
36
|
+
activesupport (= 3.2.7)
|
37
|
+
activesupport (3.2.7)
|
38
|
+
i18n (~> 0.6)
|
39
|
+
multi_json (~> 1.0)
|
40
|
+
arel (3.0.2)
|
41
|
+
builder (3.0.0)
|
42
|
+
diff-lcs (1.1.3)
|
43
|
+
erubis (2.7.0)
|
44
|
+
hike (1.2.1)
|
45
|
+
i18n (0.6.0)
|
46
|
+
journey (1.0.4)
|
47
|
+
json (1.7.4)
|
48
|
+
mail (2.4.4)
|
49
|
+
i18n (>= 0.4.0)
|
50
|
+
mime-types (~> 1.16)
|
51
|
+
treetop (~> 1.4.8)
|
52
|
+
mime-types (1.19)
|
53
|
+
multi_json (1.3.6)
|
54
|
+
polyglot (0.3.3)
|
55
|
+
rack (1.4.1)
|
56
|
+
rack-cache (1.2)
|
57
|
+
rack (>= 0.4)
|
58
|
+
rack-ssl (1.3.2)
|
59
|
+
rack
|
60
|
+
rack-test (0.6.1)
|
61
|
+
rack (>= 1.0)
|
62
|
+
rails (3.2.7)
|
63
|
+
actionmailer (= 3.2.7)
|
64
|
+
actionpack (= 3.2.7)
|
65
|
+
activerecord (= 3.2.7)
|
66
|
+
activeresource (= 3.2.7)
|
67
|
+
activesupport (= 3.2.7)
|
68
|
+
bundler (~> 1.0)
|
69
|
+
railties (= 3.2.7)
|
70
|
+
railties (3.2.7)
|
71
|
+
actionpack (= 3.2.7)
|
72
|
+
activesupport (= 3.2.7)
|
73
|
+
rack-ssl (~> 1.3.2)
|
74
|
+
rake (>= 0.8.7)
|
75
|
+
rdoc (~> 3.4)
|
76
|
+
thor (>= 0.14.6, < 2.0)
|
77
|
+
rake (0.9.2.2)
|
78
|
+
rdoc (3.12)
|
79
|
+
json (~> 1.4)
|
80
|
+
rspec (2.11.0)
|
81
|
+
rspec-core (~> 2.11.0)
|
82
|
+
rspec-expectations (~> 2.11.0)
|
83
|
+
rspec-mocks (~> 2.11.0)
|
84
|
+
rspec-core (2.11.1)
|
85
|
+
rspec-expectations (2.11.2)
|
86
|
+
diff-lcs (~> 1.1.3)
|
87
|
+
rspec-mocks (2.11.2)
|
88
|
+
sprockets (2.1.3)
|
89
|
+
hike (~> 1.2)
|
90
|
+
rack (~> 1.0)
|
91
|
+
tilt (~> 1.1, != 1.3.0)
|
92
|
+
thor (0.16.0)
|
93
|
+
tilt (1.3.3)
|
94
|
+
treetop (1.4.10)
|
95
|
+
polyglot
|
96
|
+
polyglot (>= 0.3.1)
|
97
|
+
tzinfo (0.3.33)
|
98
|
+
|
99
|
+
PLATFORMS
|
100
|
+
ruby
|
101
|
+
|
102
|
+
DEPENDENCIES
|
103
|
+
justlogging-rails!
|
data/README.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
module Mongo
|
3
|
+
module Logging
|
4
|
+
alias_method "instrument_without_notification", 'instrument'
|
5
|
+
def instrument(name, payload={})
|
6
|
+
ActiveSupport::Notifications.instrument(
|
7
|
+
'query.mongodb',
|
8
|
+
:query => payload.merge(:method => name)) do
|
9
|
+
send "instrument_without_notification", name, payload do
|
10
|
+
yield
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/justlogging/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Robert Beekman"]
|
6
|
+
gem.email = ["robert@80beans.com"]
|
7
|
+
gem.description = %q{The official justlogging.com gem}
|
8
|
+
gem.summary = %q{Logs rails's notifications to justlogging.com}
|
9
|
+
gem.homepage = "http://github.com/80beans/justlogging-rails"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "justlogging-rails"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Justlogging::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'rails'
|
19
|
+
gem.add_dependency 'rspec'
|
20
|
+
gem.add_dependency 'activesupport'
|
21
|
+
gem.add_dependency 'rake'
|
22
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Justlogging
|
2
|
+
|
3
|
+
class Agent
|
4
|
+
|
5
|
+
attr_reader :queue, :active, :sleep_time
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@sleep_time = 5
|
9
|
+
@queue = []
|
10
|
+
@active = true
|
11
|
+
@thread = Thread.new do
|
12
|
+
while true do
|
13
|
+
if (@queue.any? && @active == true)
|
14
|
+
send_queue
|
15
|
+
end
|
16
|
+
sleep @sleep_time
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_to_queue(transaction)
|
22
|
+
@queue << transaction
|
23
|
+
end
|
24
|
+
|
25
|
+
def uri
|
26
|
+
URI(Justlogging.config[:endpoint])
|
27
|
+
end
|
28
|
+
|
29
|
+
def http_client
|
30
|
+
Net::HTTP.new(uri.host, uri.port).tap do |http|
|
31
|
+
if uri.scheme == 'https'
|
32
|
+
http.use_ssl = true
|
33
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def send_queue
|
39
|
+
json = ActiveSupport::JSON.encode @queue
|
40
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
41
|
+
request.set_form_data('api_key' => Justlogging.config[:api_key], 'log_entries' => json)
|
42
|
+
|
43
|
+
begin
|
44
|
+
result = http_client.request(request)
|
45
|
+
code = result.code
|
46
|
+
rescue
|
47
|
+
code = nil
|
48
|
+
end
|
49
|
+
handle_result(code)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Empty queue is result is 200 ok.
|
53
|
+
# Throttle connection when result is 403
|
54
|
+
# Unsubscribe and stop sending all together on any other code.
|
55
|
+
def handle_result(code)
|
56
|
+
if code == '200'
|
57
|
+
@queue = []
|
58
|
+
elsif code == '403'
|
59
|
+
@sleep_time = @sleep_time * 1.5
|
60
|
+
else
|
61
|
+
ActiveSupport::Notifications.unsubscribe(Justlogging.subscriber)
|
62
|
+
@active = false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Justlogging
|
2
|
+
class MissingController
|
3
|
+
def method_missing(*args, &block)
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
class ExceptionNotification
|
8
|
+
|
9
|
+
attr_reader :env, :exception, :kontroller, :request, :backtrace
|
10
|
+
|
11
|
+
def initialize(env, exception)
|
12
|
+
#@env = env
|
13
|
+
@exception = exception
|
14
|
+
#@kontroller = env['action_controller.instance'] || Justlogging::MissingController.new
|
15
|
+
#@request = ActionDispatch::Request.new(env)
|
16
|
+
@backtrace = Rails.respond_to?(:backtrace_cleaner) ?
|
17
|
+
Rails.backtrace_cleaner.send(:filter, exception.backtrace) :
|
18
|
+
exception.backtrace
|
19
|
+
end
|
20
|
+
|
21
|
+
def name
|
22
|
+
@exception.class.name
|
23
|
+
end
|
24
|
+
|
25
|
+
def message
|
26
|
+
@exception.message
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'action_dispatch'
|
2
|
+
|
3
|
+
module Justlogging
|
4
|
+
class Middleware
|
5
|
+
|
6
|
+
def initialize(app, options = {})
|
7
|
+
@app, @options = app, options
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
Justlogging::Transaction.create(env['action_dispatch.request_id'], env)
|
12
|
+
@app.call(env)
|
13
|
+
rescue Exception => exception
|
14
|
+
unless Array.wrap(Justlogging.config[:ignore_exceptions]).include?(exception.class.name)
|
15
|
+
Justlogging::Transaction.current.add_exception(
|
16
|
+
Justlogging::ExceptionNotification.new(env, exception)
|
17
|
+
)
|
18
|
+
end
|
19
|
+
raise exception
|
20
|
+
ensure
|
21
|
+
Justlogging::Transaction.current.complete!
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'justlogging'
|
2
|
+
|
3
|
+
module Justlogging
|
4
|
+
class Railtie < Rails::Railtie
|
5
|
+
|
6
|
+
initializer "justlogging.configure_rails_initialization" do |app|
|
7
|
+
app.middleware.insert_after ActionDispatch::DebugExceptions, Justlogging::Middleware
|
8
|
+
|
9
|
+
Justlogging.subscriber = ActiveSupport::Notifications.subscribe do |*args|
|
10
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
11
|
+
if event.name == 'process_action.action_controller'
|
12
|
+
Justlogging::Transaction.current.set_log_entry(event)
|
13
|
+
else
|
14
|
+
Justlogging::Transaction.current.add_event(event)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Justlogging
|
2
|
+
class Transaction
|
3
|
+
|
4
|
+
def self.create(key, env)
|
5
|
+
Thread.current[:justlogging_transaction_id] = key
|
6
|
+
Justlogging.transactions[key] = Justlogging::Transaction.new(key, env)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.current
|
10
|
+
Justlogging.transactions[Thread.current[:justlogging_transaction_id]]
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :id, :events, :exception, :env, :log_entry
|
14
|
+
|
15
|
+
def initialize(id, env)
|
16
|
+
@id = id
|
17
|
+
@events = []
|
18
|
+
@log_entry = nil
|
19
|
+
@exception = nil
|
20
|
+
@env = env
|
21
|
+
end
|
22
|
+
|
23
|
+
def request
|
24
|
+
ActionDispatch::Request.new(@env)
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_log_entry(event)
|
28
|
+
@log_entry = event
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_event(event)
|
32
|
+
@events << event
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_exception(ex)
|
36
|
+
@exception = ex
|
37
|
+
end
|
38
|
+
|
39
|
+
def formatted_exception
|
40
|
+
return {} unless @exception
|
41
|
+
{
|
42
|
+
:backtrace => @exception.backtrace,
|
43
|
+
:exception => @exception.name,
|
44
|
+
:message => @exception.message
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def formatted_events
|
49
|
+
@events.map do |event|
|
50
|
+
{
|
51
|
+
:name => event.name,
|
52
|
+
:duration => event.duration,
|
53
|
+
:time => event.time,
|
54
|
+
:end => event.end,
|
55
|
+
:payload => event.payload
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def formatted_log_entry
|
61
|
+
@log_entry.payload.merge(
|
62
|
+
:duration => @log_entry.duration,
|
63
|
+
:time => @log_entry.time,
|
64
|
+
:end => @log_entry.end,
|
65
|
+
:name => request.fullpath,
|
66
|
+
:environment => Rails.env,
|
67
|
+
:server => @env['SERVER_NAME']
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_hash
|
72
|
+
{
|
73
|
+
:request_id => @id,
|
74
|
+
:log_entry => formatted_log_entry,
|
75
|
+
:events => formatted_events,
|
76
|
+
:exception => formatted_exception,
|
77
|
+
:failed => exception.present?
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
def complete!
|
82
|
+
Thread.current[:justlogging_transaction_id] = nil
|
83
|
+
current_transaction = Justlogging.transactions.delete(@id)
|
84
|
+
if @events.any? || @exception.present?
|
85
|
+
Justlogging.agent.add_to_queue(
|
86
|
+
current_transaction.to_hash
|
87
|
+
)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/justlogging.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
raise 'This justlogging gem only works with rails' unless defined?(Rails)
|
2
|
+
require 'net/http'
|
3
|
+
require 'net/https'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
module Justlogging
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_accessor :subscriber
|
10
|
+
|
11
|
+
def transactions
|
12
|
+
@transactions ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def agent
|
16
|
+
@agent ||= Justlogging::Agent.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def config
|
20
|
+
@config ||= {:ignore_exceptions => []}.merge(YAML.load_file("#{Rails.root}/config/justlogging.yml")[Rails.env].symbolize_keys)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'justlogging/agent'
|
27
|
+
require 'justlogging/middleware'
|
28
|
+
require 'justlogging/transaction'
|
29
|
+
require 'justlogging/exception_notification'
|
30
|
+
require 'justlogging/version'
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Justlogging::Agent do
|
4
|
+
before :each do
|
5
|
+
Thread.stub(:new)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:agent) { Justlogging::Agent.new }
|
9
|
+
let(:event) { stub(:name => 'event') }
|
10
|
+
|
11
|
+
describe '#add_to_queue' do
|
12
|
+
it 'should add the event to the queue' do
|
13
|
+
expect {
|
14
|
+
agent.add_to_queue(event)
|
15
|
+
}.to change(agent, :queue).to([event])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#send_queue' do
|
20
|
+
before do
|
21
|
+
agent.add_to_queue(event)
|
22
|
+
ActiveSupport::JSON.stub(:encode => '{"abc":"def"}')
|
23
|
+
Net::HTTP.stub(:post_form).and_return(stub(:code => '200'))
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should call Net::HTTP.post_form with the correct params' do
|
27
|
+
Net::HTTP.should_receive(:post_form).with(
|
28
|
+
URI('http://localhost:3000/api/1/log_entries'),
|
29
|
+
'api_key' => 'abc',
|
30
|
+
'log_entries' => '{"abc":"def"}'
|
31
|
+
).and_return(stub(:code => '200'))
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should call handle_result" do
|
35
|
+
agent.should_receive(:handle_result).with('200')
|
36
|
+
end
|
37
|
+
|
38
|
+
after { agent.send_queue }
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#handle_result' do
|
42
|
+
before do
|
43
|
+
agent.add_to_queue(event)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should empty the queue for 200" do
|
47
|
+
expect {
|
48
|
+
agent.handle_result('200')
|
49
|
+
}.to change(agent, :queue).to([])
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should raise the sleep_time time for 403" do
|
53
|
+
expect {
|
54
|
+
agent.handle_result('403')
|
55
|
+
}.to change(agent, :sleep_time).to(7.5)
|
56
|
+
end
|
57
|
+
|
58
|
+
context "any other response" do
|
59
|
+
|
60
|
+
it "should deactivate for any other response code" do
|
61
|
+
expect {
|
62
|
+
agent.handle_result('500')
|
63
|
+
}.to change(agent, :active).to(false)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should unsubscribe from the justlogging subscriber" do
|
67
|
+
ActiveSupport::Notifications.should_receive(:unsubscribe)
|
68
|
+
agent.handle_result('500')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Justlogging::ExceptionNotification do
|
4
|
+
before { Rails.stub(:respond_to? => false) }
|
5
|
+
let(:error) { StandardError.new('moo') }
|
6
|
+
let(:notification) { Justlogging::ExceptionNotification.new({}, error) }
|
7
|
+
subject { notification }
|
8
|
+
|
9
|
+
its(:exception) { should == error }
|
10
|
+
its(:name) { should == 'StandardError' }
|
11
|
+
its(:message) { should == 'moo' }
|
12
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Justlogging
|
4
|
+
class IgnoreMeError < StandardError
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class AppWithError
|
9
|
+
|
10
|
+
def self.call(env)
|
11
|
+
raise Justlogging::IgnoreMeError, 'the roof'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Justlogging::Middleware do
|
16
|
+
|
17
|
+
describe '#call' do
|
18
|
+
let(:app) { stub(:call => true) }
|
19
|
+
let(:env) { {'action_dispatch.request_id' => '1'} }
|
20
|
+
let(:middleware) { Justlogging::Middleware.new(app, {})}
|
21
|
+
let(:current) { stub(:complete! => true, :add_exception => true) }
|
22
|
+
before { Justlogging::Transaction.stub(:current => current) }
|
23
|
+
|
24
|
+
describe 'around call' do
|
25
|
+
|
26
|
+
it 'should call justlogging transaction' do
|
27
|
+
Justlogging::Transaction.should_receive(:create).with('1', env)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should call complete! after the call' do
|
31
|
+
current.should_receive(:complete!)
|
32
|
+
end
|
33
|
+
|
34
|
+
after { middleware.call(env) }
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'with exception' do
|
38
|
+
let(:app) { AppWithError }
|
39
|
+
|
40
|
+
it 'should re-raise the exception' do
|
41
|
+
expect {
|
42
|
+
middleware.call(env)
|
43
|
+
}.to raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should catch the exception and notify the transaction of it' do
|
47
|
+
Justlogging::ExceptionNotification.should_receive(:new)
|
48
|
+
current.should_receive(:add_exception)
|
49
|
+
middleware.call(env) rescue nil
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'when ignoring exception' do
|
53
|
+
before { Justlogging.stub(:config => {:ignore_exceptions => 'Justlogging::IgnoreMeError'})}
|
54
|
+
|
55
|
+
it 'should re-raise the exception' do
|
56
|
+
expect {
|
57
|
+
middleware.call(env)
|
58
|
+
}.to raise_error
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should ignore the error' do
|
62
|
+
Justlogging::ExceptionNotification.should_not_receive(:new)
|
63
|
+
current.should_not_receive(:add_exception)
|
64
|
+
middleware.call(env) rescue nil
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'after an error' do
|
70
|
+
|
71
|
+
it 'should call complete! after the call' do
|
72
|
+
current.should_receive(:complete!)
|
73
|
+
end
|
74
|
+
|
75
|
+
after { middleware.call(env) rescue nil }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'action_controller/railtie'
|
3
|
+
require 'justlogging/railtie'
|
4
|
+
|
5
|
+
describe Justlogging::Railtie do
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
MyApp::Application.initialize!
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should have set the justlogging subscriber" do
|
12
|
+
Justlogging.subscriber.should be_a ActiveSupport::Notifications::Fanout::Subscriber
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have added the middleware for exceptions" do
|
16
|
+
MyApp::Application.middleware.middlewares.should include Justlogging::Middleware
|
17
|
+
end
|
18
|
+
|
19
|
+
context "non action_controller event" do
|
20
|
+
|
21
|
+
it "should call add_event for non action_controller event" do
|
22
|
+
current = stub
|
23
|
+
current.should_receive(:add_event)
|
24
|
+
Justlogging::Transaction.should_receive(:current).and_return(current)
|
25
|
+
end
|
26
|
+
|
27
|
+
after do
|
28
|
+
ActiveSupport::Notifications.instrument 'query.mongoid'
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
context "action_controller event" do
|
34
|
+
|
35
|
+
it "should call set_log_entry for action_controller event" do
|
36
|
+
current = stub
|
37
|
+
current.should_receive(:set_log_entry)
|
38
|
+
Justlogging::Transaction.should_receive(:current).and_return(current)
|
39
|
+
end
|
40
|
+
|
41
|
+
after do
|
42
|
+
ActiveSupport::Notifications.instrument 'process_action.action_controller'
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Justlogging::Transaction do
|
4
|
+
|
5
|
+
describe '.create' do
|
6
|
+
before { Justlogging::Transaction.create('1', {}) }
|
7
|
+
|
8
|
+
it 'should add the id to the thread' do
|
9
|
+
Thread.current[:justlogging_transaction_id].should == '1'
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should add the transaction to the list' do
|
13
|
+
Justlogging.transactions['1'].should be_a Justlogging::Transaction
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.current' do
|
18
|
+
let(:transaction) { Justlogging::Transaction.create('1', {}) }
|
19
|
+
before { transaction }
|
20
|
+
subject { Justlogging::Transaction.current }
|
21
|
+
|
22
|
+
it 'should return the correct transaction' do
|
23
|
+
should eq transaction
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'transaction instance' do
|
28
|
+
let(:transaction) { Justlogging::Transaction.create('1', {'SERVER_NAME' => 'localhost'}) }
|
29
|
+
|
30
|
+
describe '#request' do
|
31
|
+
subject { transaction.request }
|
32
|
+
|
33
|
+
it { should be_a ActionDispatch::Request }
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#set_log_entry' do
|
37
|
+
let(:log_entry) {stub(:name => 'test') }
|
38
|
+
|
39
|
+
it 'should add a log entry' do
|
40
|
+
expect {
|
41
|
+
transaction.set_log_entry(log_entry)
|
42
|
+
}.to change(transaction, :log_entry).to(log_entry)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#add_exception' do
|
47
|
+
let(:exception) {stub(:name => 'test') }
|
48
|
+
|
49
|
+
it 'should add an exception' do
|
50
|
+
expect {
|
51
|
+
transaction.add_exception(exception)
|
52
|
+
}.to change(transaction, :exception).to(exception)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#add_event' do
|
57
|
+
let(:event) {stub(:name => 'test') }
|
58
|
+
|
59
|
+
it 'should add a log entry' do
|
60
|
+
expect {
|
61
|
+
transaction.add_event(event)
|
62
|
+
}.to change(transaction, :events).to([event])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#formatted_exception' do
|
67
|
+
let(:exception) { stub(:backtrace => ['test'], :name => 'Justlogging::Error', :message => 'nooo') }
|
68
|
+
|
69
|
+
before { transaction.add_exception(exception) }
|
70
|
+
|
71
|
+
subject { transaction.formatted_exception }
|
72
|
+
|
73
|
+
it 'should return a formatted exception' do
|
74
|
+
should == {
|
75
|
+
:backtrace => ['test'],
|
76
|
+
:exception => 'Justlogging::Error',
|
77
|
+
:message => 'nooo'
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#formatted_events' do
|
83
|
+
let(:start_time) { Time.parse('01-01-2001 10:00:00') }
|
84
|
+
let(:end_time) { Time.parse('01-01-2001 10:00:01') }
|
85
|
+
let(:event) { stub(:name => 'name', :duration => 2, :time => start_time, :end => end_time, :payload => {}) }
|
86
|
+
|
87
|
+
before { transaction.add_event(event) }
|
88
|
+
|
89
|
+
subject { transaction.formatted_events }
|
90
|
+
|
91
|
+
it 'should return formatted events' do
|
92
|
+
should == [{:name=>'name', :duration=>2, :time=>start_time, :end=>end_time, :payload=>{}}]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#formatted_log_entry' do
|
97
|
+
let(:start_time) { Time.parse('01-01-2001 10:00:00') }
|
98
|
+
let(:end_time) { Time.parse('01-01-2001 10:00:01') }
|
99
|
+
let(:log_entry) { stub(:name => 'name', :duration => 2, :time => start_time, :end => end_time, :payload => {:controller => 'JustSayinController'}) }
|
100
|
+
let(:request) { stub(:fullpath => '/blog') }
|
101
|
+
|
102
|
+
before { transaction.stub(:request => request) }
|
103
|
+
before { transaction.set_log_entry(log_entry) }
|
104
|
+
|
105
|
+
subject { transaction.formatted_log_entry }
|
106
|
+
|
107
|
+
it 'should return formatted log_entry' do
|
108
|
+
should == {
|
109
|
+
:controller => 'JustSayinController',
|
110
|
+
:duration => 2,
|
111
|
+
:time => start_time,
|
112
|
+
:end => end_time,
|
113
|
+
:name => '/blog',
|
114
|
+
:environment => "development",
|
115
|
+
:server => 'localhost'
|
116
|
+
}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#to_hash' do
|
121
|
+
before { transaction.stub(
|
122
|
+
:formatted_log_entry => {:name => 'log_entry'},
|
123
|
+
:formatted_events => [{:name => 'event'}],
|
124
|
+
:formatted_exception => {:name => 'exception'},
|
125
|
+
:failed => false
|
126
|
+
)}
|
127
|
+
|
128
|
+
subject { transaction.to_hash }
|
129
|
+
|
130
|
+
it 'should return a formatted hash of the transaction data' do
|
131
|
+
should == {
|
132
|
+
:request_id => '1',
|
133
|
+
:log_entry => {:name => 'log_entry'},
|
134
|
+
:events => [{:name => 'event'}],
|
135
|
+
:exception => {:name => 'exception'},
|
136
|
+
:failed => false
|
137
|
+
}
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe '#complete!' do
|
142
|
+
before { transaction }
|
143
|
+
|
144
|
+
it 'should remove transaction from the queue' do
|
145
|
+
expect {
|
146
|
+
transaction.complete!
|
147
|
+
}.to change(Justlogging.transactions, :length).by(-1)
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'calling the justlogging agent' do
|
151
|
+
|
152
|
+
context 'without events and exception' do
|
153
|
+
it 'should not add transaction to the agent' do
|
154
|
+
Justlogging.agent.should_not_receive(:add_to_queue)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'with events' do
|
159
|
+
before { transaction.add_event(stub) }
|
160
|
+
before { transaction.stub(:to_hash => {})}
|
161
|
+
|
162
|
+
it 'should add transaction to the agent' do
|
163
|
+
Justlogging.agent.should_receive(:add_to_queue)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context 'with exception' do
|
168
|
+
before { transaction.add_exception(stub) }
|
169
|
+
before { transaction.stub(:to_hash => {})}
|
170
|
+
|
171
|
+
it 'should add transaction to the agent' do
|
172
|
+
Justlogging.agent.should_receive(:add_to_queue)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
after { transaction.complete! }
|
177
|
+
end
|
178
|
+
|
179
|
+
context 'thread' do
|
180
|
+
before { transaction.complete! }
|
181
|
+
|
182
|
+
it 'should reset the thread transaction id' do
|
183
|
+
Thread.current[:justlogging_transaction_id].should be_nil
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Justlogging do
|
4
|
+
|
5
|
+
it { should respond_to :subscriber }
|
6
|
+
|
7
|
+
describe ".transactions" do
|
8
|
+
subject { Justlogging.transactions }
|
9
|
+
|
10
|
+
it { should be_a Hash }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '.agent' do
|
14
|
+
subject { Justlogging.agent }
|
15
|
+
|
16
|
+
it { should be_a Justlogging::Agent }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '.config' do
|
20
|
+
subject { Justlogging.config }
|
21
|
+
|
22
|
+
it 'should return the endpoint' do
|
23
|
+
subject[:endpoint].should eq 'http://localhost:3000/api/1/log_entries'
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should return the api key' do
|
27
|
+
subject[:api_key].should eq 'abc'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should return ignored exceptions' do
|
31
|
+
subject[:ignore_exceptions].should eq []
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'rails'
|
3
|
+
|
4
|
+
module Rails
|
5
|
+
class Application
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module MyApp
|
10
|
+
class Application < Rails::Application
|
11
|
+
config.active_support.deprecation = proc { |message, stack| }
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'justlogging'
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: justlogging-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Robert Beekman
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
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: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: The official justlogging.com gem
|
79
|
+
email:
|
80
|
+
- robert@80beans.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- !binary |-
|
86
|
+
LmdpdGlnbm9yZQ==
|
87
|
+
- !binary |-
|
88
|
+
LnJ2bXJj
|
89
|
+
- !binary |-
|
90
|
+
R2VtZmlsZQ==
|
91
|
+
- !binary |-
|
92
|
+
R2VtZmlsZS5sb2Nr
|
93
|
+
- !binary |-
|
94
|
+
UkVBRE1FLm1k
|
95
|
+
- !binary |-
|
96
|
+
Y29uZmlnL2p1c3Rsb2dnaW5nLnltbA==
|
97
|
+
- !binary |-
|
98
|
+
ZG9jL2p1c3Rsb2dnaW5nLW1vbmdvLm1hcmtkb3du
|
99
|
+
- !binary |-
|
100
|
+
anVzdGxvZ2dpbmctcmFpbHMuZ2Vtc3BlYw==
|
101
|
+
- !binary |-
|
102
|
+
bGliL2p1c3Rsb2dnaW5nLnJi
|
103
|
+
- !binary |-
|
104
|
+
bGliL2p1c3Rsb2dnaW5nL2FnZW50LnJi
|
105
|
+
- !binary |-
|
106
|
+
bGliL2p1c3Rsb2dnaW5nL2V4Y2VwdGlvbl9ub3RpZmljYXRpb24ucmI=
|
107
|
+
- !binary |-
|
108
|
+
bGliL2p1c3Rsb2dnaW5nL21pZGRsZXdhcmUucmI=
|
109
|
+
- !binary |-
|
110
|
+
bGliL2p1c3Rsb2dnaW5nL3JhaWx0aWUucmI=
|
111
|
+
- !binary |-
|
112
|
+
bGliL2p1c3Rsb2dnaW5nL3RyYW5zYWN0aW9uLnJi
|
113
|
+
- !binary |-
|
114
|
+
bGliL2p1c3Rsb2dnaW5nL3ZlcnNpb24ucmI=
|
115
|
+
- !binary |-
|
116
|
+
c3BlYy9qdXN0bG9nZ2luZy9hZ2VudF9zcGVjLnJi
|
117
|
+
- !binary |-
|
118
|
+
c3BlYy9qdXN0bG9nZ2luZy9leGNlcHRpb25fbm90aWZpY2F0aW9uX3NwZWMu
|
119
|
+
cmI=
|
120
|
+
- !binary |-
|
121
|
+
c3BlYy9qdXN0bG9nZ2luZy9taWRkbGV3YXJlX3NwZWMucmI=
|
122
|
+
- !binary |-
|
123
|
+
c3BlYy9qdXN0bG9nZ2luZy9yYWlsdGllX3NwZWMucmI=
|
124
|
+
- !binary |-
|
125
|
+
c3BlYy9qdXN0bG9nZ2luZy90cmFuc2FjdGlvbl9zcGVjLnJi
|
126
|
+
- !binary |-
|
127
|
+
c3BlYy9qdXN0bG9nZ2luZ19zcGVjLnJi
|
128
|
+
- !binary |-
|
129
|
+
c3BlYy9zcGVjX2hlbHBlci5yYg==
|
130
|
+
homepage: http://github.com/80beans/justlogging-rails
|
131
|
+
licenses: []
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
none: false
|
144
|
+
requirements:
|
145
|
+
- - ! '>='
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
requirements: []
|
149
|
+
rubyforge_project:
|
150
|
+
rubygems_version: 1.8.24
|
151
|
+
signing_key:
|
152
|
+
specification_version: 3
|
153
|
+
summary: Logs rails's notifications to justlogging.com
|
154
|
+
test_files:
|
155
|
+
- !binary |-
|
156
|
+
c3BlYy9qdXN0bG9nZ2luZy9hZ2VudF9zcGVjLnJi
|
157
|
+
- !binary |-
|
158
|
+
c3BlYy9qdXN0bG9nZ2luZy9leGNlcHRpb25fbm90aWZpY2F0aW9uX3NwZWMu
|
159
|
+
cmI=
|
160
|
+
- !binary |-
|
161
|
+
c3BlYy9qdXN0bG9nZ2luZy9taWRkbGV3YXJlX3NwZWMucmI=
|
162
|
+
- !binary |-
|
163
|
+
c3BlYy9qdXN0bG9nZ2luZy9yYWlsdGllX3NwZWMucmI=
|
164
|
+
- !binary |-
|
165
|
+
c3BlYy9qdXN0bG9nZ2luZy90cmFuc2FjdGlvbl9zcGVjLnJi
|
166
|
+
- !binary |-
|
167
|
+
c3BlYy9qdXN0bG9nZ2luZ19zcGVjLnJi
|
168
|
+
- !binary |-
|
169
|
+
c3BlYy9zcGVjX2hlbHBlci5yYg==
|