Rails turn off console logging when rendering templates [duplicate] - ruby-on-rails

In rails 3.2.0,is it possible to turn off rails logging for rendering of views in
ActionView:: LogSubscriber in production environment.
Currently only way i found to supress is to monkey patch it and increase the log level to debug in the below way. Is there a better way to do this or any configuration?
module ActionView
class LogSubscriber
def render_template(event)
message = "Rendered #{from_rails_root(event.payload[:identifier])}"
message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
message << (" (%.1fms)" % event.duration)
debug(message)
end
alias :render_partial :render_template
alias :render_collection :render_template
end
end

ActionView uses ActiveSupport::Notifications and ActiveSupport::LogSubscriber to instrument its events, and to silence it from the logs is as simple as including the following in your environment file:
%w{render_template render_partial render_collection}.each do |event|
ActiveSupport::Notifications.unsubscribe "#{event}.action_view"
end
Cheers!

You can directly turn off action_view logger.
Rails.application.configure do
config.action_view.logger = nil
end

Related

Sidekiq logs show JobWrapper instead of Job class name

I have a Rails application that runs some background jobs via ActiveJob and Sidekiq. The sidekiq logs in both the terminal and the log file show the following:
2016-10-18T06:17:01.911Z 3252 TID-oukzs4q3k ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper JID-97318b38b1391672d21feb93 INFO: start
Is there some way to show the class names of the jobs here similar to how logs work for a regular Sidekiq Worker?
Update:
Here is how a Sidekiq worker logs:
2016-10-18T11:05:39.690Z 13678 TID-or4o9w2o4 ClientJob JID-b3c71c9c63fe0c6d29fd2f21 INFO: start
Update 2:
My sidekiq version is 3.4.2
I'd like to replace ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper with Client Job
So I managed to do this by removing Sidekiq::Middleware::Server::Logging from the middleware configuration and adding a modified class that displays the arguments in the logs. The arguments themself contain the job and action names as well.
For latest version, currently 4.2.3, in sidekiq.rb
require 'sidekiq'
require 'sidekiq/middleware/server/logging'
class ParamsLogging < Sidekiq::Middleware::Server::Logging
def log_context(worker, item)
klass = item['wrapped'.freeze] || worker.class.to_s
"#{klass} (#{item['args'].try(:join, ' ')}) JID-#{item['jid'.freeze]}"
end
end
Sidekiq.configure_server do |config|
config.server_middleware do |chain|
chain.remove Sidekiq::Middleware::Server::Logging
chain.add ParamsLogging
end
end
For version 3.4.2, or similar, override the call method instead:
class ParamsLogging < Sidekiq::Middleware::Server::Logging
def call(worker, item, queue)
klass = item['wrapped'.freeze] || worker.class.to_s
Sidekiq::Logging.with_context("#{klass} (#{item['args'].try(:join, ' ')}) JID-#{item['jid'.freeze]}") do
begin
start = Time.now
logger.info { "start" }
yield
logger.info { "done: #{elapsed(start)} sec" }
rescue Exception
logger.info { "fail: #{elapsed(start)} sec" }
raise
end
end
end
end
You must be running some ancient version. Upgrade.
Sorry, looks like that's a Rails 5+ feature only. You'll need to upgrade Rails. https://github.com/rails/rails/commit/8d2b1406bc201d8705e931b6f043441930f2e8ac

Log inside Sidekiq worker

I'm trying to log the progress of my sideqik worker using tail -f log/development.log in development and heroku logs in production.
However, everything inside the worker and everything called by the worker does not get logged. In the code below, only TEST 1 gets logged.
How can I log everything inside the worker and the classes the worker calls?
# app/controllers/TasksController.rb
def import_data
Rails.logger.info "TEST 1" # shows up in development.log
DataImportWorker.perform_async
render "done"
end
# app/workers/DataImportWorker.rb
class DataImportWorker
include Sidekiq::Worker
def perform
Rails.logger.info "TEST 2" # does not show up in development.log
importer = Importer.new
importer.import_data
end
end
# app/controllers/services/Importer.rb
class Importer
def import_data
Rails.logger.info "TEST 3" # does not show up in development.log
end
end
Update
I still don't understand why Rails.logger.info or Sidekiq.logger.info don't log into the log stream. Got it working by replacing Rails.logger.info with puts.
There is a Sidekiq.logger and simply logger reference that you can use within your workers. The default should be to STDOUT and you should just direct your output in production to the log file path of your choice.
It works in rails 6:
# config/initializers/sidekiq.rb
Rails.logger = Sidekiq.logger
ActiveRecord::Base.logger = Sidekiq.logger
#migu, have you tried the below command in the config/initializer.rb ?
Rails.logger = Sidekiq::Logging.logger
I've found this solution here, it seems to work well.
Sidekiq uses the Ruby Logger class with default Log Level as INFO, and its settings are independent from Rails.
You may set the Sidekiq Log Level for the Logger used by Sidekiq in config/initializers/sidekiq.rb:
Sidekiq.configure_server do |config|
config.logger.level = Rails.logger.level
end

Prevent Rails from logging email attachments

