Use of Logger with Ruby and RSpec - ruby

I have created logger object in "spec/logger.rb" and returned it.
I have created logger object in "spec/test1.rb" in describe method and can use it. it is working in same directory. If i need to use logger by creating logger object or by including file in different directory with and without class, then is there any way to do it ?
spec/logger.rb
class Logging
def initialize_logger()
log = Logger.new("test.log")
return log
end
end
spec/test1.rb
require 'java'
require 'rspec'
require 'logger'
require "logger.rb"
class SingleTest
describe 'Verify Single Test' do
# create logger object
logger_object = Logging.new
logger = logger_object.initialize_logger()
logger.info 'Checking Logger'
it 'Verify Single Test for logger is present' do
logger.info 'Creating logger'
end
end
end
lib/test_lib1.rb
require 'httparty'
require '../utility/logger.rb'
#logger_object = Logging.new
#logger = #logger_object.initialize_logger()
#logger.info 'Checking Logger'
def first()
#logger.info "first logger in lib"
end
def perform_url_request()
#logger.info "URL"
#logger.info "Request Method"
end
lib/test_lib2.rb
require '../utility/logger.rb'
class TestFile
def initialize()
#logger_object = Logging.new
#logger = #logger_object.initialize_logger()
#logger.info "I am intialize"
end
def test_method()
#logger.info "******"
end
end

Related

Ruby Class logger does not work

I am use logger class but I am getting error.
Code :-
class Try
def method_missing(method_name, *args)
logger.warn "I am try to call #{method_name} with these arguments #{args}"
super
end
end
Try.new.dummy(1, "my name is rosy.")
Getting error:-
stack level too deep (SystemStackError)
Please tell us. How to solve this problem.
I'm assuming you are not in a rails app. Have you instantiated the logger instance?
require 'logger'
logger = Logger.new(STDOUT)
logger.level = Logger::WARN
logger.warn "test"

How can ruby logger set the progname automatically based on the method

I have set up my logger using a module with the following (simplified) version:
module Logging
class << self
def logger
end
def logger=(logger)
#logger = logger
end
end
end
I would like to do something like the following (it didn't work):
Get the name of the currently executing method
def test_method
return __callee__
end
This way without the above, add logger.progname = self.test_method
So it should look like this:
module Logging
class << self
def logger
return #logger if #logger
#logger.progname = self.test_method
end
def logger=(logger)
#logger = logger
end
end
end
The end goal should be such that, with method "MyMethod":
def my_method
logger.debug "hi"
end
I get => "my_method: "hi"

logger in ruby unit test startup or setup

I am writing some tests in ruby and have this question.
class MyTest < Test::Unit::TestCase
LogFile = "test.log"
Log= Logger.new(LogFile)
def startup
#log = Log
end
def shutdown
end
def setup
end
....
end
I am trying to create a logger in startup, however, it does not work well. In the test cases, #log is nil.
I know I can put it in setup, however, I don't want to reassign it for every test case. Why it does not work? What is the correct way to do it?
startup should be used as a class method. There you could define a class variable like ##log.
If you want to use an instance variable #log you must fill it in setup.
Example:
require 'test/unit'
require 'logger'
class MyTest < Test::Unit::TestCase
LogFile = "test.log"
Log= Logger.new(LogFile)
def self.startup
##log = Log
end
def setup
#log = Log
end
def test_class_var
assert_kind_of(Logger,##log)
end
def test_instance_var
assert_kind_of(Logger,#log)
end
end

Using a singleton class in a custom logger

I currently have a logging setup that looks like this:
require 'active_support'
require 'singleton'
class Worker
def initialize(logger)
#logger = logger
end
def perform
#logger.with_context(["tag1"], "Started work")
Provider.say_hello
end
end
class Vlogger
include Singleton
attr_accessor :logger
def logger
#logger ||= ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
end
def with_context(tags, msg)
#logger.tagged(*tags) { #logger.info msg }
end
end
class Provider
def self.logger
Vlogger.instance
end
def self.say_hello
logger.with_context(["tag2"], "hello")
end
end
v = Vlogger.instance
v.logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
Worker.new(v).perform
My objective with this is to avoid having to pass around the #logger instance variable found in my Worker class. Ideally, I want the Vlogger class to be available to all classes. I'm finding that I'm having to use this pattern quite a bit in my code:
def self.logger
Vlogger.instance
end
Is there a better way to do this? Is my OO design pattern here inherently flawed? Ideally I'm trying to avoid passing around objects when really the object has no state and it should be available to various classes without introducing class or instance methods. Thoughts?

How to include a module that extends classmethods and correctly reference class var

My expectations are in the comments.
require 'logger'
module Logging
attr_accessor :logger
def logger
return #logger if #logger # allow items to have own loggers
##logger ||= Logger.new(STDERR)
puts "Instance Class REF ID#{##logger.__id__}"
puts "Class ID #{self.class.logger.__id__}"
##logger
end
module ClassMethods
def logger= logger
#logger = logger
end
def logger
#logger ||= Logger.new(STDERR)
puts "Class Instance REF ID #{#logger.__id__}"
#logger
end
end
def self.included(base)
base.extend(ClassMethods)
end
end
class Test
include Logging
def wow
logger.info 'wow'
end
end
t = Test.new
# should be the same
puts "Loggers are #{t.logger.__id__ == Test.logger.__id__ ? '' : 'not '}the same"
Test.logger = Logger.new('/dev/null')
# should still be the same
puts "Loggers are #{t.logger.__id__ == Test.logger.__id__ ? '' : 'not '}the same"
lg = Test.logger.__id__
t.logger = Logger.new(STDERR)
# class logger should be same
puts "Class Logger is #{Test.logger.__id__ == lg ? 'still the' : 'not'} same"
# class and instance logger should be different
puts "Loggers are #{t.logger.__id__ == Test.logger.__id__ ? '' : 'not '}the same"
When executed:
➜ sandbox irb
1.9.3-p392 :001 > load 'test_l.rb'
Instance Class REF ID70203753590760
Class Instance REF ID 70203753590500
Class ID 70203753590500
Class Instance REF ID 70203753590500
Loggers are not the same # I expected to be same... :(
Instance Class REF ID70203753590760
Class Instance REF ID 70203753590000
Class ID 70203753590000
Class Instance REF ID 70203753590000
Loggers are not the same # I expected to be same... :(
Class Instance REF ID 70203753590000
Class Instance REF ID 70203753590000
Class Logger is still the same
Class Instance REF ID 70203753590000
Loggers are not the same
I've deliberately forgotten how to use ## variables because they are so confusing and rarely needed.
Instead, consider only using instance variables, but delegate up to the class level if needed:
module Logging
attr_writer :logger
def logger
defined?(#logger) ? #logger : self.class.logger
end
module ClassMethods
def logger=(logger)
#logger = logger
end
def logger
#logger ||= Logger.new(STDERR)
end
end
def self.included(base)
base.extend(ClassMethods)
end
end
class Test
include Logging
# ...
end

Resources