Rails log too verbose
Asked Answered
M

6

24

How can I prevent Rails to log too much? Here is a typical trace in my production.log file, many partials, cache hits... It's useful in development but I don't want it in my production environment.

Started GET "/?redirected=true" for 46.193.131.53 at 2012-08-16 18:39:20 +0200
Processing by HomeController#index as HTML
  Parameters: {"redirected"=>"true"}
  Rendered application/_successfully_connected.html.haml (0.8ms)
  Rendered hotspot_infos/_infos.html.haml (0.4ms)
  Rendered application/_hotspot_infos.html.haml (1.8ms)
  Rendered application/_news.html.haml (0.3ms)
Read fragment views/social-zone-341-directory (0.5ms)
  Rendered application/_directory.html.haml (2.5ms)
  Rendered application/_meteo.html.haml (1.1ms)
  Rendered application/_notifications.html.haml (0.8ms)
  Rendered application/_like_button.html.haml (0.3ms)
  Rendered application/_navbar.html.haml (4.2ms)
  Rendered application/_connection.html.haml (0.5ms)
  Rendered application/_gallery.html.haml (0.2ms)
  Rendered application/_search_bar.html.haml (0.4ms)
  Rendered pictures/_picture_frame.html.haml (0.3ms)
  Rendered application/_profile_preview.html.haml (1.4ms)
  Rendered application/_profile_block.html.haml (1.7ms)
  Rendered application/_menus.html.haml (3.3ms)
  Rendered application/_left_pane.html.haml (5.5ms)
  Rendered application/_langs.html.haml (0.8ms)
  Rendered application/_footer.html.haml (1.9ms)
  Rendered application/_flash_modal.html.haml (0.1ms)
  Rendered application/_connection_required.js.erb (0.2ms)
Completed 200 OK in 159ms (Views: 25.5ms | ActiveRecord: 88.0ms)

Thank's for your help

PS: I'm using Rails 3.2.6

Modernity answered 16/8, 2012 at 16:52 Comment(1)
Use Lograge, best gem I've found for cleaning up Rails loggingEmpirical
M
32

In Rails 4 there will be a setting to clean up logs:

config.action_view.logger = nil

To achieve that in Rails 3, you have to monkey patch ActionView:

module ActionView
  class LogSubscriber < ActiveSupport::LogSubscriber
    def logger
      @memoized_logger ||= Logger.new('/dev/null')
    end
  end
end
Modernity answered 17/8, 2012 at 10:0 Comment(3)
FWIW, this monkey-patch apparently causes a file-handle leak (at least with Rails 3.2.12). I recommend replacing the Logger.new('/dev/null') with @memoized_logger ||= Logger.new('/dev/null'). Bitter voice of experience here. :)Orthorhombic
To keep partials logging enabled when log level is debug, you can use @memoized_logger ||= Rails.logger.debug? ? super : Logger.new('/dev/null')Lifesaving
Does this not also suppress potential important logs like when there was an error in the rendering?Weekly
S
6

You need to set your config.log_level differently. Learn about Log Levels.

For example, add the following to config/evironments/production.rb

config.log_level = :warn

Yours is likely set to :debug or :info.

Supersensual answered 16/8, 2012 at 17:49 Comment(1)
The problem is when the log level is set to warn, i get nothing at all in my log file. I want the basic informations to get logged like "Processing by HomeController#index as HTML" or "Completed 200 OK in 369ms (Views: 272.3ms | ActiveRecord: 8.1ms)"Modernity
L
4

I put this in my initializers to monkeypatch certain logging to go to debug instead of info:

module ActionView
  class LogSubscriber
    def render_template(event)
      message = "Rendered #{from_rails_root(event.payload[:identifier])}"
      message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
      message << " (#{event.duration.round(1)}ms)"
      debug(message)
    end
    alias :render_partial :render_template
    alias :render_collection :render_template
  end  
end

module ActionController
  class LogSubscriber
    # Use debug logging for read_fragment
    # %w(write_fragment read_fragment exist_fragment? expire_fragment expire_page write_page).each do |method|
    %w(read_fragment).each do |method|
      class_eval <<-METHOD, __FILE__, __LINE__ + 1
        def #{method}(event)
          return unless logger.info?
          key_or_path = event.payload[:key] || event.payload[:path]
          human_name  = #{method.to_s.humanize.inspect}
          debug("\#{human_name} \#{key_or_path} (\#{event.duration.round(1)}ms)")
        end
      METHOD
    end
  end
end
Lint answered 26/7, 2013 at 15:45 Comment(0)
P
0

Here in 2021, I suggest using the semantic_logger (and rails_semantic_logger) gem(s) for this. (Docs link)

Lograge is also an option, but it seems less well-maintained at this point.

Pardoes answered 28/12, 2021 at 1:13 Comment(0)
C
0

Log levels can be set on a per-component basis. It's possible, for example, to set the general log_level to INFO, but set the components to a quieter level.

# config/environments/production.rb
config.log_level = :info

# Build quieter loggers for particular components.
build_logger = ->(level) {
  # This is the recommend way to build a logger, from
  # https://guides.rubyonrails.org/v6.1/configuring.html
  logger = ActiveSupport::Logger.new(STDOUT, level: level)
  logger.formatter = config.log_formatter
  ActiveSupport::TaggedLogging.new(logger)
}
config.action_controller.logger = build_logger[::Logger::ERROR]
config.active_job.logger = build_logger[::Logger::ERROR]
config.action_view.logger = build_logger[::Logger::ERROR]
config.assets.logger = build_logger[::Logger::ERROR]
config.action_mailer.logger = build_logger[::Logger::ERROR]

This is a configuration that my team is considering for a production app with a throughput of 2-3 kilorequests per minute. It will allow us to write low-volume INFO-level logging for important business logic, without overwhelming our logging budget with high-volume INFO-level logging from components like ActionController.

Coroner answered 20/4, 2022 at 4:55 Comment(0)
M
0

To remove logging of partials, you can do this from an initializer:

ActiveSupport.on_load(:action_view) do
  ActiveSupport::Notifications.unsubscribe "render_partial.action_view"
end
Mirisola answered 19/5, 2023 at 16:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.