Rails Caching Log Level - ruby-on-rails

With the new caching options in Rails 2.1 i get nice entires in my log along the lines of
Cached fragment hit: views/homepage (0.16549)
However they are logged at the :debug level, which is the same level as the SQL output. I want to be able to disable the SQL output, and still see the cache info. How can I do this

well you could instantiate a specific logger for ActiveRecord and set it's log level to :info while leaving the default logger at debug ...
ActiveRecord::Base.logger = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}_database.log")
ActiveRecord::Base.logger.level = Logger::INFO # should set the log_level to info for you
from http://wiki.rubyonrails.org/rails/pages/HowtoConfigureLogging
or you could reopen AbstractAdapter and override the log(sql,name) method so it does nothing
http://api.rubyonrails.com/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter.html#M001242

Related

Approach to a custom rails logger

My Rails application runs in Heroku; recently, we have changed the Heroku LOG_LEVEL to WARN as the system logs flooded with so many unwanted information. But still, in some of the areas, I wanted to use Rails.logger.info;
Currently, in Heroku we have this:
LOG_LEVEL = WARN
And in production.rb, still that is
config.log_level = :info
config.log_formatter = ::Logger::Formatter.new
The above configuration we didn't change it, as the precedence is for LOG_LEVEL if we set that. So with the above configuration, if we put Rails.logger.info "Hello world," that will not work because the logger will only handle the logs equal or higher to warn in importance.
So we have tried one other way.
Created a new initializer called custom_logger.rb; we put
$INFO_LOGGER = Rails.logger.dup
$INFO_LOGGER.level = :info
then wherever we wanted to use info, we just called $INFO_LOGGER.info "Hello World," this prints
Is this a correct approach, like using the global variable?
Is this a correct approach, like using the global variable?
This question could be considered opinion based, so in my opinion I would not recommend it. Additionally the question posed in the title is regarding a custom logger and while we could implement one to facilitate the request I would propose a simpler solution that will still log exactly what you want, to the current log file, and without the need for a custom logger, a secondary logger, or any kind of global variable.
My Suggestion:
Rails uses ActiveSupport::Logger by default which is essentially just a ruby Logger.
If there are messages you always want logged regardless of the level you can use Logger#unknown.
Per the Documents for the Logger class:
Levels:
UNKNOWN - An unknown message that should always be logged.
Logger#unknown
Log an UNKNOWN message. This will be printed no matter what the logger's level is.
So You can use this to your advantage for the messages that you always want to show while still avoiding the noise of the standard info messages:
For Example:
Rails.logger.info "Noisy message" # won't show when LOG_LEVEL > INFO
Rails.logger.unknown "VERY IMPORTANT MESSAGE" # will show no matter what the level is set to
You don't want to use global variables. Instead create a custom class for example
class MyLogger
class << self
def info(*args)
new.info(*args)
end
end
delegate :info, to: :logger
attr_reader :logger
def initialize
#logger = ActiveSupport::Logger.new(Rails.root.join("log/my_logger.#{Rails.env}.log"))
#logger.formatter = ::Logger::Formatter.new
end
end
Now you can call MyLogger.info("this is a test message") and it will output the message in the log file regardless of the LOG_LEVEL or config.log_level = :info

Rails logging to a clean, custom file

I've put the following line in my config/application.rb:
config.logger = Logger.new("#{Rails.root}/log/app.log")
However both app.log and development.log include all the console "noise".
Is there a way to write on a clean app.log file without the noise?
If your goal is to just limit the amount of information in your log, you'd want to simply adjust your log level. This is typically done at the environment level, not the application level, as you'd want verbose logs in development, but quieter logs in test/production.
config.log_level defines the verbosity of the Rails logger. This
option defaults to :debug for all environments. The available log
levels are: :debug, :info, :warn, :error, :fatal, and :unknown.

What is the difference between using 'config.log_level' and 'Rails.logger.level'?

I've seen examples of both statements, and both control the level of logging whether using descriptive values (:debug, :info, :warn, :error, :fatal, :unknown) or numeral (1-5).
config.log_level is only used in environment initializer files.
Rails.logger.level can be used almost anywhere.
See this documentation.
I have never set log-level anywhere else than in my env.-initializer files. I guess maybe one possible usecase for using Rails.logger.level could be when for ex. you have a development environment so it has a log-level of :debug but you don't want to bloat you log files with a lot of db-querys and unneccessary debug-info- then you can filter out only info-level log:
Rails.logger.level = 1
# Some code that gives out too much debug information
Rails.logger.level = 0
# Code that's ok for debug information
And respectively in prod-env. if you, for some reason, want to print out debug info in a certain place of the code while environment log level is set to :info.

Logging in Ruby on Rails in Production Mode

I would like to view some variables in controller, it tried the following:
Rails.logger.debug "Year: #{Time.now.year}"
puts "Year: #{Time.now.year}, Month: #{#month}"
where can I see the output for Logger or Puts in production mode? Do I need so set something up to view these somewhere?
The normal log level in production is info, so debug logs are not shown.
Change your logging to
Rails.logger.info "Year: #{Time.now.year}"
to show it in production.log.
Alternatively (but not a good idea) you can raise the logging level in /config/environments/production.rb:
config.log_level = :debug
Update Rails 4.2:
Now the default debug level in all environments is :debug (as #nabilh mentioned).
If you want you production environment less chattery, you can reset your log level in /config/environments/production.rb to the former :info:
config.log_level = :info
While I believe #martin-m is right that you probably don't want to clutter your logs by using config.log_level = :debug in /config/environments/production.rb, I believe the default logging level in all environments is debug as of Rails 4.2. So debug logs (and all levels up) will be shown in production unless you specify otherwise.
So in response to your question, you can now write:
Rails.logger.debug "Year: #{Time.now.year}" and see the results in /log/production.log.
See here for more detailed documentation. Here is the documentation for Rails 4.1 for comparison.
If you have a production app that you may need to temporarily change log levels, you might want to use an environment variable to be able to set level without modifying code and redeployment, though your app would need to be restarted, you could take this approach:
config/environment/production.rb
MyApp::Application.configure do
#...
log_level = :info #default state
[:debug, :info, :warn, :error, :fatal, :unknown].each do |level|
if ENV['LOG_LEVEL']&.to_sym == level
log_level = level
end
end
config.log_level = log_level
#...
end

How to set Rails Cache log level separately?

I use a pretty old rails version which is 2.3.2 because of legacy project.
I set global log_level to :debug in our rails app. But since we also use Rails.cache the log file are full of annoying lines such as
Cache read: ...
Cache miss: ...
I want to just suppress these but not affect other 'more useful' info such as SQL logging.
How to do that?
Well, after initializing your cache store (in the example below, I use memory store) in your specific environment.rb file, you can redirect cache_store's log to a separate file and also tweak the logger level:
config.cache_store = ActiveSupport::Cache::MemoryStore.new(:expires_in => 5.minutes)
config.cache_store.logger = Logger.new("#{Rails.root}/log/#{ENV['RAILS_ENV']}_cache.log")
config.cache_store.logger.level = Logger::INFO
In addition to that, the cache store has a method called silence! that will turn off the logger :-|
config.cache_store.silence!

Resources