Ответ 1
SQL-регистрация в рельсах - Вкратце - вам нужно переопределить метод выполнения ActiveRecord. Там вы можете добавить любую логику для ведения журнала.
Я хочу сохранить файл журнала, который выполняет некоторые реляционные запросы SQL (а именно CREATE, UPDATE и DELETE) поэтому мне нужно перехватить все запросы, а затем отфильтровать их, возможно, с помощью некоторого regexp и зарегистрировать их по мере необходимости.
Где бы я поместил такую вещь в код rails?
SQL-регистрация в рельсах - Вкратце - вам нужно переопределить метод выполнения ActiveRecord. Там вы можете добавить любую логику для ведения журнала.
Вот упрощенная версия того, с чем связан c0r0ner, чтобы лучше показать это:
connection = ActiveRecord::Base.connection
class << connection
alias :original_exec :execute
def execute(sql, *name)
# try to log sql command but ignore any errors that occur in this block
# we log before executing, in case the execution raises an error
begin
File.open(Rails.root.join("/log/sql.txt"),'a'){|f| f.puts Time.now.to_s+": "+sql}
rescue Exception => e
;
end
# execute original statement
original_exec(sql, *name)
end
end
В качестве примечания для подписчиков вы можете "регистрировать все запросы", например Rails - см. сгенерированные SQL-запросы в файлах журналов, а затем grep файлы для тех, которые вы хотите, при желании.
Если вы используете mysql, я бы посмотрел на mysqlbinlog. Он будет отслеживать все, что потенциально обновляет данные. вы можете легко вытащить все, что вам нужно из этого журнала.
SQL Server? Если так...
Собственно, я бы сделал это на конце SQL. Вы можете настроить трассировку и собрать каждый запрос, который приходит через соединение с определенным именем приложения. Если вы сохраните его в таблице, вы можете легко запросить эту таблицу позже.
Слегка обновленная версия ответа @luca как минимум для Rails 4 (и, вероятно, Rails 5)
Поместите это в config/initializers/sql_logger.rb
:
connection = ActiveRecord::Base.connection
class << connection
alias :original_exec :execute
def execute(sql, *name)
# try to log sql command but ignore any errors that occur in this block
# we log before executing, in case the execution raises an error
begin
File.open(Rails.root.join("log/sql.log"), 'a') do |file|
file.puts Time.now.to_s + ": " + sql
end
rescue Exception => e
"Error logging SQL: #{e}"
end
# execute original statement
original_exec(sql, *name)
end
end