Reputation: 19150
I use the gem “Lograge” 0.3.6, and Rails 4.2. I have this configured in my config/environments/development.rb file
config.lograge.enabled = true
config.lograge.formatter = CustomLogstash.new
However, I notice the output in my log/development.log file doesn’t contain date/times in front of each line. How do I configure lograge (or maybe just my Rails logger?) to prefix each line in that file with a date and time?
Upvotes: 0
Views: 1659
Reputation: 1424
As per the document, the lograge gem provides below log formatters.
Lograge::Formatters::Lines.new # need to install "lines" gem
Lograge::Formatters::Cee.new
Lograge::Formatters::Graylog2.new
Lograge::Formatters::KeyValue.new # default lograge format
Lograge::Formatters::Json.new
Lograge::Formatters::Logstash.new # need to install "logstash-event" gem
Lograge::Formatters::LTSV.new
Lograge::Formatters::Raw.new # Returns a ruby hash object
By default the lograge gem uses Lograge::Formatters::KeyValue.new
format for log.
You can customize this and make it universal by using your CustomLogStash
class with some changes.
class CustomLogStash < Lograge::Formatters::KeyValue
def call(data)
# I'm using timestamp key here, you can choose whatever you want.
data_hash = { timestamp: Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.%3N")}.merge!(data)
super(data_hash)
end
end
Same way you can use any Lograge::Formatters
class and apply the custom format to the log.
Now add below code to your config/initializers/lograge.rb
file.
Rails.application.configure do
config.lograge.enabled = true
config.lograge.formatter = CustomLogStash.new
end
Now restart your server and load a page in your browser. You will see the logs something like below:
timestamp=2021-11-21T17:14:10.726 method=GET path=/categories format=html controller=categories action=index status=200 duration=259.11 view=244.91 db=2.60
EDITED
If you are looking for logs something like
then you don't need any gem for this. You can achieve this by adding below lines to your preferred environment development/production/test
config.log_level = :debug
config.log_formatter = ::Logger::Formatter.new
If you want to apply this across all environments then add above lines to the config/application.rb
file.
Upvotes: 1
Reputation: 1374
As per official documentation for lograge
, you can make use of custom_options
EDIT 1 : custom_options using time: Time.now
or time:event.time
Rails.application.configure do
config.lograge.enabled = true
config.lograge.formatter = Lograge::Formatters::Logstash.new
# add time to lograge
config.lograge.custom_options = lambda do |event|
{ time: Time.now } #or use time:event.time
end
end
Note: When using the logstash output, you need to add the additional gem logstash-event. You can simply add it to your Gemfile like this
gem "logstash-event"
EDIT 2: Update based on comments custom_options using :time => event.time
#config/environments/production.rb
MyApp::Application.configure do
config.lograge.enabled = true
# add time to lograge
config.lograge.custom_options = lambda do |event|
{:time => event.time}
end
end
OR the below custom options which was a fix in lograge issue to ensure both date and time logged using time: event.time.to_s(:db)
config.lograge.custom_options = lambda do |event|
unwanted_keys = %w[format action controller utf8]
params = event.payload[:params].reject { |key,_| unwanted_keys.include? key }
{time: event.time.to_s(:db), user: event.payload[:user], params: params}
end
ALTERNATIVELY you can use this Custom logger
# Define a setter to pass in a custom log formatter
class ActiveSupport::BufferedLogger
def formatter=(formatter)
@log.formatter = formatter
end
end
# Defines a custom log format (time, severity, message, PID, backtrace)... all with color!
class Formatter
SEVERITY_TO_TAG = {'DEBUG'=>'meh', 'INFO'=>'fyi', 'WARN'=>'hmm', 'ERROR'=>'wtf', 'FATAL'=>'omg', 'UNKNOWN'=>'???'}
SEVERITY_TO_COLOR = {'DEBUG'=>'37', 'INFO'=>'32', 'WARN'=>'33', 'ERROR'=>'31', 'FATAL'=>'31', 'UNKNOWN'=>'37'}
HUMOR_FOR_ENV = {development: true, test: true, production: false}
DEPTH_FOR_ENV = {development: 3, test: 3, production: 1}
EXCLUSION_REGEX = /log|active_support|active_record/
def humorous?
return @is_humorous if defined? @is_humorous
@is_humorous = HUMOR_FOR_ENV[ Rails.env.to_sym ]
end
def depth
@depth ||= DEPTH_FOR_ENV[ Rails.env.to_sym ]
end
def call(severity, time, progname, msg)
t = time.strftime("%Y-%m-%d %H:%M:%S.") << time.usec.to_s[0..2].rjust(3)
color = SEVERITY_TO_COLOR[severity]
sev = humorous? ? "%-3s" % SEVERITY_TO_TAG[severity] # pad to at least 3 characters
: "%-5s" % severity # pad to at least 5 characters
# 2013-05-01 19:16:00.785 [omg] oh noes! (pid:30976) (admin/user.rb:45:in `block (4 levels) in <top (required)>') <- `call' <- `content_for' <- `block (2 levels) in row' <- `block in build_tag'
"\033[0;37m#{t}\033[0m [\033[#{color}m#{sev}\033[0m] #{msg.strip} (pid:#{$$}) #{whodunit}\033[0m\n"
end
def whodunit
latest, *others = caller.select{ |a| a !~ EXCLUSION_REGEX }[0, depth]
latest = latest[/(lib|app)\/(.*)/,-1] || latest
string = ""
string << "\033[36m(#{latest})"
string << "\033[35m <- " + others.map{ |s| s[/`.*/] }.join(' <- ') if others.any?
string
end
end
Rails.logger.formatter = Formatter.new
For Rails 4.2 don’t forget to add ActiveSupport::TaggedLogging to be able to call custom logger like a default rails logger
ActiveSupport::TaggedLogging is used to wrap any standard logger instance to add "tags" to a log statement. A "tag" in this case usually describes a subdomain, and is used by the default Rails.logger to allow you to tag log statements with subdomains, request ids, etc. in your multi-user, multi-instance production applications.
include
ActiveSupport::TaggedLogging::Formatter
to the Formatter
class.
Upvotes: 0
Reputation: 978
Can you paste contents of CustomLogstash class? From docs, this class should respond to call method and return Hash.
This works for me:
class CustomLogstash
def call(data)
{ time: Time.now, controller: data[:controller] } # this can be anything as long it is Hash, eg. data.merge(time: Time.now)
end
end
Sample output from above:
{:time=>"2021-11-18T20:31:41.486+01:00", :controller=>"calendar_events"}
Upvotes: 0
Reputation: 274
Can you add the following in config if it helps.
config.lograge.formatter = ->(data) { data.reverse_merge({time: Time.now}) }# data is a ruby hash.
It will give you output like following
{:time=>2021-11-16 12:26:24.65362 +0000, :method=>"GET", :path=>"/", :format=>:html, :controller=>"Controller", :action=>"index", :status=>200, :duration=>393.41, :view=>85.55, :db=>1.38}
Upvotes: 0