yarder 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +24 -13
- data/lib/yarder/action_controller/log_subscriber.rb +24 -24
- data/lib/yarder/action_view/log_subscriber.rb +4 -1
- data/lib/yarder/active_record/log_subscriber.rb +10 -6
- data/lib/yarder/active_resource/log_subscriber.rb +6 -7
- data/lib/yarder/event.rb +13 -19
- data/lib/yarder/logger.rb +17 -1
- data/lib/yarder/rack/logger.rb +23 -20
- data/lib/yarder/tagged_logging.rb +4 -3
- data/lib/yarder/version.rb +1 -1
- data/test/action_controller/log_subscriber_test.rb +24 -23
- data/test/action_view/log_subscriber_test.rb +11 -3
- data/test/active_record/log_subscriber_test.rb +31 -11
- data/test/active_resource/log_subscriber_test.rb +28 -8
- data/test/dummy/config/application.rb +2 -2
- data/test/dummy/log/test.log +702 -0
- data/test/logger_test.rb +10 -0
- data/test/rack/logger_test.rb +38 -13
- data/test/tagged_logging_test.rb +38 -40
- metadata +62 -49
- checksums.yaml +0 -7
data/README.md
CHANGED
@@ -7,16 +7,16 @@
|
|
7
7
|
|
8
8
|
JSON Based Replacement logging system for Ruby on Rails.
|
9
9
|
|
10
|
-
This is an experimental gem to see how easy / difficult it is to completely replace the default Ruby
|
10
|
+
This is an experimental gem to see how easy / difficult it is to completely replace the default Ruby
|
11
11
|
on Rails logging system with one based on outputting JSON messages.
|
12
12
|
|
13
|
-
This gem will create JSON based log entries designed for consumption by Logstash (although being
|
14
|
-
JSON they can be read by other software). The JSON will contain the same information as can be found
|
13
|
+
This gem will create JSON based log entries designed for consumption by Logstash (although being
|
14
|
+
JSON they can be read by other software). The JSON will contain the same information as can be found
|
15
15
|
in the default rails logging output.
|
16
16
|
|
17
17
|
## Current Status
|
18
18
|
|
19
|
-
This gem is not production ready however it is probably ready for people interested in seeing the
|
19
|
+
This gem is not production ready however it is probably ready for people interested in seeing the
|
20
20
|
results. All logging in a Rails3 app should be JSON formatted, including ad-hoc logging.
|
21
21
|
|
22
22
|
Yarder has only been tested against Rails 3.2.8 on Ruby 1.9.3 and JRuby running in 1.9 mode. Test
|
@@ -26,9 +26,12 @@ unique to this gem still need to be created.
|
|
26
26
|
There may be issues regarding outputting UTF-8 characters in logs on JRuby 1.6 in --1.9 mode. JRuby
|
27
27
|
1.7 is recommended (These same issues exist in the man ruby loggers so use that as a guide).
|
28
28
|
|
29
|
-
Any help, feedback or pull-requests would be much appreciated, especially related to refactoring and
|
29
|
+
Any help, feedback or pull-requests would be much appreciated, especially related to refactoring and
|
30
30
|
test improvement
|
31
31
|
|
32
|
+
Version 0.1.0 of this gem is designed for logstash 1.2 and Kibana version 3. If you are using an older
|
33
|
+
version then it is probably best to stick with 0.0.2
|
34
|
+
|
32
35
|
## Installation
|
33
36
|
|
34
37
|
Add this line to your Rails application's Gemfile:
|
@@ -57,16 +60,19 @@ module MyApp
|
|
57
60
|
|
58
61
|
# Set a logger compatible with the standard ruby logger to be used by Yarder
|
59
62
|
config.logger = Yarder::Logger.new(Rails.root.join('log',"#{Rails.env}.log").to_s)
|
60
|
-
|
63
|
+
# Logs AR SQL queries in debug level
|
64
|
+
config.logger.level = Logger::DEBUG
|
65
|
+
# Root name of nested logs, formerly known as :fields
|
66
|
+
config.logger.log_namespace = :rails
|
67
|
+
# Logstash logtype
|
68
|
+
config.logger.log_type = :rails_json_log
|
61
69
|
end
|
62
70
|
end
|
63
71
|
```
|
64
72
|
|
65
73
|
## Logstash Configuration
|
66
74
|
|
67
|
-
Yarder currently creates log entries with
|
68
|
-
in future and may become configurable) therefore your Logstash configuration file should be as
|
69
|
-
follows:
|
75
|
+
Yarder currently creates log entries with default logtype of "rails_json_log" therefore your Logstash configuration file should be as follows:
|
70
76
|
|
71
77
|
```
|
72
78
|
input {
|
@@ -78,7 +84,14 @@ input {
|
|
78
84
|
}
|
79
85
|
```
|
80
86
|
|
81
|
-
|
87
|
+
### Beaver
|
88
|
+
|
89
|
+
```
|
90
|
+
[/var/www/rails/application-1/log/production.log]
|
91
|
+
format: rawjson
|
92
|
+
```
|
93
|
+
|
94
|
+
You will need to edit the path to point to your application's log file. Because Yarder creates json
|
82
95
|
serialized Logstash::Event entries there is no need to setup any filters
|
83
96
|
|
84
97
|
### Known issues
|
@@ -88,7 +101,7 @@ for nested JSON but logstash web does not.
|
|
88
101
|
|
89
102
|
## Developers
|
90
103
|
|
91
|
-
Thoughts, suggestions, opinions and contributions are welcome.
|
104
|
+
Thoughts, suggestions, opinions and contributions are welcome.
|
92
105
|
|
93
106
|
When contributing please make sure to run your tests with warnings enabled and make sure that
|
94
107
|
yarder creates no warnings. (Warnings from other libraries like capybara etc. are ok)
|
@@ -96,5 +109,3 @@ yarder creates no warnings. (Warnings from other libraries like capybara etc. ar
|
|
96
109
|
```
|
97
110
|
RUBYOPT=-w rake
|
98
111
|
```
|
99
|
-
|
100
|
-
|
@@ -8,58 +8,50 @@ module Yarder
|
|
8
8
|
def start_processing(event)
|
9
9
|
payload = event.payload
|
10
10
|
|
11
|
-
entry
|
12
|
-
entry
|
13
|
-
|
14
|
-
format = payload[:format]
|
15
|
-
entry.fields['format'] = format.to_s.downcase if format.is_a?(Symbol)
|
16
|
-
|
11
|
+
entry['name'] = payload[:controller]
|
12
|
+
entry['action'] = payload[:action]
|
13
|
+
entry['path'] = payload[:path]
|
14
|
+
entry['format'] = payload[:format].to_s.downcase
|
17
15
|
end
|
18
16
|
|
19
17
|
def process_action(event)
|
20
|
-
|
21
18
|
payload = event.payload
|
22
|
-
#TODO Think about additions. Comment out for the moment to shut up warnings
|
23
|
-
#additions = ::ActionController::Base.log_process_action(payload)
|
24
19
|
|
25
20
|
params = payload[:params].except(*INTERNAL_PARAMS)
|
26
|
-
entry
|
27
|
-
|
28
|
-
entry.fields['controller_duration'] = event.duration
|
29
|
-
|
30
|
-
#TODO What on earth are additions and how should we handle them?
|
31
|
-
# message << " (#{additions.join(" | ")})" unless additions.blank?
|
21
|
+
entry['parameters'] = params unless params.empty?
|
32
22
|
|
23
|
+
root['duration']['controller'] = event.duration
|
33
24
|
end
|
34
25
|
|
35
26
|
def halted_callback(event)
|
36
|
-
entry
|
27
|
+
entry['halted_callback'] = event.payload[:filter]
|
37
28
|
end
|
38
29
|
|
39
30
|
def send_file(event)
|
40
|
-
entry
|
41
|
-
|
31
|
+
entry['send_file'] = event.payload[:path]
|
32
|
+
root['duration']['send_file'] = event.duration
|
42
33
|
end
|
43
34
|
|
44
35
|
def redirect_to(event)
|
45
|
-
entry
|
36
|
+
entry['redirect_to'] = event.payload[:location]
|
46
37
|
end
|
47
38
|
|
48
39
|
def send_data(event)
|
49
|
-
entry
|
50
|
-
|
40
|
+
entry['send_data'] = event.payload[:filename]
|
41
|
+
root['duration']['send_data'] = event.duration
|
51
42
|
end
|
52
43
|
|
53
44
|
%w(write_fragment read_fragment exist_fragment?
|
54
45
|
expire_fragment expire_page write_page).each do |method|
|
55
46
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
56
47
|
def #{method}(event)
|
57
|
-
entry.fields['cache'] ||= []
|
58
48
|
cache_event = {}
|
59
49
|
cache_event['key_or_path'] = event.payload[:key] || event.payload[:path]
|
60
50
|
cache_event['type'] = #{method.to_s.humanize.inspect}
|
61
51
|
cache_event['duration'] = event.duration
|
62
|
-
|
52
|
+
cache << cache_event
|
53
|
+
root['duration']['cache'] ||= 0
|
54
|
+
root['duration']['cache'] += event.duration.to_f
|
63
55
|
end
|
64
56
|
METHOD
|
65
57
|
end
|
@@ -67,7 +59,15 @@ module Yarder
|
|
67
59
|
private
|
68
60
|
|
69
61
|
def entry
|
70
|
-
|
62
|
+
@entry ||= (root['controller'] ||= {})
|
63
|
+
end
|
64
|
+
|
65
|
+
def cache
|
66
|
+
@cache ||= (root['cache'] ||= [])
|
67
|
+
end
|
68
|
+
|
69
|
+
def root
|
70
|
+
@root ||= Yarder.log_entries[Thread.current].fields.tap { |o| o['duration'] ||= {} }
|
71
71
|
end
|
72
72
|
|
73
73
|
end
|
@@ -4,14 +4,17 @@ module Yarder
|
|
4
4
|
class LogSubscriber < ::ActiveSupport::LogSubscriber
|
5
5
|
|
6
6
|
def render_template(event)
|
7
|
-
entry.fields['rendering'] ||= []
|
8
7
|
render_entry = {}
|
9
8
|
render_entry['identifier'] = from_rails_root(event.payload[:identifier])
|
10
9
|
render_entry['layout'] = from_rails_root(event.payload[:layout]) if event.payload[:layout]
|
11
10
|
render_entry['duration'] = event.duration
|
12
11
|
|
12
|
+
entry.fields['rendering'] ||= []
|
13
13
|
entry.fields['rendering'] << render_entry
|
14
14
|
|
15
|
+
entry.fields['duration'] ||= {}
|
16
|
+
entry.fields['duration']['rendering'] ||= 0
|
17
|
+
entry.fields['duration']['rendering'] += event.duration.to_f
|
15
18
|
end
|
16
19
|
alias :render_partial :render_template
|
17
20
|
alias :render_collection :render_template
|
@@ -66,6 +66,10 @@ module Yarder
|
|
66
66
|
entry = log_entry
|
67
67
|
entry.fields['sql'] ||= []
|
68
68
|
entry.fields['sql'] << sql_entry
|
69
|
+
|
70
|
+
entry.fields['duration'] ||= {}
|
71
|
+
entry.fields['duration']['sql'] ||= 0
|
72
|
+
entry.fields['duration']['sql'] += sql_entry['duration'].to_f
|
69
73
|
entry.write(false)
|
70
74
|
end
|
71
75
|
|
@@ -74,12 +78,12 @@ module Yarder
|
|
74
78
|
end
|
75
79
|
|
76
80
|
def log_entry
|
77
|
-
Yarder.log_entries[Thread.current] ||
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
81
|
+
Yarder.log_entries[Thread.current] || Yarder::Event.create(Rails.logger, tags)
|
82
|
+
end
|
83
|
+
|
84
|
+
def tags
|
85
|
+
if log_tags = Rails.configuration.log_tags
|
86
|
+
log_tags.select{|tag| tag.is_a? String}
|
83
87
|
end
|
84
88
|
end
|
85
89
|
|
@@ -3,12 +3,7 @@ module Yarder
|
|
3
3
|
class LogSubscriber < ::ActiveSupport::LogSubscriber
|
4
4
|
|
5
5
|
def request(event)
|
6
|
-
|
7
|
-
#TODO Think of a better name for this!
|
8
|
-
entry.fields['active_resource'] ||= []
|
9
|
-
|
10
6
|
request_entry = {}
|
11
|
-
|
12
7
|
request_entry['method'] = event.payload[:method].to_s.upcase
|
13
8
|
request_entry['uri'] = event.payload[:request_uri]
|
14
9
|
|
@@ -19,7 +14,12 @@ module Yarder
|
|
19
14
|
request_entry['length'] = result.body.to_s.length
|
20
15
|
request_entry['duration'] = event.duration
|
21
16
|
|
22
|
-
entry.fields['
|
17
|
+
entry.fields['rest'] ||= []
|
18
|
+
entry.fields['rest'] << request_entry
|
19
|
+
|
20
|
+
entry.fields['duration'] ||= {}
|
21
|
+
entry.fields['duration']['rest'] ||= 0
|
22
|
+
entry.fields['duration']['rest'] += event.duration.to_f
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
@@ -31,4 +31,3 @@ module Yarder
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
34
|
-
|
data/lib/yarder/event.rb
CHANGED
@@ -3,14 +3,18 @@ module Yarder
|
|
3
3
|
# Basically a wrapper for a LogStash event that keeps track of if it was created from a rack
|
4
4
|
# middle-ware or not. This is important when it comes to deciding when to write the log
|
5
5
|
class Event
|
6
|
-
|
7
6
|
extend Forwardable
|
8
|
-
def_delegators :@logstash_event, :
|
7
|
+
def_delegators :@logstash_event, :[]=, :[], :to_json
|
9
8
|
|
10
9
|
def initialize(logger, rack = false)
|
11
10
|
@logger = logger
|
12
11
|
@rack = rack
|
13
12
|
@logstash_event = LogStash::Event.new
|
13
|
+
|
14
|
+
self['type'] = logger.log_type
|
15
|
+
self['tags'] ||= []
|
16
|
+
self.fields['duration'] = {}
|
17
|
+
self.fields['env'] = logger.env
|
14
18
|
end
|
15
19
|
|
16
20
|
def write(rack = false)
|
@@ -21,24 +25,14 @@ module Yarder
|
|
21
25
|
end
|
22
26
|
end
|
23
27
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
27
|
-
tags.each do |tag|
|
28
|
-
case tag
|
29
|
-
when Symbol
|
30
|
-
tag_hash << {tag.to_s => request.send(tag) }
|
31
|
-
when Proc
|
32
|
-
tag_hash << tag.call(request)
|
33
|
-
else
|
34
|
-
tag_hash << tag
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
@logger.push_request_tags(tag_hash)
|
28
|
+
def self.create(logger, tags, rack = false)
|
29
|
+
logger.push_request_tags(tags) if tags
|
30
|
+
new(logger, rack)
|
40
31
|
end
|
41
32
|
|
33
|
+
def fields
|
34
|
+
@fields ||= (@logstash_event[@logger.log_namespace.to_s] ||= {})
|
35
|
+
end
|
42
36
|
end
|
43
37
|
|
44
|
-
end
|
38
|
+
end
|
data/lib/yarder/logger.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'logger'
|
2
|
+
require 'socket'
|
2
3
|
|
3
4
|
module Yarder
|
4
5
|
|
@@ -39,11 +40,26 @@ module Yarder
|
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
43
|
+
attr_accessor :log_type, :log_namespace
|
44
|
+
|
42
45
|
def initialize(*args)
|
43
46
|
super
|
47
|
+
self.log_type = :rails_json_log
|
48
|
+
self.log_namespace = :rails
|
44
49
|
@formatter = SimpleFormatter.new
|
45
50
|
end
|
46
51
|
|
52
|
+
def env
|
53
|
+
@env ||= {
|
54
|
+
:ruby => "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}",
|
55
|
+
:env => Rails.env,
|
56
|
+
:pwd => Dir.pwd,
|
57
|
+
:program => $0,
|
58
|
+
:user => ENV['USER'],
|
59
|
+
:host => ::Socket.gethostname
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
47
63
|
# Simple formatter which only displays the message.
|
48
64
|
class SimpleFormatter < ::Logger::Formatter
|
49
65
|
# This method is invoked when a log event occurs
|
@@ -52,4 +68,4 @@ module Yarder
|
|
52
68
|
end
|
53
69
|
end
|
54
70
|
end
|
55
|
-
end
|
71
|
+
end
|
data/lib/yarder/rack/logger.rb
CHANGED
@@ -13,40 +13,43 @@ module Yarder
|
|
13
13
|
t1 = Time.now
|
14
14
|
request = ActionDispatch::Request.new(env)
|
15
15
|
|
16
|
-
event = Yarder::Event.
|
17
|
-
event
|
18
|
-
event.fields['client_ip'] = request.ip
|
19
|
-
event.fields['method'] = request.request_method
|
20
|
-
event.fields['path'] = request.filtered_path
|
21
|
-
#TODO Should really move this into the base logger
|
22
|
-
event.source = "http://#{Socket.gethostname}#{request.filtered_path}"
|
23
|
-
event.type = "rails_json_log"
|
16
|
+
event = Yarder::Event.create Rails.logger, tags(request), true
|
17
|
+
event['message'] = "#{request.request_method} #{request.filtered_path} for #{request.ip}"
|
24
18
|
|
25
|
-
event.
|
19
|
+
entry = (event.fields['rack'] ||= {})
|
20
|
+
entry['client_ip'] = request.ip
|
21
|
+
entry['method'] = request.request_method
|
22
|
+
entry['path'] = request.filtered_path
|
23
|
+
entry['url'] = request.url
|
26
24
|
|
27
25
|
Yarder.log_entries[Thread.current] = event
|
28
26
|
|
29
27
|
status, headers, response = @app.call(env)
|
30
28
|
[status, headers, response]
|
31
|
-
|
32
29
|
ensure
|
33
30
|
if event
|
34
|
-
|
35
|
-
event.fields['
|
36
|
-
|
37
|
-
['rendering','sql'].each do |type|
|
38
|
-
if event.fields[type] && !event.fields[type].empty?
|
39
|
-
duration = event.fields[type].inject(0) {|result, local_event| result += local_event[:duration].to_f }
|
40
|
-
event.fields["#{type}_duration"] = duration
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
31
|
+
entry['status'] = status
|
32
|
+
event.fields['duration']['total'] = (Time.now - t1)*1000
|
44
33
|
event.write(true)
|
45
34
|
end
|
46
35
|
|
47
36
|
Yarder.log_entries[Thread.current] = nil
|
48
37
|
end
|
49
38
|
|
39
|
+
def tags(request)
|
40
|
+
return unless @tags
|
41
|
+
@tags.reduce([]) do |arr, tag|
|
42
|
+
case tag
|
43
|
+
when Symbol
|
44
|
+
arr << {tag.to_s => request.send(tag) }
|
45
|
+
when Proc
|
46
|
+
arr << tag.call(request)
|
47
|
+
else
|
48
|
+
arr << tag
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
50
53
|
end
|
51
54
|
|
52
55
|
end
|
@@ -24,9 +24,10 @@ module Yarder
|
|
24
24
|
@entry = msg
|
25
25
|
else
|
26
26
|
@entry = Yarder::Event.new(Rails.logger)
|
27
|
-
@entry
|
27
|
+
@entry['message'] = msg
|
28
28
|
end
|
29
|
-
@entry
|
29
|
+
@entry['severity'] = severity
|
30
|
+
|
30
31
|
process_tags(current_tags)
|
31
32
|
process_tags(current_request_tags)
|
32
33
|
#TODO Should we do anything with progname? What about source?
|
@@ -57,7 +58,7 @@ module Yarder
|
|
57
58
|
@entry.fields[k] = v
|
58
59
|
end
|
59
60
|
else
|
60
|
-
@entry
|
61
|
+
@entry['tags'] << tag
|
61
62
|
end
|
62
63
|
end
|
63
64
|
end
|
data/lib/yarder/version.rb
CHANGED
@@ -28,12 +28,13 @@ class ACLogSubscriberTest < ActionController::TestCase
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def test_start_processing
|
31
|
-
get :show, {:
|
31
|
+
get :show, {:attr => 'test'}
|
32
32
|
wait
|
33
33
|
|
34
|
-
assert_equal "LogSubscribersController", @log_entry.fields['controller']
|
35
|
-
assert_equal "show", @log_entry.fields['action']
|
36
|
-
assert_equal "
|
34
|
+
assert_equal "LogSubscribersController", @log_entry.fields['controller']['name']
|
35
|
+
assert_equal "show", @log_entry.fields['controller']['action']
|
36
|
+
assert_equal "/show?attr=test", @log_entry.fields['controller']['path']
|
37
|
+
assert_equal "html", @log_entry.fields['controller']['format']
|
37
38
|
end
|
38
39
|
|
39
40
|
|
@@ -41,28 +42,28 @@ class ACLogSubscriberTest < ActionController::TestCase
|
|
41
42
|
get :never_executed
|
42
43
|
wait
|
43
44
|
|
44
|
-
assert_equal ":redirector" ,@log_entry.fields['halted_callback']
|
45
|
+
assert_equal ":redirector" ,@log_entry.fields['controller']['halted_callback']
|
45
46
|
end
|
46
47
|
|
47
|
-
def
|
48
|
+
def test_controller_duration_action
|
48
49
|
get :show
|
49
50
|
wait
|
50
51
|
|
51
|
-
assert_present @log_entry.fields['
|
52
|
+
assert_present @log_entry.fields['duration']['controller']
|
52
53
|
end
|
53
54
|
|
54
55
|
def test_process_action_without_parameters
|
55
56
|
get :show
|
56
57
|
wait
|
57
58
|
|
58
|
-
assert_blank @log_entry.fields['parameters']
|
59
|
+
assert_blank @log_entry.fields['controller']['parameters']
|
59
60
|
end
|
60
61
|
|
61
62
|
def test_process_action_with_parameters
|
62
63
|
get :show, :id => '10'
|
63
64
|
wait
|
64
65
|
|
65
|
-
assert_equal '10', @log_entry.fields['parameters']['id']
|
66
|
+
assert_equal '10', @log_entry.fields['controller']['parameters']['id']
|
66
67
|
end
|
67
68
|
|
68
69
|
def test_process_action_with_wrapped_parameters
|
@@ -70,8 +71,8 @@ class ACLogSubscriberTest < ActionController::TestCase
|
|
70
71
|
post :show, :id => '10', :name => 'jose'
|
71
72
|
wait
|
72
73
|
|
73
|
-
assert_equal '10', @log_entry.fields['parameters']['id']
|
74
|
-
assert_equal 'jose', @log_entry.fields['parameters']['name']
|
74
|
+
assert_equal '10', @log_entry.fields['controller']['parameters']['id']
|
75
|
+
assert_equal 'jose', @log_entry.fields['controller']['parameters']['name']
|
75
76
|
end
|
76
77
|
|
77
78
|
def test_process_action_with_filter_parameters
|
@@ -80,7 +81,7 @@ class ACLogSubscriberTest < ActionController::TestCase
|
|
80
81
|
get :show, :lifo => 'Pratik', :amount => '420', :step => '1'
|
81
82
|
wait
|
82
83
|
|
83
|
-
params = @log_entry.fields['parameters']
|
84
|
+
params = @log_entry.fields['controller']['parameters']
|
84
85
|
assert_equal '[FILTERED]', params['amount']
|
85
86
|
assert_equal '[FILTERED]', params['lifo']
|
86
87
|
assert_equal '1', params['step']
|
@@ -90,7 +91,7 @@ class ACLogSubscriberTest < ActionController::TestCase
|
|
90
91
|
get :redirector
|
91
92
|
wait
|
92
93
|
|
93
|
-
assert_equal 'http://foo.bar/', @log_entry.fields['redirect_to']
|
94
|
+
assert_equal 'http://foo.bar/', @log_entry.fields['controller']['redirect_to']
|
94
95
|
end
|
95
96
|
|
96
97
|
|
@@ -98,8 +99,8 @@ class ACLogSubscriberTest < ActionController::TestCase
|
|
98
99
|
get :data_sender
|
99
100
|
wait
|
100
101
|
|
101
|
-
assert_equal 'file.txt', @log_entry.fields['send_data']
|
102
|
-
assert_present @log_entry.fields['
|
102
|
+
assert_equal 'file.txt', @log_entry.fields['controller']['send_data']
|
103
|
+
assert_present @log_entry.fields['duration']['send_data']
|
103
104
|
end
|
104
105
|
|
105
106
|
|
@@ -107,8 +108,8 @@ class ACLogSubscriberTest < ActionController::TestCase
|
|
107
108
|
get :file_sender
|
108
109
|
wait
|
109
110
|
|
110
|
-
assert_match 'test/dummy/public/favicon.ico', @log_entry.fields['send_file']
|
111
|
-
assert_present @log_entry.fields['
|
111
|
+
assert_match 'test/dummy/public/favicon.ico', @log_entry.fields['controller']['send_file']
|
112
|
+
assert_present @log_entry.fields['duration']['send_file']
|
112
113
|
end
|
113
114
|
|
114
115
|
def test_with_fragment_cache
|
@@ -123,6 +124,8 @@ class ACLogSubscriberTest < ActionController::TestCase
|
|
123
124
|
|
124
125
|
assert_match('Write fragment', @log_entry.fields['cache'].last['type'])
|
125
126
|
assert_match('views/foo', @log_entry.fields['cache'].last['key_or_path'])
|
127
|
+
|
128
|
+
assert_present @log_entry.fields['duration']['cache']
|
126
129
|
ensure
|
127
130
|
LogSubscribersController.config.perform_caching = true
|
128
131
|
end
|
@@ -144,22 +147,20 @@ class ACLogSubscriberTest < ActionController::TestCase
|
|
144
147
|
LogSubscribersController.config.perform_caching = true
|
145
148
|
end
|
146
149
|
|
147
|
-
=begin TODO Figure out why this last test fails.
|
148
150
|
def test_with_page_cache
|
149
151
|
@controller.config.perform_caching = true
|
150
152
|
get :with_page_cache
|
151
153
|
wait
|
152
154
|
|
153
|
-
|
155
|
+
assert_present @log_entry.fields['cache']
|
154
156
|
|
155
|
-
assert_match('Write page', @log_entry.fields['cache'][
|
156
|
-
assert_match('index.html', @log_entry.fields['cache'][
|
157
|
+
assert_match('Write page', @log_entry.fields['cache'].first['type'])
|
158
|
+
assert_match('index.html', @log_entry.fields['cache'].first['key_or_path'])
|
157
159
|
ensure
|
158
160
|
@controller.config.perform_caching = true
|
159
161
|
end
|
160
|
-
=end
|
161
162
|
|
162
163
|
def logs
|
163
164
|
@logs ||= @logger.logged(:info)
|
164
165
|
end
|
165
|
-
end
|
166
|
+
end
|