Module: ActiveRecord::QueryLogs
- Defined in:
- lib/active_record/query_logs.rb,
lib/active_record/query_logs_formatter.rb
Overview
Active Record Query Logs
Automatically append comments to SQL queries with runtime information tags. This can be used to trace troublesome SQL statements back to the application code that generated these statements.
Query logs can be enabled via Rails configuration in config/application.rb
or an initializer:
config.active_record. = true
By default the name of the application, the name and action of the controller, or the name of the job are logged. The default format is SQLCommenter. The tags shown in a query comment can be configured via Rails configuration:
config.active_record. = [ :application, :controller, :action, :job ]
Active Record defines default tags available for use:
-
application
-
pid
-
socket
-
db_host
-
database
-
source_location
Action Controller adds default tags when loaded:
-
controller
-
action
-
namespaced_controller
Active Job adds default tags when loaded:
-
job
New comment tags can be defined by adding them in a Hash
to the tags Array
. Tags can have dynamic content by setting a Proc
or lambda value in the Hash
, and can reference any value stored by Rails in the context
object. ActiveSupport::CurrentAttributes can be used to store application values. Tags with nil
values are omitted from the query comment.
Escaping is performed on the string returned, however untrusted user input should not be used.
Example:
config.active_record. = [
:namespaced_controller,
:action,
:job,
{
request_id: ->(context) { context[:controller]&.request&.request_id },
job_id: ->(context) { context[:job]&.job_id },
tenant_id: -> { Current.tenant&.id },
static: "value",
},
]
By default the name of the application, the name and action of the controller, or the name of the job are logged using the SQLCommenter format. This can be changed via config.active_record.query_log_tags_format
Tag comments can be prepended to the query:
ActiveRecord::QueryLogs.prepend_comment = true
For applications where the content will not change during the lifetime of the request or job execution, the tags can be cached for reuse in every query:
config.active_record. = true
Defined Under Namespace
Modules: LegacyFormatter Classes: GetKeyHandler, IdentityHandler, SQLCommenter, ZeroArityHandler
Class Attribute Summary collapse
-
.cache_query_log_tags ⇒ Object
:nodoc:.
-
.prepend_comment ⇒ Object
:nodoc:.
-
.taggings ⇒ Object
:nodoc:.
-
.tags ⇒ Object
:nodoc:.
-
.tags_formatter ⇒ Object
:nodoc:.
Class Method Summary collapse
-
.call(sql, connection) ⇒ Object
:nodoc:.
-
.clear_cache ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#query_source_location ⇒ Object
:nodoc:.
Class Attribute Details
.cache_query_log_tags ⇒ Object
:nodoc:
115 116 117 |
# File 'lib/active_record/query_logs.rb', line 115 def @cache_query_log_tags end |
.prepend_comment ⇒ Object
:nodoc:
115 116 117 |
# File 'lib/active_record/query_logs.rb', line 115 def prepend_comment @prepend_comment end |
.taggings ⇒ Object
:nodoc:
114 115 116 |
# File 'lib/active_record/query_logs.rb', line 114 def taggings @taggings end |
.tags ⇒ Object
:nodoc:
114 115 116 |
# File 'lib/active_record/query_logs.rb', line 114 def @tags end |
.tags_formatter ⇒ Object
:nodoc:
114 115 116 |
# File 'lib/active_record/query_logs.rb', line 114 def @tags_formatter end |
Class Method Details
.call(sql, connection) ⇒ Object
:nodoc:
139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/active_record/query_logs.rb', line 139 def call(sql, connection) # :nodoc: comment = self.comment(connection) if comment.blank? sql elsif prepend_comment "#{comment} #{sql}" else "#{sql} #{comment}" end end |
.clear_cache ⇒ Object
:nodoc:
151 152 153 |
# File 'lib/active_record/query_logs.rb', line 151 def clear_cache # :nodoc: self.cached_comment = nil end |
Instance Method Details
#query_source_location ⇒ Object
:nodoc:
156 157 158 159 160 161 162 |
# File 'lib/active_record/query_logs.rb', line 156 def query_source_location # :nodoc: Thread.each_caller_location do |location| frame = LogSubscriber.backtrace_cleaner.clean_frame(location.path) return frame if frame end nil end |