lograge 0.0.1 → 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/Gemfile +5 -0
- data/README.md +68 -7
- data/lib/lograge/log_subscriber.rb +82 -12
- data/lib/lograge/rails_ext/rack/logger.rb +2 -1
- data/lib/lograge/railtie.rb +2 -0
- data/lib/lograge/version.rb +1 -1
- data/lib/lograge.rb +51 -12
- data/lograge.gemspec +1 -1
- data/spec/lograge_logsubscriber_spec.rb +168 -5
- data/spec/spec_helper.rb +2 -0
- metadata +32 -12
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -7,6 +7,10 @@ default logging output. Rails' default approach to log everything is great
|
|
|
7
7
|
during development, it's terrible when running it in production. It pretty much
|
|
8
8
|
renders Rails logs useless to me.
|
|
9
9
|
|
|
10
|
+
Lograge is a work in progress. I appreciate constructive feedback and criticism.
|
|
11
|
+
My main goal is to improve Rails' logging and to show people that they don't
|
|
12
|
+
need to stick with its defaults anymore if they don't want to.
|
|
13
|
+
|
|
10
14
|
Instead of trying solving the problem of having multiple lines per request by
|
|
11
15
|
switching Rails' logger for something that outputs syslog lines or adds a
|
|
12
16
|
request token, Lograge replaces Rails' request logging entirely, reducing the
|
|
@@ -30,7 +34,7 @@ Completed 200 OK in 79ms (Views: 78.8ms | ActiveRecord: 0.0ms)
|
|
|
30
34
|
you get a single line with all the important information, like this:
|
|
31
35
|
|
|
32
36
|
```
|
|
33
|
-
GET
|
|
37
|
+
method=GET path=/jobs/833552.json format=json controller=jobs action=show status=200 duration=58.33 view=40.43 db=15.26
|
|
34
38
|
```
|
|
35
39
|
|
|
36
40
|
The second line is easy to grasp with a single glance and still includes all the
|
|
@@ -51,10 +55,44 @@ Enable it for the relevant environments, e.g. production:
|
|
|
51
55
|
```
|
|
52
56
|
# config/environments/production.rb
|
|
53
57
|
MyApp::Application.configure do
|
|
54
|
-
config.lograge.enabled = true
|
|
58
|
+
config.lograge.enabled = true
|
|
59
|
+
end
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
You can also add a hook for own custom data
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
# config/environments/staging.rb
|
|
66
|
+
MyApp::Application.configure do
|
|
67
|
+
config.lograge.enabled = true
|
|
68
|
+
|
|
69
|
+
# custom_options can be a lambda or hash
|
|
70
|
+
# if it's a lambda then it must return a hash
|
|
71
|
+
config.lograge.custom_options = lambda do |event|
|
|
72
|
+
# capture some specific timing values you are interested in
|
|
73
|
+
{:name => "value", :timing => some_float.round(2)}
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Lograge supports multiple output formats. The most common is the default
|
|
79
|
+
lograge format described above. Alternatively, you can also generate JSON
|
|
80
|
+
logs in the json_event format used by [Logstash](http://logstash.net/).
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
# config/environments/production.rb
|
|
84
|
+
MyApp::Application.configure do
|
|
85
|
+
config.lograge.log_format = :logstash
|
|
55
86
|
end
|
|
56
87
|
```
|
|
57
88
|
|
|
89
|
+
*Note:* When using the logstash output, you need to add the additional gem
|
|
90
|
+
`logstash-event`. You can simply add it to your Gemfile like this
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
gem "logstash-event"
|
|
94
|
+
```
|
|
95
|
+
|
|
58
96
|
Done.
|
|
59
97
|
|
|
60
98
|
**Internals**
|
|
@@ -79,16 +117,24 @@ While the LogSubscribers encapsulate most logging pretty nicely, there are still
|
|
|
79
117
|
two lines that show up no matter what. The first line that's output for every
|
|
80
118
|
Rails request, you know, this one:
|
|
81
119
|
|
|
120
|
+
```
|
|
121
|
+
Started GET "/" for 127.0.0.1 at 2012-03-12 17:10:10 +0100
|
|
122
|
+
```
|
|
123
|
+
|
|
82
124
|
And the verbose output coming from rack-cache:
|
|
83
125
|
|
|
126
|
+
```
|
|
127
|
+
cache: [GET /] miss
|
|
128
|
+
```
|
|
129
|
+
|
|
84
130
|
Both are independent of the LogSubscribers, and both need to be shut up using
|
|
85
131
|
different means.
|
|
86
132
|
|
|
87
|
-
For the first one, the starting line of every Rails request log, Lograge
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
133
|
+
For the first one, the starting line of every Rails request log, Lograge
|
|
134
|
+
replaces code in `Rails::Rack::Logger` to remove that particular log line. It's
|
|
135
|
+
not great, but it's just another unnecessary output and would still clutter the
|
|
136
|
+
log files. Maybe a future version of Rails will make this log line an event as
|
|
137
|
+
well.
|
|
92
138
|
|
|
93
139
|
To remove rack-cache's output (which is only enabled if caching in Rails is
|
|
94
140
|
enabled), Lograge disables verbosity for rack-cache, which is unfortunately
|
|
@@ -98,6 +144,9 @@ There, a single line per request. Beautiful.
|
|
|
98
144
|
|
|
99
145
|
**What it doesn't do**
|
|
100
146
|
|
|
147
|
+
Lograge is opinionated, very opinionated. If the stuff below doesn't suit your
|
|
148
|
+
needs, it may not be for you.
|
|
149
|
+
|
|
101
150
|
Lograge removes ActionView logging, which also includes rendering times for
|
|
102
151
|
partials. If you're into those, Lograge is probably not for you. In my honest
|
|
103
152
|
opinion, those rendering times don't belong in the log file, they should be
|
|
@@ -106,6 +155,18 @@ service that allows graphing rendering percentiles. I assume this for everything
|
|
|
106
155
|
that represents a moving target. That kind of data is better off being
|
|
107
156
|
visualized in graphs than dumped (and ignored) in a log file.
|
|
108
157
|
|
|
158
|
+
Lograge doesn't yet log the request parameters. This is something I'm actively
|
|
159
|
+
contemplating, mainly because I want to find a good way to include them, a way
|
|
160
|
+
that fits in with the general spirit of the log output generated by Lograge.
|
|
161
|
+
|
|
162
|
+
**Changes**
|
|
163
|
+
|
|
164
|
+
* Add support for Logstash events (Holger Just, http://github.com/meineerde)
|
|
165
|
+
* Fix for Rails 3.2.9
|
|
166
|
+
* Use keys everywhere (Curt Michols, http://github.com/asenchi)
|
|
167
|
+
* Add `custom_options` to allow adding custom key-value pairs at runtime (Adam
|
|
168
|
+
Cooper, https://github.com/adamcooper)
|
|
169
|
+
|
|
109
170
|
**License**
|
|
110
171
|
|
|
111
172
|
MIT. Code extracted from [Travis CI](http://travis-ci.org).
|
|
@@ -5,31 +5,101 @@ module Lograge
|
|
|
5
5
|
class RequestLogSubscriber < ActiveSupport::LogSubscriber
|
|
6
6
|
def process_action(event)
|
|
7
7
|
payload = event.payload
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
|
|
9
|
+
data = extract_request(payload)
|
|
10
|
+
data.merge! extract_status(payload)
|
|
11
|
+
data.merge! runtimes(event)
|
|
12
|
+
data.merge! location(event)
|
|
13
|
+
data.merge! custom_options(event)
|
|
14
|
+
|
|
15
|
+
logger.info send(:"process_action_#{Lograge.log_format}", data)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
LOGRAGE_FIELDS = [
|
|
19
|
+
:method, :path, :format, :controller, :action, :status, :error,
|
|
20
|
+
:duration, :view, :db, :location
|
|
21
|
+
]
|
|
22
|
+
def process_action_lograge(data)
|
|
23
|
+
fields = LOGRAGE_FIELDS
|
|
24
|
+
fields += (data.keys - LOGRAGE_FIELDS)
|
|
25
|
+
|
|
26
|
+
event = fields.inject([]) do |message, key|
|
|
27
|
+
next message unless data.has_key?(key)
|
|
28
|
+
# Exactly preserve the previous output
|
|
29
|
+
# Parsing this can be ambigious if the error messages contains
|
|
30
|
+
# a single quote
|
|
31
|
+
data[key] = "'#{data[key]}'" if key == :error
|
|
32
|
+
# Ensure that we always have exactly two decimals
|
|
33
|
+
data[key] = "%.2f" % data[key] if data[key].is_a? Numeric
|
|
34
|
+
|
|
35
|
+
message << "#{key}=#{data[key]}"
|
|
36
|
+
message
|
|
37
|
+
end
|
|
38
|
+
event.join(" ")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def process_action_logstash(data)
|
|
42
|
+
event = LogStash::Event.new("@fields" => data)
|
|
43
|
+
event.to_json
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def redirect_to(event)
|
|
47
|
+
Thread.current[:lograge_location] = event.payload[:location]
|
|
12
48
|
end
|
|
13
49
|
|
|
14
50
|
private
|
|
15
51
|
|
|
52
|
+
def extract_request(payload)
|
|
53
|
+
{
|
|
54
|
+
:method => payload[:method],
|
|
55
|
+
:path => payload[:path],
|
|
56
|
+
:format => extract_format(payload),
|
|
57
|
+
:controller => payload[:params]['controller'],
|
|
58
|
+
:action => payload[:params]['action']
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def extract_format(payload)
|
|
63
|
+
if ::ActionPack::VERSION::MAJOR == 3 && ::ActionPack::VERSION::MINOR == 0
|
|
64
|
+
payload[:formats].first
|
|
65
|
+
else
|
|
66
|
+
payload[:format]
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
16
70
|
def extract_status(payload)
|
|
17
71
|
if payload[:status]
|
|
18
|
-
|
|
72
|
+
{ :status => payload[:status].to_i }
|
|
19
73
|
elsif payload[:exception]
|
|
20
74
|
exception, message = payload[:exception]
|
|
21
|
-
|
|
75
|
+
{ :status => 500, :error => "#{exception}:#{message}" }
|
|
76
|
+
else
|
|
77
|
+
{ :status => 0 }
|
|
22
78
|
end
|
|
23
79
|
end
|
|
24
80
|
|
|
81
|
+
def custom_options(event)
|
|
82
|
+
Lograge.custom_options(event) || {}
|
|
83
|
+
end
|
|
84
|
+
|
|
25
85
|
def runtimes(event)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
86
|
+
{
|
|
87
|
+
:duration => event.duration,
|
|
88
|
+
:view => event.payload[:view_runtime],
|
|
89
|
+
:db => event.payload[:db_runtime]
|
|
90
|
+
}.inject({}) do |runtimes, (name, runtime)|
|
|
91
|
+
runtimes[name] = runtime.to_f.round(2) if runtime
|
|
92
|
+
runtimes
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def location(event)
|
|
97
|
+
if location = Thread.current[:lograge_location]
|
|
98
|
+
Thread.current[:lograge_location] = nil
|
|
99
|
+
{ :location => location }
|
|
100
|
+
else
|
|
101
|
+
{}
|
|
31
102
|
end
|
|
32
|
-
message
|
|
33
103
|
end
|
|
34
104
|
end
|
|
35
105
|
end
|
data/lib/lograge/railtie.rb
CHANGED
data/lib/lograge/version.rb
CHANGED
data/lib/lograge.rb
CHANGED
|
@@ -5,32 +5,71 @@ require 'active_support/core_ext/string/inflections'
|
|
|
5
5
|
require 'active_support/ordered_options'
|
|
6
6
|
|
|
7
7
|
module Lograge
|
|
8
|
-
mattr_accessor :logger
|
|
8
|
+
mattr_accessor :logger
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
# Custom options that will be appended to log line
|
|
11
|
+
#
|
|
12
|
+
# Currently supported formats are:
|
|
13
|
+
# - Hash
|
|
14
|
+
# - Any object that responds to call and returns a hash
|
|
15
|
+
#
|
|
16
|
+
mattr_writer :custom_options
|
|
17
|
+
self.custom_options = nil
|
|
18
|
+
|
|
19
|
+
def self.custom_options(event)
|
|
20
|
+
if @@custom_options.respond_to?(:call)
|
|
21
|
+
@@custom_options.call(event)
|
|
22
|
+
else
|
|
23
|
+
@@custom_options
|
|
13
24
|
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# The emitted log format
|
|
28
|
+
#
|
|
29
|
+
# Currently supported formats are>
|
|
30
|
+
# - :lograge - The custom tense lograge format
|
|
31
|
+
# - :logstash - JSON formatted as a Logstash Event.
|
|
32
|
+
mattr_accessor :log_format
|
|
33
|
+
self.log_format = :lograge
|
|
14
34
|
|
|
15
|
-
|
|
16
|
-
|
|
35
|
+
def self.remove_existing_log_subscriptions
|
|
36
|
+
ActiveSupport::LogSubscriber.log_subscribers.each do |subscriber|
|
|
37
|
+
case subscriber
|
|
38
|
+
when ActionView::LogSubscriber
|
|
39
|
+
unsubscribe(:action_view, subscriber)
|
|
40
|
+
when ActionController::LogSubscriber
|
|
41
|
+
unsubscribe(:action_controller, subscriber)
|
|
42
|
+
end
|
|
17
43
|
end
|
|
18
44
|
end
|
|
19
45
|
|
|
20
|
-
def self.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
46
|
+
def self.unsubscribe(component, subscriber)
|
|
47
|
+
events = subscriber.public_methods(false).reject{ |method| method.to_s == 'call' }
|
|
48
|
+
events.each do |event|
|
|
49
|
+
ActiveSupport::Notifications.notifier.listeners_for("#{event}.#{component}").each do |listener|
|
|
50
|
+
if listener.instance_variable_get('@delegate') == subscriber
|
|
51
|
+
ActiveSupport::Notifications.unsubscribe listener
|
|
52
|
+
end
|
|
25
53
|
end
|
|
26
54
|
end
|
|
27
55
|
end
|
|
28
56
|
|
|
29
57
|
def self.setup(app)
|
|
30
|
-
app.config.action_dispatch.rack_cache[:verbose] = false
|
|
58
|
+
app.config.action_dispatch.rack_cache[:verbose] = false if app.config.action_dispatch.rack_cache
|
|
31
59
|
require 'lograge/rails_ext/rack/logger'
|
|
32
60
|
Lograge.remove_existing_log_subscriptions
|
|
33
61
|
Lograge::RequestLogSubscriber.attach_to :action_controller
|
|
62
|
+
Lograge.custom_options = app.config.lograge.custom_options
|
|
63
|
+
Lograge.log_format = app.config.lograge.log_format || :lograge
|
|
64
|
+
case Lograge.log_format.to_s
|
|
65
|
+
when "logstash"
|
|
66
|
+
begin
|
|
67
|
+
require "logstash-event"
|
|
68
|
+
rescue LoadError
|
|
69
|
+
puts "You need to install the logstash-event gem to use the logstash output."
|
|
70
|
+
raise
|
|
71
|
+
end
|
|
72
|
+
end
|
|
34
73
|
end
|
|
35
74
|
end
|
|
36
75
|
|
data/lograge.gemspec
CHANGED
|
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
|
7
7
|
s.version = Lograge::VERSION
|
|
8
8
|
s.authors = ["Mathias Meyer"]
|
|
9
9
|
s.email = ["meyer@paperplanes.de"]
|
|
10
|
-
s.homepage = ""
|
|
10
|
+
s.homepage = "https://github.com/roidrage/lograge"
|
|
11
11
|
s.summary = %q{Tame Rails' multi-line logging into a single line per request}
|
|
12
12
|
s.description = %q{Tame Rails' multi-line logging into a single line per request}
|
|
13
13
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
+
require 'lograge'
|
|
2
3
|
require 'lograge/log_subscriber'
|
|
3
4
|
require 'active_support/notifications'
|
|
4
5
|
require 'active_support/core_ext/string'
|
|
@@ -14,7 +15,7 @@ describe Lograge::RequestLogSubscriber do
|
|
|
14
15
|
logger
|
|
15
16
|
}
|
|
16
17
|
before do
|
|
17
|
-
Lograge::RequestLogSubscriber.logger = logger
|
|
18
|
+
Lograge::RequestLogSubscriber.logger = logger
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
let(:subscriber) {Lograge::RequestLogSubscriber.new}
|
|
@@ -34,7 +35,11 @@ describe Lograge::RequestLogSubscriber do
|
|
|
34
35
|
)
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
describe "when processing an action" do
|
|
38
|
+
describe "when processing an action with lograge output" do
|
|
39
|
+
before do
|
|
40
|
+
Lograge::log_format = :lograge
|
|
41
|
+
end
|
|
42
|
+
|
|
38
43
|
it "should include the URL in the log output" do
|
|
39
44
|
subscriber.process_action(event)
|
|
40
45
|
log_output.string.should include('/home')
|
|
@@ -42,9 +47,9 @@ describe Lograge::RequestLogSubscriber do
|
|
|
42
47
|
|
|
43
48
|
it "should start the log line with the HTTP method" do
|
|
44
49
|
subscriber.process_action(event)
|
|
45
|
-
log_output.string.starts_with?('GET').should == true
|
|
50
|
+
log_output.string.starts_with?('method=GET').should == true
|
|
46
51
|
end
|
|
47
|
-
|
|
52
|
+
|
|
48
53
|
it "should include the status code" do
|
|
49
54
|
subscriber.process_action(event)
|
|
50
55
|
log_output.string.should include('status=200')
|
|
@@ -52,7 +57,7 @@ describe Lograge::RequestLogSubscriber do
|
|
|
52
57
|
|
|
53
58
|
it "should include the controller and action" do
|
|
54
59
|
subscriber.process_action(event)
|
|
55
|
-
log_output.string.should include('action=
|
|
60
|
+
log_output.string.should include('controller=home action=index')
|
|
56
61
|
end
|
|
57
62
|
|
|
58
63
|
it "should include the duration" do
|
|
@@ -77,5 +82,163 @@ describe Lograge::RequestLogSubscriber do
|
|
|
77
82
|
log_output.string.should =~ /status=500/
|
|
78
83
|
log_output.string.should =~ /error='AbstractController::ActionNotFound:Route not found'/
|
|
79
84
|
end
|
|
85
|
+
|
|
86
|
+
it "should return an unknown status when no status or exception is found" do
|
|
87
|
+
event.payload[:status] = nil
|
|
88
|
+
event.payload[:exception] = nil
|
|
89
|
+
subscriber.process_action(event)
|
|
90
|
+
log_output.string.should =~ /status=0/
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe "with a redirect" do
|
|
94
|
+
before do
|
|
95
|
+
Thread.current[:lograge_location] = "http://www.example.com"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "should add the location to the log line" do
|
|
99
|
+
subscriber.process_action(event)
|
|
100
|
+
log_output.string.should =~ %r{ location=http://www.example.com}
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "should remove the thread local variable" do
|
|
104
|
+
subscriber.process_action(event)
|
|
105
|
+
Thread.current[:lograge_location].should == nil
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "should not include a location by default" do
|
|
110
|
+
subscriber.process_action(event)
|
|
111
|
+
log_output.string.should_not =~ /location=/
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
describe "when processing an action with logstash output" do
|
|
116
|
+
before do
|
|
117
|
+
require 'logstash-event'
|
|
118
|
+
Lograge::log_format = :logstash
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "should include the URL in the log output" do
|
|
122
|
+
subscriber.process_action(event)
|
|
123
|
+
log_output.string.should include('/home')
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "should start include the HTTP method" do
|
|
127
|
+
subscriber.process_action(event)
|
|
128
|
+
log_output.string.should include('"method":"GET"')
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "should include the status code" do
|
|
132
|
+
subscriber.process_action(event)
|
|
133
|
+
log_output.string.should include('"status":200')
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "should include the controller and action" do
|
|
137
|
+
subscriber.process_action(event)
|
|
138
|
+
log_output.string.should include('"controller":"home"')
|
|
139
|
+
log_output.string.should include('"action":"index"')
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "should include the duration" do
|
|
143
|
+
subscriber.process_action(event)
|
|
144
|
+
log_output.string.should =~ /"duration":\d+\.\d{0,2}/
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "should include the view rendering time" do
|
|
148
|
+
subscriber.process_action(event)
|
|
149
|
+
log_output.string.should =~ /"view":0.01/
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "should include the database rendering time" do
|
|
153
|
+
subscriber.process_action(event)
|
|
154
|
+
log_output.string.should =~ /"db":0.02/
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "should add a 500 status when an exception occurred" do
|
|
158
|
+
event.payload[:status] = nil
|
|
159
|
+
event.payload[:exception] = ['AbstractController::ActionNotFound', 'Route not found']
|
|
160
|
+
subscriber.process_action(event)
|
|
161
|
+
log_output.string.should =~ /"status":500/
|
|
162
|
+
log_output.string.should =~ /"error":"AbstractController::ActionNotFound:Route not found"/
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "should return an unknown status when no status or exception is found" do
|
|
166
|
+
event.payload[:status] = nil
|
|
167
|
+
event.payload[:exception] = nil
|
|
168
|
+
subscriber.process_action(event)
|
|
169
|
+
log_output.string.should =~ /"status":0/
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
describe "with a redirect" do
|
|
173
|
+
before do
|
|
174
|
+
Thread.current[:lograge_location] = "http://www.example.com"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "should add the location to the log line" do
|
|
178
|
+
subscriber.process_action(event)
|
|
179
|
+
log_output.string.should =~ %r{"location":"http://www.example.com"}
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "should remove the thread local variable" do
|
|
183
|
+
subscriber.process_action(event)
|
|
184
|
+
Thread.current[:lograge_location].should == nil
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it "should not include a location by default" do
|
|
189
|
+
subscriber.process_action(event)
|
|
190
|
+
log_output.string.should_not =~ /"location":/
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
describe "with custom_options configured for lograge output" do
|
|
195
|
+
before do
|
|
196
|
+
Lograge::log_format = :lograge
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it "should combine the hash properly for the output" do
|
|
200
|
+
Lograge.custom_options = {:data => "value"}
|
|
201
|
+
subscriber.process_action(event)
|
|
202
|
+
log_output.string.should =~ / data=value/
|
|
203
|
+
end
|
|
204
|
+
it "should combine the output of a lambda properly" do
|
|
205
|
+
Lograge.custom_options = lambda {|event| {:data => "value"}}
|
|
206
|
+
subscriber.process_action(event)
|
|
207
|
+
log_output.string.should =~ / data=value/
|
|
208
|
+
end
|
|
209
|
+
it "should work if the method returns nil" do
|
|
210
|
+
Lograge.custom_options = lambda {|event| nil}
|
|
211
|
+
subscriber.process_action(event)
|
|
212
|
+
log_output.string.should be_present
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
describe "with custom_options configured for logstash output" do
|
|
217
|
+
before do
|
|
218
|
+
Lograge::log_format = :logstash
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
it "should combine the hash properly for the output" do
|
|
222
|
+
Lograge.custom_options = {:data => "value"}
|
|
223
|
+
subscriber.process_action(event)
|
|
224
|
+
log_output.string.should =~ /"data":"value"/
|
|
225
|
+
end
|
|
226
|
+
it "should combine the output of a lambda properly" do
|
|
227
|
+
Lograge.custom_options = lambda {|event| {:data => "value"}}
|
|
228
|
+
subscriber.process_action(event)
|
|
229
|
+
log_output.string.should =~ /"data":"value"/
|
|
230
|
+
end
|
|
231
|
+
it "should work if the method returns nil" do
|
|
232
|
+
Lograge.custom_options = lambda {|event| nil}
|
|
233
|
+
subscriber.process_action(event)
|
|
234
|
+
log_output.string.should be_present
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
describe "when processing a redirect" do
|
|
239
|
+
it "should store the location in a thread local variable" do
|
|
240
|
+
subscriber.redirect_to(redirect)
|
|
241
|
+
Thread.current[:lograge_location].should == "http://example.com"
|
|
242
|
+
end
|
|
80
243
|
end
|
|
81
244
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lograge
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,11 +9,11 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2012-
|
|
12
|
+
date: 2012-11-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rspec
|
|
16
|
-
requirement:
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
17
|
none: false
|
|
18
18
|
requirements:
|
|
19
19
|
- - ! '>='
|
|
@@ -21,10 +21,15 @@ dependencies:
|
|
|
21
21
|
version: '0'
|
|
22
22
|
type: :development
|
|
23
23
|
prerelease: false
|
|
24
|
-
version_requirements:
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ! '>='
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '0'
|
|
25
30
|
- !ruby/object:Gem::Dependency
|
|
26
31
|
name: guard-rspec
|
|
27
|
-
requirement:
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
28
33
|
none: false
|
|
29
34
|
requirements:
|
|
30
35
|
- - ! '>='
|
|
@@ -32,10 +37,15 @@ dependencies:
|
|
|
32
37
|
version: '0'
|
|
33
38
|
type: :development
|
|
34
39
|
prerelease: false
|
|
35
|
-
version_requirements:
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ! '>='
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
36
46
|
- !ruby/object:Gem::Dependency
|
|
37
47
|
name: activesupport
|
|
38
|
-
requirement:
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
39
49
|
none: false
|
|
40
50
|
requirements:
|
|
41
51
|
- - ! '>='
|
|
@@ -43,10 +53,15 @@ dependencies:
|
|
|
43
53
|
version: '0'
|
|
44
54
|
type: :runtime
|
|
45
55
|
prerelease: false
|
|
46
|
-
version_requirements:
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ! '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
47
62
|
- !ruby/object:Gem::Dependency
|
|
48
63
|
name: actionpack
|
|
49
|
-
requirement:
|
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
65
|
none: false
|
|
51
66
|
requirements:
|
|
52
67
|
- - ! '>='
|
|
@@ -54,7 +69,12 @@ dependencies:
|
|
|
54
69
|
version: '0'
|
|
55
70
|
type: :runtime
|
|
56
71
|
prerelease: false
|
|
57
|
-
version_requirements:
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ! '>='
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '0'
|
|
58
78
|
description: Tame Rails' multi-line logging into a single line per request
|
|
59
79
|
email:
|
|
60
80
|
- meyer@paperplanes.de
|
|
@@ -78,7 +98,7 @@ files:
|
|
|
78
98
|
- spec/lograge_logsubscriber_spec.rb
|
|
79
99
|
- spec/lograge_spec.rb
|
|
80
100
|
- spec/spec_helper.rb
|
|
81
|
-
homepage:
|
|
101
|
+
homepage: https://github.com/roidrage/lograge
|
|
82
102
|
licenses: []
|
|
83
103
|
post_install_message:
|
|
84
104
|
rdoc_options: []
|
|
@@ -98,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
98
118
|
version: '0'
|
|
99
119
|
requirements: []
|
|
100
120
|
rubyforge_project: lograge
|
|
101
|
-
rubygems_version: 1.8.
|
|
121
|
+
rubygems_version: 1.8.23
|
|
102
122
|
signing_key:
|
|
103
123
|
specification_version: 3
|
|
104
124
|
summary: Tame Rails' multi-line logging into a single line per request
|