How to Format Ruby Logger

How to format ruby logger?

logger = Logger.new('nice.log')

logger.formatter = proc do |severity, datetime, progname, msg|
"NICE: #{msg}\n"
end

logger.info("I like cheese.")

# nice.log:
NICE: I like cheese.

How to format ruby logger to this?

try this:

 "#{severity} [#{datetime.strftime('%Y-%m-%d %H:%M:%S.%L')}]: #{msg}\n"

ruby Logger formatter change message only

Based on the example in documentation, one can do the following:

require 'logger'
logger = Logger.new(STDOUT)

original_formatter = Logger::Formatter.new
logger.formatter = proc { |severity, datetime, progname, msg|
original_formatter.call(severity, datetime, progname, "[mymessage] #{msg}\n")
}

logger.debug("I am a debug msg")
logger.info("I am an info msg")

Output of program:

D, [2016-01-13T12:45:47.354261 #11512] DEBUG -- : [mymessage] I am a debug msg

I, [2016-01-13T12:45:47.354261 #11512] INFO -- : [mymessage] I am an info msg

Rails logger format string configuration

Did some digging and found this post in the RubyOnRails Talk google group.

So I modified it a little bit and put it at the end of my environment.rb:

module ActiveSupport
class BufferedLogger
def add(severity, message = nil, progname = nil, &block)
return if @level > severity
message = (message || (block && block.call) || progname).to_s

level = {
0 => "DEBUG",
1 => "INFO",
2 => "WARN",
3 => "ERROR",
4 => "FATAL"
}[severity] || "U"

message = "[%s: %s #%d] %s" % [level,
Time.now.strftime("%m%d %H:%M:%S"),
$$,
message]

message = "#{message}\n" unless message[-1] == ?\n
buffer << message
auto_flush
message
end
end
end

This results in a format string like this:

[DEBUG: 0121 10:35:26 #57078] Rendered layouts/_header (0.00089)

Ruby logger loses formatting

Are you requireing different gems in the different environments, or could it be IRB itself that sets the log format? What happens if you add require 'irb' to your application, does that also change the formatting?

The formatting is stored in a global variable, any gem can override it. I've been bitten by a similar issue when I required a gem that in turn required ActiveRecord, which set the log format.

It just shows how bad it is to use global variables for configuration, something that is way too common in Ruby gems.

How can I have ruby logger log output to stdout as well as file?

You can write a pseudo IO class that will write to multiple IO objects. Something like:

class MultiIO
def initialize(*targets)
@targets = targets
end

def write(*args)
@targets.each {|t| t.write(*args)}
end

def close
@targets.each(&:close)
end
end

Then set that as your log file:

log_file = File.open("log/debug.log", "a")
Logger.new MultiIO.new(STDOUT, log_file)

Every time Logger calls puts on your MultiIO object, it will write to both STDOUT and your log file.

Edit: I went ahead and figured out the rest of the interface. A log device must respond to write and close (not puts). As long as MultiIO responds to those and proxies them to the real IO objects, this should work.

Custom logger formatter in HTTParty

Cool idea.

You need to implement initialize(logger, level) and format(request, response) as per the sample curl and apache samples. Then you can add it to the formatters.

There's some properties you can use as well, but they don't seem to be mandatory.

attr_accessor :level, :logger, :current_time

I had a little play with the httparty example to see if it works, seems to work fine. Here's my sample and output.

party.rb

require 'httparty'
require 'logger'
require './custom_formatter.rb'

HTTParty::Logger.add_formatter('custom', HTTParty::Logger::CustomFormatter)

# Or wrap things up in your own class
class StackExchange
include HTTParty
logger ::Logger.new("a logger"), :debug, :custom
base_uri 'api.stackexchange.com'

def initialize(service, page)
@options = { query: {site: service, page: page} }
end

def questions
self.class.get("/2.2/questions", @options)
end

def users
self.class.get("/2.2/users", @options)
end
end

stack_exchange = StackExchange.new("stackoverflow", 1)
puts stack_exchange.questions
puts stack_exchange.users

custom_formatter.rb

module HTTParty
module Logger
class CustomFormatter

attr_accessor :level

def initialize(logger, level)
@logger = logger
@level = level.to_sym
end

def format(request, response)
@logger.send @level, "hahahahaha "
end
end
end
end

output:

--> D, [2016-06-02T22:30:26.613721 #5844] DEBUG -- : hahahahaha 
--> D, [2016-06-02T22:30:27.440348 #5844] DEBUG -- : hahahahaha


Related Topics



Leave a reply



Submit