ezlog 0.2.2 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +82 -11
- data/ezlog.gemspec +1 -1
- data/lib/ezlog.rb +2 -1
- data/lib/ezlog/logging_layout.rb +2 -2
- data/lib/ezlog/rails.rb +12 -0
- data/lib/ezlog/rails/access_log.rb +37 -0
- data/lib/ezlog/rails/debug_exceptions.rb +8 -0
- data/lib/ezlog/rails/log_exceptions.rb +17 -0
- data/lib/ezlog/rails/log_subscriber.rb +16 -0
- data/lib/ezlog/rails/request_log_context.rb +17 -0
- data/lib/ezlog/railtie.rb +19 -7
- data/lib/ezlog/sidekiq/job_logger.rb +1 -1
- data/lib/ezlog/version.rb +1 -1
- metadata +22 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93492a6b3f140b41d4aad461fcb7bd9017149c3bca1a0d19a9edf5e2ed9fc25d
|
4
|
+
data.tar.gz: bddac2fcd0e1ef426f228e97bb537a34704d102d8f480cee872be74e505aefcc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22f5427eaa445d7189140bb98bf1206f2e5b0dd0b1df8d1f1ec12af01a2472dea1006422b69e50d28bf7c87dd9f2002ee29ba7a8dcdbccceea6cb3c65ff60080
|
7
|
+
data.tar.gz: 8c0c3f28b548609c667f7e4b1d610a50a9a44a114b05a66dfaef9901d6f252e564eb6458ae4808c5154c759e685dd44b368b984a076ad1b9b7a53a75a555ae89
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
### 0.3.1 (2019-06-09)
|
2
|
+
|
3
|
+
[Full Changelog](https://github.com/emartech/ezlog/compare/v0.2.2...v0.3.1)
|
4
|
+
|
5
|
+
* Features & enhancements
|
6
|
+
* Unified access log for Rails
|
7
|
+
* 1 message per request
|
8
|
+
* Includes request ID, parameters, response code
|
9
|
+
* Non-verbose logging of uncaught exceptions in Rails apps
|
10
|
+
* 1 message per error
|
11
|
+
* Use ERROR level instead of FATAL
|
12
|
+
* [Rack::Timeout](https://github.com/heroku/rack-timeout) logging is now completely turned off, because Timeout errors
|
13
|
+
are handled by the application's error logger and we don't want duplicated log messages
|
14
|
+
|
15
|
+
* Bug fixes
|
16
|
+
* Fix bug where the application log level wasn't set to INFO by default but remained on DEBUG
|
17
|
+
|
1
18
|
### 0.2.2 (2019-05-19)
|
2
19
|
|
3
20
|
[Full Changelog](https://github.com/emartech/ezlog/compare/v0.2.1...v0.2.2)
|
data/README.md
CHANGED
@@ -3,31 +3,41 @@
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/ezlog.svg)](https://badge.fury.io/rb/ezlog)
|
4
4
|
[![Build Status](https://travis-ci.com/emartech/ezlog.svg?branch=master)](https://travis-ci.com/emartech/ezlog)
|
5
5
|
|
6
|
-
Ezlog is intended to be a zero-configuration logging setup for pure Ruby or
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
Ezlog is intended to be a zero-configuration structured logging setup for pure Ruby or [Ruby on Rails](https://rubyonrails.org/)
|
7
|
+
projects using any (or all) of the following libraries or frameworks:
|
8
|
+
|
9
|
+
* [Ruby on Rails](https://rubyonrails.org/)
|
10
|
+
* [Sidekiq](https://github.com/mperham/sidekiq)
|
11
|
+
* [Sequel](https://sequel.jeremyevans.net/)
|
12
|
+
* [Rack::Timeout](https://github.com/heroku/rack-timeout)
|
13
|
+
|
14
|
+
It uses Tim Pease's wonderful [Logging](https://github.com/TwP/logging) gem for an all-purpose structured logging solution.
|
10
15
|
|
11
16
|
Ezlog's purpose is threefold:
|
12
|
-
1. Make sure that our applications are logging in a sensible manner; emitting no unnecessary "noise" but
|
13
|
-
relevant and necessary information (like timing).
|
17
|
+
1. Make sure that our applications are logging in a concise and sensible manner; emitting no unnecessary "noise" but
|
18
|
+
containing all relevant and necessary information (like timing).
|
14
19
|
2. Make sure that all log messages are written to STDOUT in a machine-processable format (JSON) across all of our projects.
|
15
|
-
3. Achieving the above
|
20
|
+
3. Achieving the above goals should require no configuration in the projects where the library is used.
|
16
21
|
|
17
22
|
## Installation
|
18
23
|
|
24
|
+
#### Rails
|
25
|
+
|
19
26
|
Add this line to your application's Gemfile:
|
20
27
|
|
21
28
|
```ruby
|
22
29
|
gem 'ezlog'
|
23
30
|
```
|
24
31
|
|
32
|
+
That's it. Everything else is automatically configured.
|
33
|
+
|
25
34
|
## What it does
|
26
35
|
|
27
36
|
* Initializes the [Logging](https://github.com/TwP/logging) library
|
28
37
|
* Configures Rails logging
|
29
38
|
* Configures Sidekiq logging
|
30
39
|
* Configures Rack::Timeout logging
|
40
|
+
* Provides testing support for [RSpec](https://rspec.info/)
|
31
41
|
|
32
42
|
#### Initializes the Logging library
|
33
43
|
|
@@ -64,8 +74,39 @@ logger.error ex
|
|
64
74
|
|
65
75
|
Ezlog configures the `Rails.logger` to be an instance of a [Logging](https://github.com/TwP/logging) logger by the name
|
66
76
|
of `Application`, behaving as described above. The logger uses the log level set in `application.rb` (if present) or
|
67
|
-
uses INFO as a default log level.
|
68
|
-
|
77
|
+
uses INFO as a default log level.
|
78
|
+
|
79
|
+
In addition to this, Ezlog also does the following:
|
80
|
+
* It adds the environment (`Rails.env`) to the logger's initial context, so it will automatically be appended to all log messages
|
81
|
+
emitted by the application.
|
82
|
+
* It disables Rails's default (verbose) logging of uncaught errors and injects its own error logger into the application, which
|
83
|
+
* logs 1 line per error, including the error's name and context (stack trace, etc.),
|
84
|
+
* logs every error at ERROR level instead of the default FATAL.
|
85
|
+
* It disables Rails's default (verbose) request logging, which logs several lines per event during the processing of an action
|
86
|
+
and replaces the default Rack access log with its own access log middleware. The end result is an access log, which
|
87
|
+
* contains all relevant information (request ID, method, path, params, client IP, duration and response status code), and
|
88
|
+
* has 1 log line per request, logged at the end of the request.
|
89
|
+
|
90
|
+
Thanks to Mathias Meyer for writing [Lograge](https://github.com/roidrage/lograge), which inspired the solution.
|
91
|
+
If Ezlog's not your cup of tea but you're looking for a way to tame Rails's logging then be sure to check out
|
92
|
+
[Lograge](https://github.com/roidrage/lograge).
|
93
|
+
|
94
|
+
```
|
95
|
+
GET /welcome?subsession_id=34ea8596f9764f475f81158667bc2654
|
96
|
+
|
97
|
+
With default Rails logging:
|
98
|
+
|
99
|
+
Started GET "/welcome?subsession_id=34ea8596f9764f475f81158667bc2654" for 127.0.0.1 at 2019-06-08 08:49:31 +0200
|
100
|
+
Processing by PagesController#welcome as HTML
|
101
|
+
Parameters: {"subsession_id"=>"34ea8596f9764f475f81158667bc2654"}
|
102
|
+
Rendering pages/welcome.html.haml within layouts/application
|
103
|
+
Rendered pages/welcome.html.haml within layouts/application (5.5ms)
|
104
|
+
Completed 200 OK in 31ms (Views: 27.3ms | ActiveRecord: 0.0ms)
|
105
|
+
|
106
|
+
With Ezlog:
|
107
|
+
|
108
|
+
{"logger":"AccessLog","timestamp":"2019-06-08T08:49:31+02:00","level":"INFO","hostname":"MacbookPro.local","pid":75463,"environment":"development","request_id":"9a43631b-284c-4677-9d08-9c1cc5c7d3a7","duration_sec":0.031,"message":"GET /welcome?subsession_id=34ea8596f9764f475f81158667bc2654 - 200 (OK)","remote_ip":"127.0.0.1","method":"GET","path":"/welcome?subsession_id=34ea8596f9764f475f81158667bc2654","params":{"subsession_id":"34ea8596f9764f475f81158667bc2654","controller":"pages","action":"welcome"},"response_status_code":200}
|
109
|
+
```
|
69
110
|
|
70
111
|
#### Configures Sidekiq logging
|
71
112
|
|
@@ -97,8 +138,38 @@ TestWorker.perform_async 42
|
|
97
138
|
#### Configures Rack::Timeout logging
|
98
139
|
|
99
140
|
[Rack::Timeout](https://github.com/heroku/rack-timeout) is a very useful tool for people running services on Heroku
|
100
|
-
but it is way too verbose by default
|
101
|
-
|
141
|
+
but it is way too verbose by default and all of its important messages (i.e. Timeout errors) are logged by the application
|
142
|
+
as well. For this reason, Ezlog turns off [Rack::Timeout](https://github.com/heroku/rack-timeout) logging completely.
|
143
|
+
|
144
|
+
#### Provides testing support for RSpec
|
145
|
+
|
146
|
+
Ezlog comes with built-in support for testing your logging activity using [RSpec](https://rspec.info/).
|
147
|
+
To enable spec support for Ezlog, put this line in your `spec_helper.rb` or `rails_helper.rb`:
|
148
|
+
```ruby
|
149
|
+
require "ezlog/rspec"
|
150
|
+
```
|
151
|
+
|
152
|
+
What you get:
|
153
|
+
* Helpers
|
154
|
+
* `log_output` provides access to the complete log output in your specs
|
155
|
+
* `log_output_is_expected` shorthand for writing expectations for the log output
|
156
|
+
* Matchers
|
157
|
+
* `include_log_message` matcher for expecting a certain message in the log output
|
158
|
+
* `log` matcher for expecting an operation to log a certain message
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
# Check that the log contains a certain message
|
162
|
+
expect(log_output).to include_log_message message: 'Test message'
|
163
|
+
log_output_is_expected.to include_log_message message: 'Test message'
|
164
|
+
|
165
|
+
# Check that the message is not present in the logs before the operation but is present after it
|
166
|
+
expect { operation }.to log message: 'Test message',
|
167
|
+
user_id: 123456
|
168
|
+
|
169
|
+
# Expect a certain log level
|
170
|
+
log_output_is_expected.to include_log_message(message: 'Test message').at_level(:info)
|
171
|
+
expect { operation }.to log(message: 'Test message').at_level(:info)
|
172
|
+
```
|
102
173
|
|
103
174
|
## Disclaimer
|
104
175
|
|
data/ezlog.gemspec
CHANGED
@@ -23,10 +23,10 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
25
|
spec.add_dependency "logging", "~> 2.0"
|
26
|
-
spec.add_dependency "multi_json"
|
27
26
|
|
28
27
|
spec.add_development_dependency "bundler", "~> 2.0"
|
29
28
|
spec.add_development_dependency "rake", "~> 10.0"
|
30
29
|
spec.add_development_dependency "rspec", "~> 3.0"
|
31
30
|
spec.add_development_dependency "sidekiq", "~> 5.0"
|
31
|
+
spec.add_development_dependency "actionpack", "~> 5.0"
|
32
32
|
end
|
data/lib/ezlog.rb
CHANGED
@@ -6,9 +6,10 @@ require 'ezlog/railtie' if defined? Rails
|
|
6
6
|
module Ezlog
|
7
7
|
autoload :LogContextHelper, 'ezlog/log_context_helper'
|
8
8
|
autoload :LoggingLayout, 'ezlog/logging_layout'
|
9
|
+
autoload :Rails, 'ezlog/rails'
|
9
10
|
autoload :Sidekiq, 'ezlog/sidekiq'
|
10
11
|
|
11
12
|
def self.logger(name)
|
12
|
-
Logging::Logger[name]
|
13
|
+
::Logging::Logger[name]
|
13
14
|
end
|
14
15
|
end
|
data/lib/ezlog/logging_layout.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'time'
|
2
|
-
require '
|
2
|
+
require 'json'
|
3
3
|
|
4
4
|
module Ezlog
|
5
5
|
class LoggingLayout < ::Logging::Layout
|
@@ -12,7 +12,7 @@ module Ezlog
|
|
12
12
|
add_initial_context_to log_entry
|
13
13
|
add_logging_context_to log_entry
|
14
14
|
add_event_information_to log_entry, event
|
15
|
-
::
|
15
|
+
::JSON.dump(log_entry) + "\n"
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
data/lib/ezlog/rails.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "action_controller"
|
2
|
+
require "action_controller/log_subscriber"
|
3
|
+
|
4
|
+
module Ezlog
|
5
|
+
module Rails
|
6
|
+
autoload :AccessLog, 'ezlog/rails/access_log'
|
7
|
+
autoload :DebugExceptions, 'ezlog/rails/debug_exceptions'
|
8
|
+
autoload :LogExceptions, 'ezlog/rails/log_exceptions'
|
9
|
+
autoload :RequestLogContext, 'ezlog/rails/request_log_context'
|
10
|
+
autoload :LogSubscriber, 'ezlog/rails/log_subscriber'
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Ezlog
|
2
|
+
module Rails
|
3
|
+
class AccessLog
|
4
|
+
include LogContextHelper
|
5
|
+
|
6
|
+
def initialize(app, logger)
|
7
|
+
@app = app
|
8
|
+
@logger = logger
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
status, headers, body_lines = benchmark { @app.call(env) }
|
13
|
+
log_request ActionDispatch::Request.new(env), status
|
14
|
+
[status, headers, body_lines]
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def benchmark
|
20
|
+
start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
21
|
+
yield
|
22
|
+
ensure
|
23
|
+
end_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
24
|
+
add_to_log_context duration_sec: (end_time - start_time).round(3)
|
25
|
+
end
|
26
|
+
|
27
|
+
def log_request(request, status)
|
28
|
+
@logger.info message: '%s %s - %i (%s)' % [request.method, request.filtered_path, status, Rack::Utils::HTTP_STATUS_CODES[status]],
|
29
|
+
remote_ip: request.remote_ip,
|
30
|
+
method: request.method,
|
31
|
+
path: request.filtered_path,
|
32
|
+
params: request.filtered_parameters,
|
33
|
+
response_status_code: status
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Ezlog
|
2
|
+
module Rails
|
3
|
+
class LogExceptions
|
4
|
+
def initialize(app, logger)
|
5
|
+
@app = app
|
6
|
+
@logger = logger
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
@app.call(env)
|
11
|
+
rescue Exception => exception
|
12
|
+
@logger.error exception
|
13
|
+
raise
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Ezlog
|
2
|
+
module Rails
|
3
|
+
class LogSubscriber
|
4
|
+
def self.detach(subscriber_class)
|
5
|
+
subscriber = ::ActiveSupport::LogSubscriber.log_subscribers.find { |subscriber| subscriber.is_a? subscriber_class }
|
6
|
+
return unless subscriber
|
7
|
+
|
8
|
+
subscriber.patterns.each do |pattern|
|
9
|
+
::ActiveSupport::Notifications.notifier.listeners_for(pattern).each do |listener|
|
10
|
+
::ActiveSupport::Notifications.unsubscribe listener if listener.instance_variable_get('@delegate').is_a? subscriber_class
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Ezlog
|
2
|
+
module Rails
|
3
|
+
class RequestLogContext
|
4
|
+
include LogContextHelper
|
5
|
+
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
within_log_context request_id: env['action_dispatch.request_id'] do
|
12
|
+
@app.call(env)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/ezlog/railtie.rb
CHANGED
@@ -2,8 +2,8 @@ module Ezlog
|
|
2
2
|
class Railtie < Rails::Railtie
|
3
3
|
initializer 'ezlog.configure_logging' do |app|
|
4
4
|
::Logging.logger.root.appenders = ::Logging.appenders.stdout 'stdout',
|
5
|
-
layout: Ezlog::LoggingLayout.new(environment: Rails.env),
|
6
|
-
level: app.config.log_level
|
5
|
+
layout: Ezlog::LoggingLayout.new(environment: ::Rails.env),
|
6
|
+
level: app.config.log_level
|
7
7
|
end
|
8
8
|
|
9
9
|
initializer 'ezlog.configure_sidekiq_logging' do
|
@@ -11,11 +11,24 @@ module Ezlog
|
|
11
11
|
end
|
12
12
|
|
13
13
|
initializer 'ezlog.configure_rack_timeout_logging' do
|
14
|
-
|
14
|
+
disable_rack_timeout_logging if defined? ::Rack::Timeout
|
15
|
+
end
|
16
|
+
|
17
|
+
initializer 'ezlog.configure_middlewares' do |app|
|
18
|
+
app.config.middleware.insert_after ::ActionDispatch::RequestId, Ezlog::Rails::RequestLogContext
|
19
|
+
app.config.middleware.swap ::Rails::Rack::Logger, Ezlog::Rails::AccessLog, Ezlog.logger('AccessLog')
|
20
|
+
app.config.middleware.swap ::ActionDispatch::DebugExceptions, Ezlog::Rails::DebugExceptions
|
21
|
+
app.config.middleware.insert_after Ezlog::Rails::DebugExceptions, Ezlog::Rails::LogExceptions, Ezlog.logger('Application')
|
22
|
+
end
|
23
|
+
|
24
|
+
config.after_initialize do
|
25
|
+
Ezlog::Rails::LogSubscriber.detach ::ActionController::LogSubscriber
|
26
|
+
Ezlog::Rails::LogSubscriber.detach ::ActionView::LogSubscriber
|
15
27
|
end
|
16
28
|
|
17
29
|
config.before_configuration do |app|
|
18
|
-
app.config.logger =
|
30
|
+
app.config.logger = Ezlog.logger('Application')
|
31
|
+
app.config.log_level = :info
|
19
32
|
end
|
20
33
|
|
21
34
|
private
|
@@ -30,9 +43,8 @@ module Ezlog
|
|
30
43
|
end
|
31
44
|
end
|
32
45
|
|
33
|
-
def
|
34
|
-
::Rack::Timeout::Logger.logger = ::
|
35
|
-
::Rack::Timeout::Logger.logger.level = :warn
|
46
|
+
def disable_rack_timeout_logging
|
47
|
+
::Rack::Timeout::Logger.logger = ::Logger.new(nil)
|
36
48
|
end
|
37
49
|
end
|
38
50
|
end
|
data/lib/ezlog/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ezlog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zoltan Ormandi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logging
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: multi_json
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: bundler
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +80,20 @@ dependencies:
|
|
94
80
|
- - "~>"
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '5.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: actionpack
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '5.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '5.0'
|
97
97
|
description:
|
98
98
|
email:
|
99
99
|
- zoltan.ormandi@emarsys.com
|
@@ -115,6 +115,12 @@ files:
|
|
115
115
|
- lib/ezlog.rb
|
116
116
|
- lib/ezlog/log_context_helper.rb
|
117
117
|
- lib/ezlog/logging_layout.rb
|
118
|
+
- lib/ezlog/rails.rb
|
119
|
+
- lib/ezlog/rails/access_log.rb
|
120
|
+
- lib/ezlog/rails/debug_exceptions.rb
|
121
|
+
- lib/ezlog/rails/log_exceptions.rb
|
122
|
+
- lib/ezlog/rails/log_subscriber.rb
|
123
|
+
- lib/ezlog/rails/request_log_context.rb
|
118
124
|
- lib/ezlog/railtie.rb
|
119
125
|
- lib/ezlog/rspec.rb
|
120
126
|
- lib/ezlog/rspec/helpers.rb
|