-
-
Notifications
You must be signed in to change notification settings - Fork 153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Logging #368
Conversation
@@ -237,9 +237,9 @@ def self.version | |||
# | |||
# @since 0.7.0 | |||
# @api private | |||
def initialize(configuration: self.class.configuration) | |||
def initialize(configuration: self.class.configuration, stream: $stdout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why passing the stream
and not a Logger
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I understand he will build the logger later on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be easier to pass the logger? I don't see that it's the Migrators responsibility to build it. Harder to configure logger/pattern like this, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pascalbetz @mereghost TBH, I injected that dependency only for testing purposes, but I don't like it. Also, look at how many times is passed down from method call, to method call, deep in the stack.
I can refactor it, by adding a Configuration#migrations_logger
as private API, so we can remove it from all these method signatures and have an easy access to stub it during test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -73,6 +73,7 @@ def self.container | |||
|
|||
# @since 0.1.0 | |||
def self.load!(&blk) # rubocop:disable Metrics/AbcSize | |||
configuration.gateway.use_logger(configuration.logger) unless configuration.logger.nil? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think of introducing a NullObject
/Mimic
logger? With ti we would not check for nils and it would simply do nothing. Yeah, one more method call, but cleaner code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mereghost @pascalbetz By avoiding the call to use_logger
, we avoid the overhead of thousands of useless method calls against a null object.
Because once gateway
receives a logger, it uses it. It wouldn't log, because it's a null object, but still it invokes methods on it. Which is a useless overhead.
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't we have a logger set most of the times anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pascalbetz In development, yes, but not necessarily in production
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least in production we don't log SQL queries, only the needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see.
Here is a benchmark, so we can make informed decisions:-)
Comparison:
no logger, nil check: 8778993.1 i/s
null logger, call: 6309574.3 i/s - 1.39x slower
require 'benchmark/ips'
class NullLogger
def info(message)
end
end
class Something
def initialize(logger)
@logger = logger
end
def work_with_null_check
@logger.info('working hard') if @logger
end
def work_without_null_check
@logger.info('working hard')
end
end
null_logger = Something.new(NullLogger.new)
no_logger = Something.new(nil)
Benchmark.ips do |x|
x.compare!
x.report('null logger, call') do
null_logger.work_without_null_check
end
x.report('no logger, nil check') do
no_logger.work_with_null_check
end
end
@@ -237,9 +237,9 @@ def self.version | |||
# | |||
# @since 0.7.0 | |||
# @api private | |||
def initialize(configuration: self.class.configuration) | |||
def initialize(configuration: self.class.configuration, stream: $stdout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I understand he will build the logger later on.
It accepts the following arguments: | ||
|
||
* `stream`: a Ruby StringIO object - it can be `$stdout` or a path to file (eg. `"log/development.log"`) - Defaults to `$stdout` | ||
* `:level`: logging level - it can be: `:debug`, `:info`, `:warn`, `:info`, `:warn`, `:error`, `:fatal`, `:unknown` - Defaults to `:debug` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
double :warn
and :info
@@ -73,6 +73,7 @@ def self.container | |||
|
|||
# @since 0.1.0 | |||
def self.load!(&blk) # rubocop:disable Metrics/AbcSize | |||
configuration.gateway.use_logger(configuration.logger) unless configuration.logger.nil? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least in production we don't log SQL queries, only the needed.
3c8544e
to
6a4b13a
Compare
@mereghost @pascalbetz @TiteiKo @AlfonsoUceda I've refactored, according to your requests. Please review. 😄 |
This is a proposal to add:
$stdout
when running migrationsLogging for database operations
This is optional when using
hanami-model
in standalone, but it will be enabled by default for Hanami projects (hanami
gem).Usage
Where the first argument is a
IO
Ruby object: a path to a file, or$stdout
.Again, this will be setup automatically in Hanami projects
Example
Automatic Logging for Migrations
This is always enabled without any configuration.
Example
This is too much verbose IMO, but we don't have control on it, as we use
Sequel
logger for that./cc @hanami/issues @hanami/ecosystem @davidpelaez for review. 👍
Closes #277