I have a rails 5 app that I'd like to push to heroku, in which I have a logger that creates a daily log file, which I use to print out various pieces of status information. This works in development, but I get an error when I try to push it to heroku (after pushing everything to git).
The error I receive: "Errno::ENOENT: No such file or directory # rb_sysopen - /tmp/build_e3fe50d2e37e0a51f1bc7d94dd1fc2f3/log/daily_logs_production/2016-12-19.log
"
Here is the relevant portion from production.rb:
if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new("#{Rails.root}/log/daily_logs_production/#{Time.now.strftime('%Y-%m-%d')}.log", 'daily')
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
Any idea what is wrong? Thank you!
whether or not you are getting an error can be neglected.
due to the ephemeral filesystem of heroku dynos you should not use it for such purposes.
install a plugin of the Logging category instead.
Related
I am working on a Rails app which they are running in AWS EC2,
this app is coming from Heroku, and this app is in Heroku is generating the logs, all show like info and verbose in the console log
However, the same app running in the AWS ec2 is not generating the same logs report as in the heroku.
They are generated in the Console log but they are not saving all log in the cloud watch or log files in rails folder.
I assume it's a more RAILS_LOG_TO_STDOUT issue on EC2? as they are built by Heroku?
config.log_formatter = ::Logger::Formatter.new
if ENV['RAILS_LOG_TO_STDOUT'].present?
logger = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
in the EC2 console log, this is perfect outcome log report and that what I'm looking for
but in Log report in log folder and cloudwatch show different report
Not sure where I am missing something even I have added this line and outcome still same
ActiveRecord::Base.verbose_query_logs = true
config.log_level = :info
config.log_level = :debug
Fixed as I remove two items in the gem file
gem 'rails_12factor'
gem 'rails_stdout_logging'
as it generates all the verbose, info, debug into the log files at the log folder. and it show details in the cloudwatch
We have a Rails 6 app, which is being deployed to an Ubuntu server with the following setup:
Nginx 1.17 & passenger 6, releases are deployed using capistrano v3
I could find the following log files:
Nginx (access & error logs):
/var/log/nginx/access.log & /var/log/nginx/error.log
Passenger logs: (on staging env)
/home/deploy/myapp/current/log/staging.log
The logs written in Passenger logs (which is the one that shall have the application log as I understand), has only Ruby logs for the Table migrations and creation but not ruby application log
So none of the above logs have the Rails application logs (i.e.: the log that shows Rails details like the rails s output in the dev env) & the nginx access log shows only the static assets logs when a page is loaded but not the ruby or the sql logs
The logical place to me, staging.log file, only has stale log data & doesn't get any new Rails logs written to it
Where is the Rails application logs please?
Rails writes its logs by default to the log/ENVIRONMENT.log file (where ENVIRONMENT is replaced by the value of your RAILS_ENV environment variable.
On your production environment, the logs are thus likely written to /home/deploy/myapp/current/log/production.log
Note that Rails tries to create that file if it doesn't exist. If the user running your app doesn't have the necessary permissions to create (or write to) the file, it doesn't write logs at all.
Guided by Nathan comment & credit for solving this goes to him:
The cause of the issue is:
In the staging.rb, I had this config for the logs
& the env variable was defined as export RAILS_LOG_TO_STDOUT='enabled'
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
So removing the env variable:
RAILS_LOG_TO_STDOUT='enabled'
Allowed the Rails log to show as expected in the correct directory:
/home/user/project-name/current/log/staging.log
How to see the live server log in production like it is shown in development?
My app is on digitalOcean, if that helps. I am using unicorn as my production server.
When I do tail -f log/production.log, I can just see some migration info like this, but not the live requests info along with the SQL queries being run.
Also in my production.rb, I changed config.log_level to :debug
Try adding these lines of code into config/environments/production.rb:
Rails.logger = Logger.new(STDOUT)
config.logger = ActiveSupport::Logger.new("log/#{Rails.env}.log")
Reference:
This article for more info on logger
My rails4 application is running with docker. It runs a rake task for fetching messages from AWS SQS.
The problem I met is that logs can't show up in a console in time. The console doesn't show anything until exception/error comes. In other words, if my application works fine, no logs come to console. But if application went wrong, all the logs(info, warn and error) come together!
I already configure the config/production.rb as blow:
config.logger = Logger.new(STDOUT)
config.logger.level = Logger.const_get('INFO')
config.log_level = :info
I google 'rake task log was not working', but nothing useful. Is this a rails log problem or a rake task log problem, or maybe a docker problem?
Hoping that get some advice!
Try disabling output buffering to STDOUT. You can do this by adding this line to your rake task:
$stdout.sync = true
For Rails 4.x the log level is configuration
# Enable stdout logger
config.logger = Logger.new(STDOUT)
# Set log level
config.log_level = :ERROR
The logger level is set on the logger instance from config.log_level at:
(https://github.com/rails/rails/blob/v4.2.4/railties/lib/rails/application/bootstrap.rb#L70)
I have some Rake tasks that produce CSV output which I'd like to redirect to a file and open with other tools, but when I run heroku rake foo > foo.csv I get log messages (SQL queries, etc.) in my output.
I've tried Rails.logger = Logger.new('/dev/null') and Rails.logger = Logger.new(STDERR) at the top of the Rake task and while those function as expected locally, they don't have any noticeable effect when I run the task on Heroku.
I'm not too shocked that Heroku would squash STDOUT and STDERR together but it's a mystery to me why sending to /dev/null would not kill the output.
Any help greatly appreciated.
Rails v3.0.0, Heroku bamboo-ree-1.8.7 stack, rake 0.9.2.
I was having the same problem, though I didn't run into it until I changed config/environments/production.rb to have this:
config.logger = Logger.new(STDOUT)
(I did this so that my app would log to the heroku log.)
My fix was this:
config.logger = Logger.new(STDOUT) unless 'rake' == File.basename($0)
From Heroku | Dev Center | Logging:
When a Rails app is pushed, we will automatically install the rails_log_stdout plugin into the application which will redirect logs to stdout.
I think Heroku includes (in the output sent through your git push command) a notification about this (and one other addition: for serving static/public content, if I remember correctly). You may only see the notifications for certain kinds of pushes though (complete slug rebuilds?). I remember seeing it when I recently pushed a new application to a Bamboo/MRI-1.9.2 stack, but I do not think I got the message every time I pushed changes to just the application’s code (maybe adding a new gem to the Gemfile is enough to trigger it?).
Several Rails subsystems keep their own logger binding (independent bindings whose values are often initialized from Rails.logger; reassigning the latter does not change the former):
ActiveRecord::Base.logger
ActionController::Base.logger
ActionMailer::Base.logger
Heroku’s changes probably set a new value for Rails.logger before ActiveRecord is initialized. When ActiveRecord is eventually loaded, it sets its own logger to be the same as Rails.logger (the Heroku/stdout one). When your task runs, it reassigns Rails.logger, but it is too late for this to have any effect on ActiveRecord::Base.logger (the only most likely to be handling the SQL logs).
You probably need to reassign some of these other logger bindings to squelch the logging going to STDOUT. Some other likely locations are listed in rails_log_stdout’s init.rb in the Rails 2 section.
I faced the same problem and found the following to be a more convenient workaround:
Add the following to config/environments/production.rb
config.logger.level = Logger.const_get(ENV['LOG_LEVEL'] ? ENV['LOG_LEVEL'].upcase : 'INFO')
Push to Heroku, then when you run your rake tasks add LOG_LEVEL="fatal" to the end of the command (replace foo and foo.csv with your things):
heroku run rake foo LOG_LEVEL="fatal" > foo.csv
I have log_level set to fatal in the above example, but it can be any of the following: debug|info|warn|error|fatal. In our case, using the highest would mean nothing but the most fatal errors are outputted into the csv file.
Just to help anyone with a "fresh" Rails project pushing to Heroku:
You need a combination of #Matt Burke and #Hengjie's answer:
Add these two lines to config/environments/production.rb:
config.logger = Logger.new(STDOUT)
config.logger.level = Logger.const_get(ENV['LOG_LEVEL'] ? ENV['LOG_LEVEL'].upcase : 'INFO')
This will setup a new STDOUT logger and allow you to easily control the log resolution with the LOG_LEVEL environment variable.
I solved this problem with the following change to production.rb:
if 'rake' == File.basename($0)
ActiveRecord::Base.logger = Logger.new('rake.log', 'daily')
end
I suppose we could ignore the output as well
if 'rake' == File.basename($0)
ActiveRecord::Base.logger = Logger.new('/dev/null')
end