Skip to content
This repository has been archived by the owner on Apr 17, 2018. It is now read-only.

Commit

Permalink
Display logs via ActiveSupport::Notifications.instrument
Browse files Browse the repository at this point in the history
As of this commit, dm-rails provides the same amount
of log information as ActiveRecord, and it does so via
the same interface. This means that logs show up
just like ActiveRecord's in the console, and the
log level for example can be controlled in the same
way as for ActiveRecord (e.g. via config/environments)

This also means that dm-rails now provides all the
information rails_metrics also displays for ActiveRecord.
Currently, rails_metrics only works when used from
my fork at snusnu/rails_metrics (you have to use
the 'datamapper-compatibility' branch). I'm pretty
confident that these changes get merged upstream
eventually.
  • Loading branch information
snusnu committed May 26, 2010
1 parent 7a63704 commit e26d404
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 5 deletions.
3 changes: 2 additions & 1 deletion dm-rails.gemspec
Expand Up @@ -9,7 +9,7 @@ Gem::Specification.new do |s|

s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
s.authors = ["Martin Gamsjaeger (snusnu)", "Dan Kubb"]
s.date = %q{2010-05-23}
s.date = %q{2010-05-26}
s.description = %q{Integrate DataMapper with Rails 3}
s.email = %q{gamsnjaga@gmail.com}
s.extra_rdoc_files = [
Expand All @@ -33,6 +33,7 @@ Gem::Specification.new do |s|
"lib/dm-rails/railties/controller_runtime.rb",
"lib/dm-rails/railties/database.rake",
"lib/dm-rails/railties/i18n_support.rb",
"lib/dm-rails/railties/log_listener.rb",
"lib/dm-rails/railties/log_subscriber.rb",
"lib/dm-rails/session_store.rb",
"lib/dm-rails/setup.rb",
Expand Down
15 changes: 15 additions & 0 deletions lib/dm-rails/railties/log_listener.rb
@@ -0,0 +1,15 @@
module LogListener
def log(message)
ActiveSupport::Notifications.instrument('sql.data_mapper',
:name => 'SQL',
:sql => message.query, # TODO think about changing the key to :query
:start => message.start,
:duration => message.duration,
:connection_id => self.object_id
)
super
rescue Exception => e
# TODO proper logging
puts "[datamapper - ERROR] #{e.class.name}: #{e.message}: #{message.inspect}}"
end
end
5 changes: 5 additions & 0 deletions lib/dm-rails/railties/log_subscriber.rb
Expand Up @@ -3,6 +3,11 @@ module Railties

class LogSubscriber < Rails::LogSubscriber

def initialize
super
@odd_or_even = false
end

def sql(event)
name = '%s (%.1fms)' % [event.payload[:name], event.duration]
sql = event.payload[:sql].squeeze(' ')
Expand Down
21 changes: 17 additions & 4 deletions lib/dm-rails/setup.rb
@@ -1,6 +1,7 @@
require 'active_support/core_ext/hash/except'

require 'dm-rails/configuration'
require 'dm-rails/railties/log_listener'
require 'dm-rails/railties/benchmarking_mixin'

module Rails
Expand All @@ -14,14 +15,26 @@ def self.setup(environment)
initialize_foreign_keys
end

def self.setup_logger(logger)
::DataMapper.logger = logger
end

def self.setup_with_instrumentation(name, options)
puts "[datamapper] Setting up #{name.inspect} repository: '#{options['database']}' on #{options['adapter']}"
adapter = ::DataMapper.setup(name, options)
adapter.extend ::DataMapper::Adapters::Benchmarking
setup_log_listener(options['adapter'])
end

def self.setup_logger(logger)
::DataMapper.logger = logger
end

def self.setup_log_listener(adapter_name)
if Object.const_defined?('DataObjects')
DataObjects::Connection.send(:include, LogListener)
# FIXME Setting DataMapper::Logger.new($stdout, :off) alone won't work because the #log
# method is currently only available in DO and needs an explicit DO Logger instantiated.
# We turn the logger :off because ActiveSupport::Notifications handles displaying log messages
do_adapter = DataObjects.const_get(adapter_name.classify)

This comment has been minimized.

Copy link
@dkubb

dkubb May 26, 2010

Member

When adapter_name is "postgres", String#classify will return "Postgre" incorrectly.

Can adapter_name ever be "sqlite"? If so, this will cause an explosion because (I think) the namespace in DO is DataObjects::Sqlite3.

Also, I assume this code will be refactored to handle cases where multiple adapters are being used.. I presume this will explode badly in cases where you are mixing usage of MySQL and MongoDB.

This comment has been minimized.

Copy link
@ku1ik

ku1ik May 26, 2010

Yep, it just exploded for my app with both mysql and mongo with error:

~/code/kanbanery (dm_1.0.0_upgrade) % bes spec/models && bes spec/requests
[datamapper] Setting up the "test" environment:
[datamapper] Setting up :logs repository: 'kanbanery_test' on mongo
/home/kill/.rvm/gems/ruby-1.9.1-p378/bundler/gems/dm-rails-6d789ab541218bf52f1038ecd3856026704f4c3b-master/lib/dm-rails/setup.rb:36:in setup_log_listener': undefined methodlogger=' for Mongo:Module (NoMethodError)

This comment has been minimized.

Copy link
@dkubb

dkubb May 26, 2010

Member

So perhaps the sqlite issue should be looked into, and then just before the const_get line, we should use an if condition with const_defined?.

This comment has been minimized.

Copy link
@ku1ik

ku1ik May 26, 2010

I don't know what will be the best but I have subject on which I can test :)

This comment has been minimized.

Copy link
@dkubb

dkubb May 28, 2010

Member

@sickill: I added the fix I talked about above. Could you give it a test on your end?

This comment has been minimized.

Copy link
@ku1ik

ku1ik May 28, 2010

Hey,

Unfortunately it didn't help, the same problem, different line though:

~/code/kanbanery (master) % bes spec
[datamapper] Setting up the "test" environment:
[datamapper] Setting up :logs repository: 'kanbanery_test' on mongo
/home/kill/.rvm/gems/ruby-1.9.1-p378/bundler/gems/dm-rails-6d789ab541218bf52f1038ecd3856026704f4c3b-master/lib/dm-rails/setup.rb:38:in setup_log_listener': undefined methodlogger=' for Mongo:Module (NoMethodError)
from /home/kill/.rvm/gems/ruby-1.9.1-p378/bundler/gems/dm-rails-6d789ab541218bf52f1038ecd3856026704f4c3b-master/lib/dm-rails/setup.rb:22:in setup_with_instrumentation' from /home/kill/.rvm/gems/ruby-1.9.1-p378/bundler/gems/dm-rails-6d789ab541218bf52f1038ecd3856026704f4c3b-master/lib/dm-rails/setup.rb:13:inblock in setup'
from /home/kill/.rvm/gems/ruby-1.9.1-p378/bundler/gems/dm-rails-6d789ab541218bf52f1038ecd3856026704f4c3b-master/lib/dm-rails/setup.rb:12:in each' from /home/kill/.rvm/gems/ruby-1.9.1-p378/bundler/gems/dm-rails-6d789ab541218bf52f1038ecd3856026704f4c3b-master/lib/dm-rails/setup.rb:12:insetup'

do_adapter.logger = DataObjects::Logger.new($stdout, :off)
end
end

def self.initialize_foreign_keys
Expand Down

0 comments on commit e26d404

Please sign in to comment.