使用 Rails 4.2 和 lograge,如何在每个记录的行之前启用日期/时间?
Posted
技术标签:
【中文标题】使用 Rails 4.2 和 lograge,如何在每个记录的行之前启用日期/时间?【英文标题】:With Rails 4.2 and lograge, how do I enable date/times before each logged line? 【发布时间】:2021-12-25 06:25:08 【问题描述】:我使用 gem “Lograge” 0.3.6 和 Rails 4.2。我在我的 config/environments/development.rb 文件中配置了这个
config.lograge.enabled = true
config.lograge.formatter = CustomLogstash.new
但是,我注意到我的 log/development.log 文件中的输出不包含每一行前面的日期/时间。如何配置 lograge(或者只是我的 Rails 记录器?)为该文件中的每一行加上日期和时间的前缀?
【问题讨论】:
【参考方案1】:如果有帮助,您可以在配置中添加以下内容吗?
config.lograge.formatter = ->(data) data.reverse_merge(time: Time.now) # data is a ruby hash.
它会给你如下输出
: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
【讨论】:
试一试,但没有骰子。重新启动服务器后,我的 log/development.log 文件中仍然没有添加日期。 每个环境有不同的 lograge 配置吗? 配置相同,但有三个单独的文件——config/environments/development.rb、config/environments/staging.rb和config/environments/production.rb。 您在配置中使用了哪个自定义记录器格式化程序?就像您在上面的示例中提到的那样 config.lograge.formatter = CustomLogstash.new 如果您可以分享您的开发配置的外观,是否有可能?【参考方案2】:你能粘贴 CustomLogstash 类的内容吗?从文档来看,这个类应该响应 call 方法并返回 Hash。
这对我有用:
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
上面的示例输出:
:time=>"2021-11-18T20:31:41.486+01:00", :controller=>"calendar_events"
【讨论】:
你是说我应该创建这个类吗?我的项目中没有一个名为 this 的类。 我指的是你粘贴的代码,所以我假设你已经有了这个类。如果没有,请创建它并确保在调用config.lograge.formatter = CustomLogstash.new
之前加载它。
明白了。因此,当调用控制器方法并在它们前面加上时间戳时,包括该行似乎确实将行添加到 log/development.log 文件中,例如':time=>"2021-11-21T03:46:53.525+00:00", :controller=>"api/products"'。有什么办法让这个通用吗?将时间戳添加到所有内容(例如记录的 SQL 查询)【参考方案3】:
根据official documentationlograge
,你可以使用custom_options
EDIT 1:custom_options 使用time: Time.now
或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
注意:使用 logstash 输出时,需要添加额外的 gem logstash-event。您可以像这样简单地将它添加到您的 Gemfile 中
gem "logstash-event"
编辑 2: 基于 cmets custom_options 使用 :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 以下自定义选项修复了使用 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
或者你可以使用这个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[#colorm#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
对于 Rails 4.2,不要忘记添加 ActiveSupport::TaggedLogging 以便能够像默认的 Rails 记录器一样调用自定义记录器
ActiveSupport::TaggedLogging 用于包装任何标准记录器实例以将“标签”添加到日志语句中。在这种情况下,“标签”通常描述一个子域,默认 Rails.logger 使用它来允许您在多用户、多实例生产应用程序中使用子域、请求 ID 等标记日志语句。
include
ActiveSupport::TaggedLogging::Formatter
到Formatter
类。
【讨论】:
不幸的是,它们都不会在 log/development.log 文件中生成前缀时间条目。 @Dave 检查custom_options
的新更新代码
当您说“将 ActiveSupport::TaggedLogging::Formatter 包含到 Formatter 类中”时,那是什么?我的项目中没有名为 Formatter 的类,至少没有我创建的类。
创建自定义记录器时理想情况下需要它,我添加了自定义记录器,这似乎在我之前的编辑中被遗漏了
你添加的自定义记录器,ActiveSupport::BufferedLogger 类,应该放在什么目录下?【参考方案4】:
根据document,lograge gem 提供以下日志格式化程序。
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
默认情况下,lograge gem 使用Lograge::Formatters::KeyValue.new
格式的日志。
您可以通过使用 CustomLogStash
类进行一些更改来自定义它并使其通用。
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
您可以使用任何Lograge::Formatters
类并将自定义格式应用于日志。
现在将以下代码添加到您的 config/initializers/lograge.rb
文件中。
Rails.application.configure do
config.lograge.enabled = true
config.lograge.formatter = CustomLogStash.new
end
现在重新启动服务器并在浏览器中加载页面。您将看到类似以下的日志:
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
已编辑
如果您正在寻找类似的日志
那么你不需要任何宝石。您可以通过在首选环境开发/生产/测试中添加以下几行来实现此目的
config.log_level = :debug
config.log_formatter = ::Logger::Formatter.new
如果您想在所有环境中应用此功能,请将以上行添加到 config/application.rb
文件中。
如果有帮助,请告诉我。
【讨论】:
我确认您在上面报告的内容 - 对控制器方法的请求以该时间戳为前缀。这真的很好。我注意到我的 log/development.log 文件中的另一个输出,例如从数据库加载对象不以时间戳为前缀(它们显示为“Product Load (2.3ms) SELECTproducts
.* ...”)。有什么方法可以调整上述以使时间戳前缀通用?
@Dave - 你想要这样的东西吗ibb.co/MyzLbJP以上是关于使用 Rails 4.2 和 lograge,如何在每个记录的行之前启用日期/时间?的主要内容,如果未能解决你的问题,请参考以下文章
Rails 4.2 / Devise - 如果禁用cookie,则向用户显示特定消息
使用 #send_data 从数据库发送图像与 Rails 4.2 冲突