14

I want to save to a log file some SQL query rails performs, (namely the CREATE, UPDATE and DELETE ones) therefore I need to intercept all queries and then filter them maybe with some regexp and log them as needed.

Where would I put such a thing in the rails code?

6 Answers 6

15

Here a simplified version of what c0r0ner linked to, to better show it:

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
Sign up to request clarification or add additional context in comments.

1 Comment

The post on misuse.org notes that it should be loaded by application.rb, in there you could require a file containing your override code. (On Rails 2, you're stuck with the environment config files.)
5

SQL logging in rails - In brief - you need to override ActiveRecord execute method. There you can add any logic for logging.

3 Comments

And remember to not intercept the logging queries themselves, or you'll get an infinite loop...
@DanSingerman That's assuming you're going to log the queries in SQL itself.
404 not found. link is missing
2

As a note for followers, you can "log all queries" like Rails - See generated SQL queries in Log files and then grep the files for the ones you want, if desired.

Comments

1

If you are using mysql I would look into mysqlbinlog . It is going to track everything that potentially updates data. you can grep out whatever you need from that log easily.

http://dev.mysql.com/doc/refman/5.0/en/mysqlbinlog.html

http://dev.mysql.com/doc/refman/5.0/en/binary-log.html

Comments

0

SQL Server? If so...

Actually, I'd do this at the SQL end. You could set up a trace, and collect every query that comes through a connection with a particular Application Name. If you save it to a table, you can easily query that table later.

Comments

0

Slightly updated version of @luca's answer for at least Rails 4 (and probably Rails 5)

Place this in 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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.