I have some helper methods on my ActiveSupport::BufferedLogger such as displaying KeyValue pairs, it all works fine from rails s but fails in rails c
In rails s, I can see that my Logger extends BufferedLogger and that is the class I have chosen to MonkeyPatch, I have also tested this out with ActiveSupport::Logger as well.
I had thought that rails c ran through the same initializers that rails s used, am I wrong in thinking that?
Do I need to run some sort of initializer when starting rails c?
Location of my file is:
config/initializers/active_support_logger.rb
Error is here:
Sample Snippet listed here
class ActiveSupport::BufferedLogger
def kv(key, value)
info('%-50s %s' % ["#{key}: ".brown, value])
end
def line
info(##l.brown)
end
def block(message)
line
info(message)
line
end
end
I recommend subclassing ActiveSupport::Logger (or ActiveSupport::BufferedLogger if you really want though it's deprecated in Rails 4) instead of monkey-patching. Rails provides a configuration option to override the logger instance used by the app. This works in any context that loads the Rails environment, including the server and console.
There are a number of ways you can do this; a quick and dirty way to get you started is to just define the class and set the logger instance in an initializer that will get loaded during the initialization process of the Rails environment:
# config/initializers/my_logger.rb
class MyLogger < ::ActiveSupport::Logger
# additional methods and overrides
end
Rails.logger = MyLogger.new(Rails.root.join("log", "#{Rails.env}.log"))
For more info, check out the Rails guide to debugging applications: http://guides.rubyonrails.org/debugging_rails_applications.html#the-logger
Related
I'm currently working on the GCP and deployed my rails app on the GCP instance.
I'm currently using https://github.com/brendeschuijmert/google-cloud-ruby/tree/master/google-cloud-logging for the compute engine.
When I use this on the rails application.
Rails.logger.info "Hello World" works well.
But logger.warn "Hola Mundo" is not working.
I want someone shade some light on this problem.
Thanks
If you're trying to call logger from outside of a controller/model or some other file that is a part of Rails' structure - you will have to explicitly create a logger for yourself with:
logger = Logger.new(STDOUT) # Or wherever you want to log to
However if Rails.logger is working, then you likely just need an alias like logger = Rails.logger to allow you to use logger.warn without the Rails namespace prefix. You're probably in a file that doesn't already have a helper that is aliasing that for you.
Some more digging in the API reveals that the logger stems from ActiveSupport::LogSubscriber - several classes like ActionController include child LogSubscribers that inherit from that module and hence have the logger method available to them. You can manually alias it to Rails.logger to have it work for you wherever you are trying to invoke it.
Source: https://api.rubyonrails.org/classes/ActiveSupport/LogSubscriber.html#method-c-logger
I'm trying to monkey-patch the class "Tumble" with the module "Tinder". But when I add methods to the class, they aren't inherited. Constants, however, are.
lib/tumble.rb:
class Tumble
...
lib/tumble/tinder.rb
module Tinder
APP_ID = 1234567890
# Without self
def xyz
puts 'bar'
end
config/initializers/tumble.rb
Tumble.include Tinder
The app loads Tumble and Tinder and I can access APP_ID:
$ rails r 'puts Tumble::APP_ID'
1234567890
But Tumble didn't inherit the methods:
[~/tinder]$ rails r 'puts Tumble.foo'
Please specify a valid ruby command or the path of a script to run.
Run 'bin/rails runner -h' for help.
undefined method `foo' for Tumble:Class
[~/tinder]$ rails r 'puts Tumble.xyz'
Please specify a valid ruby command or the path of a script to run.
Run 'bin/rails runner -h' for help.
undefined method `xyz' for Tumble:Class
How do I patch Tumble to include these methods from Tinder?
Thanks :)
When you call Tumble.foo that's calling foo as if it were a class method.
Yet when you do Tumble.include Tinder that adds the module's instance methods as instance methods of Tumble.
So, your current code should work if you do Tumble.new.foo.
You can also make Tumble.foo work with Tumble.extend Tinder.
class Tinder
def initialize
# some code here
end
end
Imagine that this above was the class that you wanted to monkey-patch. To monkey-patch it you only need to write (on any place that gets loaded) the class Tinder again with the code to be added like this:
class Tinder
def some_more_code
# does great stuff
end
end
This is monkey-patch. Modules won't do monkey-patch. They extend functionality but in a different way.
Just be aware not to override any methods of the original class that you want to monkey-patch, unless, of course, if that is your goal.
Sorry if this a very basic question, but after I checked a lot entries here (and tried to implement solutions) I still do not have an answer...
The goal is to have a ruby class which could be used withot editions (or with as little editions as possible) in both ruby scripts and as ruby on rails model. I want to have the following
logger.info 'some tracing'
However when I put such statement in ruby class I'm getting error messages - unknow method logger in both ruby and ruby on rails. Well. when I modify it such way
Rails.logger.info 'some tracing'
It starts to work in rils, but of course does not work in ruby without rails. What I'm doing wrong?
I read this http://guides.rubyonrails.org/debugging_rails_applications.html#the-logger but I still confused, since examples from the section 'send messages' do not work.
So_ sorry again, but I see no other possibility as to connect to "the hive mind" ans ask for help ;-)
Rails uses the ruby logger by default.
Take a look at the API doc here : Logger (Ruby 2.0)
Here is an example:
require 'logger'
logger = Logger.new(STDOUT)
logger.level = Logger::WARN
logger.debug("Created logger")
logger.info("Program started")
logger.warn("Nothing to do!")
EDIT
Usage:
require 'logger'
class MyClass
def initialize
#logger = logger = Logger.new(STDOUT)
#logger.level = Logger::WARN
end
def say_something
#logger.info("You can't see me I'm not important enough")
#logger.warn("I'm visible")
end
end
I have some Ruby code that I am testing stand alone before integrating into a Rails app. Because the final app. is in Rails I have numerous calls to Rails.logging.xxx that I want in there, but with these I can't run the stand alone app because it doesn't know about Rails.logging. How can I set it up so I can have these logging calls both in my CLI test app. and work in the final Rails deployment?
TY,
Fred
Why not just create a simple stub logger that is only available in the CLI version? For example:
class Rails
def self.logger
#logger ||= Logger.new('cli_logger.log')
end
end
Rails.logger.info("Spam")
Or perhaps more Rails-like:
class Rails
cattr_accessor :logger
end
Rails.logger = Logger.new('cli_logger.log')
Rails.logger.info("It works")
why you cant use the logger in your app?
just use it like an normal debugger?
see http://ruby.about.com/od/tasks/a/logger.htm
I have to change my rail application's default log path because of my company's internal software deployment process: basically my rails app ends up on a read-only location, and I need the log files written in a directory "made for this".
With Rails 2.x we used to add some black magic in our FCGI script to force that in when deployed on prod. hosts:
class Rails::Configuration
def default_log_path
File.join(ENV['SOME_ENVIRONMENT_VAR'], "var/output/logs/rails.log")
end
end
However, Configuration isn't a class anymore in Rails 2.3 (it's a module), and it appears to me there isn't any default_log_path involved there anymore as well...
You just need define your logger
config.logger = ActiveSupport::BufferedLogger.new(File.join(ENV['SOME_ENVIRONMENT_VAR'], "var/output/logs/rails.log"))
This trick works with Rails 2 too. And you can define by environment where you really want your log file.
The config.log_path setting has been deprecated - the recommended solution is now:
config.paths.log = "/some/path/#{Rails.env}.log"
As of Rails 3.2.3, looks like the log pathname is also defined in Rails::Rack::LogTailer#initialize, and that comes from Rails::Server#log_path.
LOG_PATH = "log/mylog.log"
require 'rails/commands/server'
module Rails
class Server
def log_path
LOG_PATH
end
end
end
class Application < Rails::Application
...
config.paths['log'] = LOG_PATH
...
end