I'm writing Logger and got problem with automatic adding class name, from which I called print_log method. For example something like this:
class Logger
def self.print_log(string)
puts Time.now.strftime('%T | ') + *caller_class_name_here* + ' - ' + string
end
end
class MyClass
def initialize
Logger.print_log 'called .new() method'
end
end
As result of calling MyClass.new
method I wanna see in output:
14:41:23 | MyClass - called .new() method
I'm sure it's possible to do using caller
, but yet can't find how
You can use StackFrame of System. Diagnostics and MethodBase of System. Reflection . StackFrame(Int32, Boolean) initializes a new instance of the StackFrame class that corresponds to a frame above the current stack frame, optionally capturing source information.
Write the callAll() method to actually call each method explicitly without reflection. This allows for flexibility in subclassing. It also allows you to deal with methods which have parameters. It also allows you to bypass methods which don't apply.
If you want to get super class name you can use getSuperClass(). If an answer to another question can be used here, please do not answer the question and flag it as a duplicate (if you have enough privileges).
You can use module like that (Rails style):
module Loggable
extend ActiveSupport::Concern
def log_prefix
@log_prefix ||= (self.class == Class ? "#{self.to_s}" : "#{self.class.to_s}").freeze
end
included do
[:debug, :info, :warn, :error, :fatal].each do |level|
define_method level do |str = nil|
caller = caller_locations(1,1)[0].label
prefix = "[#{log_prefix}##{caller}] "
prefix << level.to_s.upcase[0]
str = "#{prefix}: #{str}"
puts str if ENV["DEBUG"]
Rails.logger.send(level, str)
end
end
end
end
and you code will be:
class MyClass
include Loggable
extend Loggable
def instance_method
debug "Hello"
end
def self.klass_method
debug "Klass"
end
end
I am not sure if it is possible to get the class name like you want. I would create a logger instance for this to which you can pass in the class name when creating it.
class Logger
def initialize(class_name)
@class_name = class_name
end
def print_log(message)
puts Time.now.strftime('%T | ') + @class_name + ' - ' + message
end
end
class MyClass
def initalize
@logger = Logger.new self.class.name
@logger.print_log 'called .new() method'
end
end
More verbose than you would like maybe but explicit code that is easy to understand.
For any serious work I recommend using the standard library logger. You may have to wrap it in your own call to get the log messages as you want it but you'll get log rotating and file handling as it should be.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With