seamless_database_pool icon indicating copy to clipboard operation
seamless_database_pool copied to clipboard

Logging of connection?

Open psharpNumerex opened this issue 12 years ago • 2 comments

Is there a way to tell which connection is being used by looking at the logs?

I can see where logger is passed into the SDPAdaptor, but it seems like the log messages are all for errors.

psharpNumerex avatar Mar 28 '13 20:03 psharpNumerex

I can't see any good way of adding logging that would work across database adapters and that wouldn't be too chatty.

You could mix in something to you specific connections to output log entries when they are being used.

I you can come up with a good general way of solving this please submit a pull request.

bdurand avatar Jun 11 '13 20:06 bdurand

I have pick some code from db_charmer and modified it for sdbp. But get_connection_name should be fixed. I couldn't find easy way to get proper connection name for now.

You can check out originals here:

  • https://github.com/kovyrin/db-charmer/blob/master/lib/db_charmer/rails3/abstract_adapter/connection_name.rb
  • https://github.com/kovyrin/db-charmer/blob/master/lib/db_charmer/rails3/active_record/log_subscriber.rb
require 'active_record/log_subscriber'

module SeamlessDatabasePool
  module ActiveRecord
    module ConnectionAdapters
      class AbstractAdapter
        module ConnectionName
          # We use this proxy to push connection name down to instrumenters
          # w/o monkey-patching the log method itself
          class InstrumenterDecorator < ActiveSupport::BasicObject
            def initialize(adapter, instrumenter)
              @adapter = adapter
              @instrumenter = instrumenter
            end

            def instrument(name, payload = {}, &block)
              payload[:connection_name] ||= get_connection_name
              @instrumenter.instrument(name, payload, &block)
            end

            def method_missing(meth, *args, &block)
              @instrumenter.send(meth, *args, &block)
            end

            private
              def get_connection_name
                ::SeamlessDatabasePool.read_only_connection_type
              end
          end

          def self.included(base)
            base.alias_method_chain :initialize, :connection_name
          end

          def connection_name
            raise "Can't find connection configuration!" unless @config
            @config[:connection_name]
          end

          def initialize_with_connection_name(*args)
            initialize_without_connection_name(*args)
            @instrumenter = InstrumenterDecorator.new(self, @instrumenter)
          end
        end

        ::ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:include, ConnectionName)
      end
    end

    module LogSubscriber
      def self.included(base)
        base.send(:attr_accessor, :connection_name)
        base.alias_method_chain :sql, :connection_name
        base.alias_method_chain :debug, :connection_name
      end

      def sql_with_connection_name(event)
        self.connection_name = event.payload[:connection_name]
        sql_without_connection_name(event)
      end

      def debug_with_connection_name(msg)
        conn = connection_name ? color("  [#{connection_name}]", ::ActiveSupport::LogSubscriber::BLUE, true) : ''
        debug_without_connection_name(conn + msg)
      end
    end

    ::ActiveRecord::LogSubscriber.send(:include, LogSubscriber)
  end
end

You can test this code adding it right after require 'rails/all' in application.rb

printercu avatar Apr 08 '14 15:04 printercu