justlogging-rails 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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==
|