What does Ruby logger with shift_age 'w' do? - ruby

What does a Ruby logger that looks like this do?
logger = Logger.new('foo.log', 'w')
The closest thing I can find on the docs is
logger = Logger.new('foo.log', 'weekly')
Or perhaps write only?
file = File.open('foo.log', File::WRONLY | File::APPEND)
I'd assume it means weekly?

TL;DR - The 'w' itself means nothing when creating a new Logger object. But 'weekly' is a viable argument.
I am not sure where you got your initial example from. However, based on the docs, the second (optional) argument of Logger::new is shift_age:
Number of old log files to keep, or frequency of rotation (daily, weekly or monthly).
Any option other than those above will still create a successful log object. (Tested in 1.9.3)
[1] pry(main)> logger = Logger.new('foo.log', 'nothing')
=> #<Logger:0x00000001023590
#default_formatter=#<Logger::Formatter:0x00000001023540 #datetime_format=nil>,
#formatter=nil,
#level=0,
#logdev=
#<Logger::LogDevice:0x000000010234a0
#dev=#<File:foo.log>,
#filename="foo.log",
#mutex=#<Logger::LogDevice::LogDeviceMutex:0x00000001023450 #mon_count=0, #mon_mutex=#<Mutex:0x00000001023388>, #mon_owner=nil>,
#shift_age="nothing",
#shift_size=1048576>,
#progname=nil>
Knowing this, the 'w' itself does not mean write-only when creating a new logger. Just because a logger may write to a file, the logger and file are still two different objects.
More information on HOW TO create a logger

Related

Causing the Ruby Logger to autoflush

I am using the standard Ruby 2.2 Logger (i.e. not the Logger from Rails), and since I want to use it as rotating logger, I call it with shift_age and shift_time and pass to it a filename, not a open file handle, like this:
Logger.new('my_file.log', 4, 100_000)
I would like to make the output of this logger unbuffered, but I did not find any method in the Logger interface which would allow this.
In the particular way I am using this logger (I am wrapping the Logger with my own class, which does customization), I have one central point in my code where each logging request is going through, so if I could get at the underlying IO object, I could do a sync at this point, but I also don't know how to find this IO object.
Any ideas?
You do not need to set sync. It's already set by Logger upon logfile creation:
def create_logfile(filename)
begin
logdev = open(filename, (File::WRONLY | File::APPEND | File::CREAT | File::EXCL))
logdev.flock(File::LOCK_EX)
logdev.sync = true
add_log_header(logdev)
logdev.flock(File::LOCK_UN)
rescue Errno::EEXIST
# file is created by another process
logdev = open_logfile(filename)
logdev.sync = true
end
logdev
end
Source:
https://github.com/ruby/ruby/blob/trunk/lib/logger.rb

metriks log to file not working

I wrote a basic program to test the ruby metriks gem
require 'metriks'
require 'metriks/reporter/logger'
#registry = Metriks::Registry.new
#logger = Logger.new('/tmp/metrics.log')
#reporter = Metriks::Reporter::Logger.new(:logger => #logger)
#reporter.start
#registry.meter('tasks').mark
print "Hello"
#registry.meter('tasks').mark
#reporter.stop
After i execute the program, there is nothing in the log other than it got created.
$ cat /tmp/metrics.log
# Logfile created on 2015-06-15 14:23:40 -0700 by logger.rb/44203
You should either pass in your own registry while instantiating Metriks::Reporter::Logger or use the deafult registry (Metrics::Resgitry.default) if you are using a logger to log metrics.
Also the default log write interval is 60 seconds, your code completes before that so even if everything is setup okay it won't get recorded. So, since you want to use your own registry, this should work for you (I'm adding a little sleep since I'm gonna use an interval of 1 second) :
require 'metriks'
require 'metriks/reporter/logger'
#registry = Metriks::Registry.new
#logger = Logger.new('/tmp/metrics.log')
#reporter = Metriks::Reporter::Logger.new(:logger => #logger,
:registry => #registry
:interval => 1)
#reporter.start
#registry.meter('tasks').mark
print "Hello"
#registry.meter('tasks').mark
# Just giving it a little time so the metrics will be recorded.
sleep 2
#reporter.stop
But I don't really think short intervals are good.
UPDATE : Also I think #reporter.write will help you write down the logs instantly regardless of the time interval. So you don't have to use sleep (better).

