How to log log level for each log in RoR application? - ruby

I want something like:
[INFO] User initiated request GET '/'
[ERROR] 500 Internal failure
I checked config.log_tags but I do not see an intuitive way to do this.
Note: One way I found is to override the Logger::add function. But would prefer a more standard way for this.

Using your rails application logger should print out the level of log
if you have a special rails application where this is not working you can initialize a Rails.logger with STDOUT
irb(main):001:0> Rails.logger.info("test")
test
=> 5
# with STDOUT initializing
irb(main):002:0> Rails.logger = Logger.new(STDOUT)
irb(main):003:0> Rails.logger.info("test")
I, [2021-04-03T11:27:09.549395 #98808] INFO -- : test
=> true
you can also configure your app per rails documentation https://guides.rubyonrails.org/debugging_rails_applications.html#the-logger

Related

How to write to stdout with Ruby on Bluemix?

I am using Bluemix Ruby buildpack out of the box.
I add some puts lines in my main *.rb file but nothing appears when tailing logs:
cf logs myapp
Searching the docs, I found this post at developerWorks where it is recommended to set runtime into development mode.
I have tried with:
cf set-env myapp RAILS_ENV development
and also adding to the code:
ENV['RAILS_ENV'] = 'development'
but nothing appears in the logs.
Also tried Sinatra options (after changing the code) with same results:
set :environment, :development
set :logging, true
An interesting thing, is that if I stop the app, then all my puts appears after the stacktrace of the FATAL SignalException: SIGTERM error. It seems like a buffer flush contention or anything like that?
Any advice? Thanks!
You can add the following line to your config.ru file. This will disable buffering to stdout and allows your puts commands to stdout to appear correctly in the log output.
$stdout.sync = true
See the answer at What STDOUT.sync = true means? for more details about how puts buffers.
Not Sure but have you tried the following links
https://developer.ibm.com/answers/questions/21548/debugging-a-ruby-app-in-bluemix-with-puts-or-print-statements-written-to-the-log-is-it-possible.html
http://www.ibm.com/developerworks/aix/library/au-unix-commandline/

How to use Logger inside a Resque's worker in a pure ruby application

I have a ruby application (not Rails) using Resque. I'd like to know what's going on in one of the worker I have.
To do that, I use the Logger class as stated in the officiel documentation.
Below is how I log inside a worker:
require 'resque'
require 'logger'
<code>
Resque.logger = Logger.new File.new('logfile.log', 'a')
Resque.logger.info "Whatever"
However, when running my worker, nothing is actually being logged. It's as if the worker is actually ignoring all those log instructions. No error is raised. The other pieces of code actually work - only the logging part is ignored.
I tried to use the logger class itself (ie logger = Logger.new) but the result is the same.
Do you have any idea on how I can actually log something inside my resque worker?
Thanks!
Use the following:
Logger.new(path_to_log_file).info(anything)
You are missing the log level to enabled printing info logs, according to the documentation you linked there, you can use something like this
Resque.logger.level = Logger::DEBUG
then if you look into Logger docs it lists levels as
DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
so if you are using logger.info you either need Logger::DEBUG or Logger::INFO to have the logged string to show up.
Also make sure the logger initialization is run by the process running the workers, and not just the process enqueueing jobs.
my environment: rails 5.0.1, resque: 1.26.0.
I tried config the resque logger in config/initializers/resque.rb and lib/tasks/resuqe.rake, they neither work for me.
but config the resque logger inside every job, that works for me, although it is not perfect.
# update_xxx_job.rb
class UpdateXxxJob
def self.perform
Resque.logger = Logger.new("#{Rails.root}/log/resque.log")
Resque.logger.level = Logger::DEBUG
Resque.logger.info 'Job starts'
...
end
end
more details in another answer.

Rails + Heroku + RSpec : How to control logging

I have a Ruby on Rails 3.2 application which runs on Heroku. I'm using RSpec for my test suite.
When I started, I just used statements such as
p "Order completed at #{Time.now.to_s}"
to generate logs. I did this because Heroku uses its magical jiggery-pokery to divert all logs to STDOUT anyways.
However, my test suite prints all kinds of logs to STDOUT now, and it is very distracting. I would like those logs to appear when the application is deployed to Heroku, but I don't want to see them on my STDOUT output along with my RSpec output.
Is there a way to divert STDOUT to a file such as log/test.log, or alternatively, use a logging API which will do what I want?
I'm not intimately familiar with the particularities of Heroku's implementation, but you should be able to choose your own file for logging without problem. If they made logging to a file impossible I would be incredibly surprised. You can define your logger in environment.rb differently for prod (ie Heroku) and dev with something like the following in the appropriate conditional:
Rails.logger = Logger.new(STDOUT)
Rails.logger = Log4r::Logger.new("Application Log")
or in your Initializer like so:
config.logger = Logger.new(STDOUT)
config.logger = Log4r::Logger.new("Application Log")
Note that you have lots of options for your logger, for example you can use Log4r instead of the built-in logger.
Check out the RoR Debugging Guide for more
Make sure you include the gem only in your production group to avoid this issue.
group :production do
gem 'rails_12factor'
end

Debug a daemon in RubyMine

Is there any way to debug a daemon in Ruby Mine. The way I am calling this file is like this
Daemons.run(file, options)
where file is the name of file and options is the bunch of options that I am passing to the file.
I'm also trying to debug a Rails daemon (gem daemons). The ActiveMessaging poller script in particular. However the ruby-debug-ide fails to attach due to various reasons (race conditions, etc).
The solution I came up with is to use gem rails-daemons. This works with ActiveMessaging and allows to me to create all kinds of daemons, and importantly, be able to debug them in RubyMine
Workaround
Use https://github.com/mirasrael/daemons-rails to create a new daemon. This works with RubyMine 6.3.3, Rails 4, Ruby 2.1.2 on OSX 10.8.x
Sample Daemon
mqpoller.rb (after running rails generate daemon mqpoller)
#!/usr/bin/env ruby
# You might want to change this
ENV["RAILS_ENV"] ||= "development"
root = File.expand_path(File.dirname(__FILE__))
root = File.dirname(root) until File.exists?(File.join(root, 'config'))
Dir.chdir(root)
require File.join(root, "config", "environment")
$running = true
Signal.trap("TERM") do
$running = false
end
while($running) do
# Replace this with your code
Rails.logger.auto_flushing = true
Rails.logger.info "This daemon is still running at #{Time.now}.\n"
# ADDED MY CODE BELOW HERE TO START ActiveMessaging
Rails.logger = Logger.new(STDOUT)
ActiveMessaging.logger = Rails.logger
# Load ActiveMessaging
ActiveMessaging::load_processors
# Start it up!
ActiveMessaging::start
sleep 10
end

Heroku logging not working

I've got a rails 3.1 app deployed on Heroku Cedar. I'm having a problem with the logging. The default rails logs are working just fine, but when I do something like:
logger.info "log this message"
In my controller, Heroku doesn't log anything. When I deploy my app I see the heroku message "Injecting rails_log_stdout" so I think calling the logger should work just fine. Puts statements end up in my logs. I've also tried other log levels like logger.error. Nothing works. Has anyone else seen this?
MBHNYC's answer works great, but it makes it difficult to change the log level in different environments without changing the code. You can use this code in your environments/production.rb to honor an environment variable as well as have a reasonable default:
# https://github.com/ryanb/cancan/issues/511
config.logger = Logger.new(STDOUT)
config.logger.level = Logger.const_get((ENV["LOG_LEVEL"] || "INFO").upcase)
Use this command to set a different log level:
heroku config:set LOG_LEVEL=error
I was just having the same issue, solved by using the technique here:
https://github.com/ryanb/cancan/issues/511
Basically, you need to specify the logger outputs to STDOUT, some gems interfere with the logger and seem to hijack the functionality (cancan in my case).
For the click lazy, just put this in environments/production.rb
config.logger = Logger.new(STDOUT)
config.log_level = :info
As of the moment, it looks like heroku injects these two plugins when building the slug:
rails_log_stdout - https://github.com/ddollar/rails_log_stdout
rails3_server_static_assets - https://github.com/pedro/rails3_serve_static_assets
Anything sent to the pre-existing Rails logger will be discarded and will not be visible in logs. Just adding this for completeness for anyone else who ends up here.
The problem, as #MBHNYC correctly addressed, is that your logs are not going to STDOUT.
Instead of configuring manually all that stuff, Heroku provides a gem that does this all for you.
Just put
gem 'rails_12factor', group: :production
in your Gemfile, bundle, and that's it!
NOTE: This works both for Rails 3 and 4.
Source: Rails 4 on Heroku

Resources