我正在将Sinatra与Apache和Passenger一起使用。
我目前在config.ru
中使用以下记录器:
LOGGER = Logger.new("logs/sinatra.log")
我可以使用以下方式在我的应用中记录内容:
LOGGER.error "Log msg"
示例日志条目如下所示:
E, [2013-01-18T19:43:41.857146 #19412] ERROR -- : Log msg
如何将当前用户的IP放入日志中,因此它可能如下所示:
E, [2013-01-18T19:43:41.857146 #19412] ERROR -- : <127.0.0.1> Log msg
我可以写:
LOGGER.error "<#{request.ip}> Log msg"
但是,我想在每条日志消息上都有它,所以总是手动预先设置IP似乎是错误的方式。如何LOGGER
配置为自动解析request.ip
并将其放入日志中?
我按照以下方式尝试了一些答案:
configure.ru:
configure do
LOGGER = Logger.new("logs/sinatra.log")
original_formatter = Logger::Formatter.new
LOGGER.formatter = proc { |severity, datetime, progname, msg|
original_formatter.call(severity, datetime, progname, "#{ip} #{msg.dump}")
}
end
app.rb:
helpers do
def ip
request.ip
end
end
get '/' do
LOGGER.info 'test'
end
结果如下:
NameError: undefined local variable or method `ip' for #<Rack::Builder:0x00000001821c60>
更新根据TheTinMan的回答,我提出了以下帮助:
helpers do
def log(call,msg = '')
severity = Logger.const_get(call.upcase)
return if LOGGER.level > severity
msg = yield if block_given?
LOGGER.send(call, "<#{request.ip}> #{msg}")
end
end
所以我可以这样做:
log :info, 'msg'
log(:debug) { very.expensive.operation }
这看起来像我想要的解决方案。还有改进的余地吗?
答案 0 :(得分:1)
请参阅“Simple and Ideal Logging in Sinatra”:
我倾向于使用类似的东西:
require 'sinatra'
use Rack::Logger
def log(msg)
logger.info('%s: %s' % [request.ip, msg])
end
get '/' do
log("Request for '/'")
'<html><body>psych</body></html>'
end
哪个输出:
I, [2013-01-18T23:39:42.049072 #81011] INFO -- : 127.0.0.1: Request for '/' 127.0.0.1 - - [18/Jan/2013 23:39:42] "GET / HTTP/1.1" 200 31 0.0034
我可以对Logger进行子类化,或对其进行修补,但我更喜欢在本地方法中包装记录器调用。我们在工作中的几个应用程序中使用它,并且它工作得很好。
答案 1 :(得分:-1)
您可以覆盖Logger的格式化程序。有关示例,请参阅http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html。 您可以创建一个sinatra帮助器方法来返回请求IP,以便可以从formatter proc调用它。