yarder 0.0.2 → 0.1.0
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/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
|