/ / Jak ustalić hosta bazy danych z ActiveSupport :: Notifications.subscribe 'sql.active_record' - sql, ruby-on-rails-3, activerecord, powiadomienia, activesupport

Jak ustalić hosta bazy danych z ActiveSupport :: Notifications.subscribe 'sql.active_record' - sql, ruby-on-rails-3, activerecord, powiadomienia, activesupport

Używam powiadomień w Rails 3 (jak opisano w tym raporcie) http://asciicasts.com/episodes/249-notifications-in-rails-3), aby rejestrować powolne zapytania sql wygenerowane w mojej aplikacji. Są to jednak zapytania, które pochodzą z mojej bazy danych tylko do odczytu. Dlatego chciałbym wiedzieć, czy istnieje sposób na określenie, w której bazie danych wykonywane jest zapytanie sql. Każda pomoc jest doceniana. Mój kod znajduje się poniżej.

ActiveSupport::Notifications.subscribe "sql.active_record" do |*args|
begin
event = ActiveSupport::Notifications::Event.new(*args)
if event.duration > 250
Rails.logger.error "[SLOW QUERY] | #{event.duration}ms | #{event.payload[:sql]}
end
rescue
end
end

Odpowiedzi:

0 dla odpowiedzi № 1

Możesz uzyskać do niego dostęp poprzez ActiveRecord::Base.connection.raw_connection.host. Jeśli to powróci nil, łączysz się z lokalną bazą danych, prawdopodobnie przez gniazdo. Jeśli tak jest, to możesz założyć, że host jest localhost.


0 dla odpowiedzi nr 2

Kluczowym punktem, którego może brakować, jest to, że ładunek zawiera connection_id element, który jest po prostu Ruby object_id. Tak więc powinieneś być w stanie zrobić coś takiego:

def get_connection_host(payload)
connection_object_id = payload[:connection_id]
return nil unless connection_object_id.present?

connection_object = ObjectSpace._id2ref(connection_object_id)
return nil unless connection_object

#If the connection object descends from ActiveRecord::Base, it"ll have this.
if connection_object.respond_to?(:connection_config)
return connection_object.connection_config[:host]
end

#If we"re dealing with straight SQL, the AR connection adapter will be the connection object and have this variable.
if connection_object.instance_variable_defined?("@connection_options")
return connection_object.instance_variable_get("@connection_options").try(:[], :host)
end
rescue => e
#log error, raise, do whatever is appropriate in your context
end

Ten kod nie jest super-przyszłościowy, na którym można polegaćZmienne instancji i nie jestem w 100% pewny, co by się stało, gdyby obiekt połączenia był już zebrany, ale powinien dać ci kilka pomysłów.

Sugestia użycia ActiveRecord::Base.connection ma sens, ale ja nie myśleć Jest niezawodny, jeśli pracujesz w aplikacji łączącej się z wieloma bazami danych, dokładnie tam, gdzie naprawdę chcesz wykonać filtrowanie według nazwy hosta lub bazy danych.