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 require
ing 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 require
d a gem that in turn require
d 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
How to Open Files Relative to Home Directory
Ubuntu 12 - How to Install Ruby and Rails Correctly
What Is an Elegant Way in Ruby to Tell If a Variable Is a Hash or an Array
How to Write Specs for Code That Depends on Environment Variables
Collect Values from an Array of Hashes
How to Remove/Disable Sign Up from Devise
Rails 4.2 - Sidekiq Not Sending Emails in Development
Can Not Install JSON Gem with Ruby 2.2.3 on Ubuntu
"Ago" Date/Time Functions in Ruby/Rails
Rails, Ruby, How to Sort an Array
Ruby: How to Count the Number of Times a String Appears in Another String
How to Run a Ruby Script Within Bundler Context
What's the Variable Scope Within 'Class_Eval' String
Simple_Form: Remove Outer Label for an Inline Checkbox with Label