Is there a way to stop rails logging everything? - ruby-on-rails

I don't want it to log incoming IPs, I don't want it to log any internal happenings.
I just want Rails to process the requests as they come in and that's that.
Is this possible to do?
How can I prevent having a growing development.log or production.log?

You could just replace the Rails logging facilities with loggers that log to /dev/null:
class NullLoggerRailtie < Rails::Railtie
initializer 'null_logger', :before => 'initialize_logger' do |app|
Rails.logger = ActiveRecord::Base.logger = ActionController::Base.logger = ::Logger.new("/dev/null")
end
end
This will reroute all of the Rails logging to the null device, rather than letting it go to a file anywhere. The logging will still happen, but it'll just be immediately trashed.

Set the log Level.
The available log levels are: :debug, :info, :warn, :error and :fatal
If you want to know the current log level you can call the Rails.logger.level method.
To change the log level use config.log_level = :fatal in your environment initializer, or
Rails.logger.level = 0 inline at any time
Another option might be to symbolicly link the log file to /dev/null

Simplifying Chris Heald answer, you can set the logger to /dev/null by environment:
Rails.application.configure do
config.logger = Logger.new("/dev/null")
end
Just place the code in the right file(s):
Development: config/environments/development.rb
Test: config/environments/test.rb
Production: config/environments/production.rb
All environments: congig/applications.rb

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.

Rails.logger.info is not working in initializer

Rails.logger.info does not write any information to log when used in initializer.
How to get logging in initializer?
Rails.logger = Logger.new(STDOUT)
before
MyServer::Application.initialize!
in /config/environment.rb
May be the log level is silencing your message. Is it production or development?
Take a look to your config.log_level in your config/*.yml files

Rails Server needs restart every time I make changes? why?

Every time I change anything in controller's or in models, I have to restart the server for it to take effect.But that wasn't always the case, it used to work normally before, when I changed anything, but i don't know what happened now ?
My Rails version is 3.2.11
In my development environment file i have set config.cache_classes = false.
Please help..
My development.rb file is as follows
Testapp::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
# Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
# Raise exception on mass assignment protection for Active Record models
config.active_record.mass_assignment_sanitizer = :strict
# Log the query plan for queries taking more than this (works
# with SQLite, MySQL, and PostgreSQL)
config.active_record.auto_explain_threshold_in_seconds = 0.5
# Do not compress assets
config.assets.compress = false
# Expands the lines which load the assets
config.assets.debug = true
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
end
I have got the answer..
After adding following line in my config/environments/development.rb file my issue has been resolved.
config.reload_classes_only_on_change = false
start your server using below command in console
rails server -e development
if not started then give your rails version and which sever you use for run rails application.
more Configuration
modify your config/environments/development.rb file to:
config.serve_static_assets = false
An additional situation where this can come up is in a virtualized environment where the files are being edited on the host operating system, and the guest operating system's file event manager doesn't generate events for file changes.
A solution for this situation is to comment out the following line in config/environments/development.rb:
# Use an evented file watcher to asynchronously detect changes in source code,
# routes, locales, etc. This feature depends on the listen gem.
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
Thus giving:
# Use an evented file watcher to asynchronously detect changes in source code,
# routes, locales, etc. This feature depends on the listen gem.
# config.file_watcher = ActiveSupport::EventedFileUpdateChecker
This forces rails to actually check file modification times instead of expecting to get filesystem events.
There is a good note for VirtualBox users, posted as comment by user Ninjaxor:
For Vagrant/ virtual box users, there's a bug where if the host clock
and guest clock are out of sync, it borks rails' reloader.
https://github.com/rails/rails/issues/16678
The file Vagrantfile you find in a directory like this:
.../ruby/gems/sass-3.4.22/vendor/listen
There you have to add this:
# Sync time every 5 seconds so code reloads properly
config.vm.provider :virtualbox do |v|
v.customize ["guestproperty", "set", :id, "--timesync-threshold", 5000]
end
Thanks to user axsuul on GitHub!
I noticed that setting
config.cache_classes = false
is what did the trick for me.

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

Resources