When I send an email with an attachment the data is logged in hex and fills up my whole log. Is there a way to disable logging of attachments?
I know I can disable mailer logging with config.action_mailer.logger = nil.
Unfortunately, the attachments are included in the logs if the logging level is set to :debug, the default level for non-production environments. This means that in production you should be fine, but your dev and staging environments could bloat during testing. You could turn down logging for your entire app (config.log_level = :info), but this is obviously less than ideal.
You can configure a custom logger:
config.action_mailer.logger = ActiveSupport::BufferedLogger.new("mailer.log")
config.action_mailer.logger.level = ActiveSupport::BufferedLogger::Severity::INFO
Rails 4
config.action_mailer.logger = ActiveSupport::Logger.new("mailer.log")
config.action_mailer.logger.level = ActiveSupport::Logger::Severity::INFO
This will split the log, but you can isolate the logging level change to the action mailer.
If you still want your log level to be debug, you can remove the attachments from the log output by overriding ActionMailer's LogSubscriber class. Look at the class in your actionmailer gem, and adjust accordingly. For my Rails 4.2.10 install, the relevant file is:
gems/actionmailer-4.2.10/lib/action_mailer/log_subscriber.rb
My module is:
module ActionMailer
class LogSubscriber < ActiveSupport::LogSubscriber
def deliver(event)
info do
recipients = Array(event.payload[:to]).join(', ')
"\nSent mail to #{recipients}, Subject: #{event.payload[:subject]}, on #{event.payload[:date]} (#{event.duration.round(1)}ms)"
end
debug { remove_attachments(event.payload[:mail]) }
end
def remove_attachments(message)
new_message = ''
skip = false
message.each_line do |line|
new_message << line unless skip
skip = true if line =~ /Content-Disposition: attachment;/
skip = false if skip && line =~ /----==_mimepart/
end
new_message
end
end
end
Save this to an .rb file anywhere under your app/ folder and it will be included.
in Application.rb you could try filtering the attachment parameter. I believe this should solve the issue, but I have not tested it myself
config.filter_parameters += [:attachment]

Rails: How to raise I18n translation is missing exceptions in the testing environment

I want Rails to raise an exception when an I18n translation is missing in the testing environment (instead of rendering text 'translation missing'). Is there a simple way to achieve this?
As of Rails 4.1.0, there's now a better solution than the 4 year-old answers to this question: add the following line to your config file:
config.action_view.raise_on_missing_translations = true
I like to set this in the test environment only, but you might also want to set it in development. I would strongly advise against setting it to true in production.
To raise exceptions, you can define a class to handle localization errors.
class TestExceptionLocalizationHandler
def call(exception, locale, key, options)
raise exception.to_exception
end
end
Then you attach it to the desired test cases with
I18n.exception_handler = TestExceptionLocalizationHandler.new
This way you get exceptions raised. I don't know how to raise failures (with flunk) to get better results.
Or you can just add those lines to your config/test.rb
config.action_view.raise_on_missing_translations = true
config.i18n.exception_handler = Proc.new { |exception| raise exception.to_exception }
Rails 4.1+
To raise i18n translation missing exceptions you need two things:
1) An initializer config/initializers/i18n_force_exceptions.rb:
module I18n
class ForceMissingTranslationsHandler < ExceptionHandler
def call(exception, locale, key, options)
if Rails.env.test?
raise exception.to_exception
else
super
end
end
end
end
I18n.exception_handler = I18n::ForceMissingTranslationsHandler.new
2) A config setting in config/environments/test.rb (and other environments as needed):
config.action_view.raise_on_missing_translations = true
Note: The config setting is needed in addition to the exception handler because rails wraps calls to I18n.translate in it's view and helpers preventing exceptions from triggering.
I've created this initializer to raise an exception - args are passed so you will know which i18n key is missing!
# only for test
if Rails.env.test?
# raises exception when there is a wrong/no i18n key
module I18n
class JustRaiseExceptionHandler < ExceptionHandler
def call(exception, locale, key, options)
if exception.is_a?(MissingTranslation)
raise exception.to_exception
else
super
end
end
end
end
I18n.exception_handler = I18n::JustRaiseExceptionHandler.new
end
Source
If you're using rails between 4.0.0 to 4.1.0 you should monkey patch this way:
module ActionView::Helpers::TranslationHelper
def t_with_raise(*args)
value = t_without_raise(*args)
if value.to_s.match(/title="translation missing: (.+)"/)
raise "Translation missing: #{$1}"
else
value
end
end
alias_method :translate_with_raise, :t_with_raise
alias_method_chain :t, :raise
alias_method_chain :translate, :raise
end

How to show all asked-for Translation Strings in Rails?

When Rails functions are asking for a translation (I18n.translate), I don't want to analyze their code in order to get the exact scopes etc.
How can I add a debug output into the console for every string that was asked for?
Examples:
I18n.t 'errors.messages.invalid', :scope => :active_record
# Translation for 'activerecord.errors.messages.invalid' (not) found
label(:post, :title)
# Translation for 'activerecord.attributes.post.title' not found
# Translation for 'views.labels.post.title' not found
This is not a very elegant solution, but it's worked for me. I've created an initialiser:
require 'i18n'
if (Rails.env.development? || Rails.env.test?) && ENV['DEBUG_TRANSLATION']
module I18n
class << self
def translate_with_debug(*args)
Rails.logger.debug "Translate : #{args.inspect}"
translate_without_debug(*args)
end
alias_method_chain :translate, :debug
end
end
end
You can then run commands like the following:
$ DEBUG_TRANSLATION=true rake cucumber
...and you'll see all the translations being attempted dumped to STDOUT. I don't consider this production code though, so I've kept it in a Gist, and not checked it into my main project source control at this stage.
Noddy, but it does the job.
Just a small change to put I18n debug messages in the log:
substitute this line:
puts "Translate: #{args.inspect}"
with
Rails.logger.debug "Translate : #{args.inspect}"

Resources