Jruby on Rails logging with Tomcat - ruby-on-rails

I have a jruby/rails (4.1) app that I want to deploy through Tomcat. I made the app log through stdout by adding
config.logger = Logger.new(STDOUT)
in config/application.rb, and the log lines are going to catalina.log.
We would like the app logs to go to a separate Tomcat logfile. Is it possible? how can it be configured?
Thanks!

if you do not set config.logger at all ... it will log to where servlet log goes
so simply do not do anything at all with config.logger (just leave the default) and it should work (assuming JRuby-Rack of course). otherwise there are 2 options :
use a Java logging library (in case of TC that is either JUL or Log4J) and configure JRuby-Rack to delegate
or simply config.logger = Logger.new('logs/rails.log') in this case make sure you set a formatter to include timestamps
NOTE: be aware that in the first case the Java logging library will receive all logs from Rails at the info level (loggers are not mapped "1-to-1") ... this might change in a future JRuby-Rack 1.2 release.

Related

Separate logging for rails application in tomcat

We have three apps running in tomcat at different context path. I am using the default context settings in context.xml. We would like one one of the applications that logs to STDOUT to be able to log to its own file.
It is a ruby on rails application that creates the logger as below. It is built as war using jruby file and deployed to tomcat.
if ENV["LOG_STDOUT"].present?
logger = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
We would like to redirect the output from the app to go to it's own file. At the moment, all output from the rails application goes to localhost.date.txt file. Other apps also log to the same file. For instance, a grails app logs unhandled exceptions to the same file.
Questions:
What is the easiest way to redirect the log output to STDOUT from an app at context path /rails/search it's own file without changing the application code?
I have tried with log4j.jar being copied to the appropriate folders if they exist or create the folders and copy of they dont as per the docmentation on tomcat website without much luck.
How can I stop the app at context /grails/hello to stop logging to the localhost.date.txt file.
I have disabled root logging to STDOUT in grails app log4j config, but it still logs unhandled exceptions. In its log file I have restricted the stacktrace to 5 lines, but in localhost.date.txt file it still prints the full stacktrace. I can disable all logging to consoleHandler, but I cannot do it unless I solve the first question. So any help is appreciated.
Things Tried:
Use log4j and slf4j to redirect logs to their own file using swallowOutput on context
Create new tomcat9 handler, but could'nt marry it to the logging class for rails app
Added properties files at appName/WEB_INF/classes/logging.properties and the file is created but no output is logged to the file.

Where is the Rails app log on ubuntu server (nginx+passenger+capistrano)?

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 increase Heroku log drain verbosity to include all Rails app details?

Presently I'm running a Rails 3.1.x app atop Heroku Celadon Cedar and it seems that log verbosity is very much lacking. I have set the log level to DEBUG a la heroku config:add LOG_LEVEL=DEBUG --app app_name, which matched up to their recommendation, however beyond that I cannot seem to pull in the log/* file contents.
Changing from Thin to Unicorn did increase verbosity slightly, but only in web worker requests. I still cannot pull down the db requests and so forth.
What is the best way to maximize log verbosity via the heroku "drain" mechanism so that one can pull all instance logs into one cohesive log?
(Ideally I'd like to include a method to dump this into one of my own log servers as this is just a pain the rear not being able to readily look at specific events and surrounding conditions in time.)
In staging.rb, production.rb or whatever environment you're running, you can insert the following:
STDOUT.sync = true
logger = Logger.new(STDOUT)
logger.level = 0 # Must be numeric here - 0 :debug, 1 :info, 2 :warn, 3 :error, and 4 :fatal
# NOTE: with 0 you're going to get all DB calls, etc.
Rails.logger = Rails.application.config.logger = logger
### NOTE: Be sure to comment out these:
# See everything in the log (default is :info)
# config.log_level = :debug # Commented out as per Chris' instructions from Heroku
# Use a different logger for distributed setups
# config.logger = SyslogLogger.new
I think the ActiveRecord logger object sends all SQL query logs with a DEBUG severity level. You may need to adjust the Rails.logger log level to get those in production too.
Since you are interested in dumping all Rails and Heroku logs to an external service, I can suggest you try the Progstr Logger free add-on. (Disclaimer, I work for Progstr). The add-on has a Ruby gem that will collect all Rails logs (everything that usually ends up in log/*). It will also set up a log drain that will fetch all system-level Heroku logs. In addition you get a cool web UI that lets you easily search for logs and some other nice features.

Rails logging to Apache logs rather than application log

I am running a Rails application on Apache using mod_passenger. I would like Rails.logger calls to write to the Apache error log rather than to the application's log file in log/production.log.
How can I do this?
In your config/environments/production.rb file you can add something like:
config.logger = Logger.new("/var/log/apache2/error.log")
Of course your app will need to have permissions to such a file. In addition intermixing Apache errors with your apps logs is definitely not a good idea.
This doesn't answer your question directly but I've just run a little test and STDERR.puts "meep" ended up in Apache's error log while using mod_passenger.
Perhaps then you could point config.logger at STDERR?

Log your SQL in Rails application inside unit test

I want to install a logger so that I can dump all executed SQL of my rails application. Problem is, such logger is associated with AbstractAdapter which initialized very soon under test mode, and thus cannot be set by my initializer code.
I try to put
ActiveRecord::Base.logger = MyCustomLogger.new(STDOUT)
in the end of environment.rb like someone advised but it only works when being run in console environment (kicked by script/console), not when run under test mode.
I wonder if there is any way to config such logger so that I will sure to be invoked under any environment (test, development, production, console)
Creating the logger in config/environment.rb should work. I get SQL logging on standard output when I run unit tests if I put the following line in either config/environment.rb or config/environments/test.rb:
ActiveRecord::Base.logger = Logger.new(STDOUT)
Does your MyCustomLogger class do anything special that causes it to fail during tests? Does it work better if you use Logger.new(STDOUT) instead?
In test/test_helper.rb, before loading config/environment.rb, add:
RAILS_DEFAULT_LOGGER = MyCustomLogger.new(STDOUT)
Relevant code in railties for 2.3 railties/lib/initializer.rb#L35. Not sure how to do it with Rails 3.0 yet. It looks like you need to call Rails#logger=, but I can't find a good spot for it yet.
The best way as far as I can found is to put such code in initializers folder. This way, regardless of the running environment, the logger is always properly installed. And no, on my mac osx Rails 2.3.2 on ruby 1.8.7, if I put ActiveRecord::Base.logger=... inside environment.rb then the logger is not properly installed, since the logger that the Sql Connection used to dump SQL was installed and cached before that.

Resources