How do I show a general_query log with Sequel gem in terminal

I have a webserver that uses Sinatra and the Sequel gem. I would like to know if it is possible to print every query executed into the console.
I found in the Sequel documentation that I can setup a log file path.
You can also specify optional parameters, such as the connection pool size, or loggers for logging SQL queries:
DB = Sequel.connect("postgres://user:password#host:port/database_name",
:max_connections => 10, :logger => Logger.new('log/db.log'))
However I was unable to find anything about printing the queries into the console rather than a log.
You can, and you can log to multiple loggers too, see example below
db_location_test = "/db/reservation.accdb"
log_file_path = "#{__FILE__}_#{Time.now.strftime("%Y%m%d")}.txt"
log_file = File.open(log_file_path, "a")
$filelog = Logger.new log_file
$console = Logger.new STDOUT
$console.info "connecting to access database" #only logged to console
sConnectionStringAccess = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=#{db_location_test}"
#sql will be logged to both file and console
DBA = Sequel.ado(:conn_string=>sConnectionStringAccess, :loggers=>[$filelog,$console])
class Reservations < Sequel::Model(:TABLE_RESERVATIONS);end
Reservations.all.each do |record|
$console.info Hash[record]
end

Padrino custom log file

I need to create a custom log file within Padrino that contains all of the logging information that is in stdout as well as custom log messages. I have been able to get the custom log file created, but the stdout file (development.log, production.log, etc.) still gets created with logging statements in it. I have tried putting these lines in the boot.rb file, but none of these seem to work:
Padrino::Logger::Config[:development][:stream] = :to_file
Padrino::Logger::Config[:development] = { :log_level => :debug, :stream => :to_file }
Padrino::Logger::Config[:development][:stream] = :null
Padrino::Logger::Config[:development] = { :log_level => :debug, :stream => :null}
I have looked at Padrino's development commands and logger documentation but they didn't help.
In case it helps, this is the code that is generating the custom log file. (Whether I run this code or not, the stdout file keeps getting created):
log_path = File.join(custom_log_path, 'My Service')
FileUtils.mkdir_p log_path
log_file_path = File.join(log_path, "MyService_#{current_date_time_formatted}.log")
logger = File.open(log_file_path, "a+")
if defined?(PADRINO_ENV) && PADRINO_ENV == 'production'
$stdout.reopen(logger)
$stderr.reopen(logger)
end
Any help is greatly appreciated!
You should be able to do this:
Padrino::Logger::Config[:development][:stream] = logger
# or
Padrino::Logger::Config[:production][:stream] = logger
after you have defined logger. If config[:stream] doesn't receive a keyword, Padrino::Logger will use whatever is passed as the output stream.
For more information on the Padrino logger, check out the relevant Padrino Core code, especially self.setup!: https://github.com/padrino/padrino-framework/blob/master/padrino-core/lib/padrino-core/logger.rb.

Log4r and Chainsaw: gathering additional log message details (line number, etc.)?

I'm using Log4r's Log4j XML formatter to talk to Chainsaw as described here in Log4r's manual. However, basically all I'm getting is the message and warning level -- I'm not getting the additional details that seem to be shown there.
Here's the context in which I'm using it, which seems to me very similar to their (note I'm also using their example Chainsaw configuration file unmodified):
#log = Log4r::Logger.new "#{self.class.name}"
log4jformat = Log4r::Log4jXmlFormatter.new
hostname = opts[:chainsaw_hostname] || DEFAULT_CHAINSAW_HOST
port = opts[:chainsaw_port] || DEFAULT_CHAINSAW_PORT
udpout = Log4r::UDPOutputter.new 'udp', :hostname => hostname, :port => port
udpout.formatter = log4jformat
#log.outputters = [udpout]
#log.debug 'this is a message with level debug'
Any suggestions on this? Again I'm seeing the messages appear, they just don't have the additional details attached like the class/method/line where the log event occurred.
You have to explicitly turn tracing on for this to work. I just had to add the line:
#log.trace = true
and it worked immediately.

Resources