Ruby 在Sinatra中使用Rack::CommonLogger
我用Sinatra编写了一个小型web服务器。我希望能够将消息记录到日志文件中。我已经通读了和www.sinatrarb.com/intro.html,我看到Rack有一个叫做Rack::CommonLogger的东西,但是我找不到任何关于如何访问和使用它记录消息的示例。我的应用程序很简单,所以我将其作为顶级DSL编写,但如果需要的话,我可以从SinatraBase中将其子类化。我遵循了我在这篇文章中找到的内容-摘录如下Ruby 在Sinatra中使用Rack::CommonLogger,ruby,logging,sinatra,rack,error-logging,Ruby,Logging,Sinatra,Rack,Error Logging,我用Sinatra编写了一个小型web服务器。我希望能够将消息记录到日志文件中。我已经通读了和www.sinatrarb.com/intro.html,我看到Rack有一个叫做Rack::CommonLogger的东西,但是我找不到任何关于如何访问和使用它记录消息的示例。我的应用程序很简单,所以我将其作为顶级DSL编写,但如果需要的话,我可以从SinatraBase中将其子类化。我遵循了我在这篇文章中找到的内容-摘录如下 require 'rubygems' require 'sinatra'
require 'rubygems'
require 'sinatra'
disable :run
set :env, :production
set :raise_errors, true
set :views, File.dirname(__FILE__) + '/views'
set :public, File.dirname(__FILE__) + '/public'
set :app_file, __FILE__
log = File.new("log/sinatra.log", "a")
STDOUT.reopen(log)
STDERR.reopen(log)
require 'app'
run Sinatra.application
然后使用
put
或print
。它对我很有用。Rack::CommonLogger不会为您的主应用程序提供记录器,它只会像Apache那样记录请求
自己检查代码:
所有Rack
应用程序都有一个调用方法,该方法通过HTTP请求环境调用get,如果您检查此中间件的调用方法,则会发生以下情况:
def call(env)
began_at = Time.now
status, header, body = @app.call(env)
header = Utils::HeaderHash.new(header)
log(env, status, header, began_at)
[status, header, body]
end
在本例中,@app
是主应用程序,中间件只是注册请求开始的时间,然后对中间件进行分类,获得[status,header,body]三元组,然后使用这些参数调用私有日志方法,返回与应用程序最初返回的三元组相同的三元组
logger
方法如下:
def log(env, status, header, began_at)
now = Time.now
length = extract_content_length(header)
logger = @logger || env['rack.errors']
logger.write FORMAT % [
env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
env["REMOTE_USER"] || "-",
now.strftime("%d/%b/%Y %H:%M:%S"),
env["REQUEST_METHOD"],
env["PATH_INFO"],
env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"],
env["HTTP_VERSION"],
status.to_s[0..3],
length,
now - began_at ]
end
可以看出,log
方法只是从request env获取一些信息,并登录到构造函数调用中指定的记录器上,如果没有记录器实例,则它将转到rack.errors
记录器(默认情况下似乎有一个)
使用方法(在config.ru
中):
如果您希望在所有应用程序中都有一个通用的记录器,您可以创建一个简单的记录器中间件:
class MyLoggerMiddleware
def initialize(app, logger)
@app, @logger = app, logger
end
def call(env)
env['mylogger'] = @logger
@app.call(env)
end
end
要使用它,请在config.ru
上:
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
run YourApp
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
use MyLoggerMiddleware, logger
run MyApp
root = ::File.dirname(__FILE__)
logfile = ::File.join(root,'logs','requests.log')
require 'logger'
class ::Logger; alias_method :write, :<<; end
logger = ::Logger.new(logfile,'weekly')
use Rack::CommonLogger, logger
require ::File.join(root,'myapp')
run MySinatraApp.new # Subclassed from Sinatra::Application
希望这有帮助。在您的
config.ru
中:
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
run YourApp
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
use MyLoggerMiddleware, logger
run MyApp
root = ::File.dirname(__FILE__)
logfile = ::File.join(root,'logs','requests.log')
require 'logger'
class ::Logger; alias_method :write, :<<; end
logger = ::Logger.new(logfile,'weekly')
use Rack::CommonLogger, logger
require ::File.join(root,'myapp')
run MySinatraApp.new # Subclassed from Sinatra::Application
root=::File.dirname(\uuuu File\uuuu)
logfile=::File.join(root、'logs'、'requests.log')
需要“记录器”
类::记录器;alias_方法:write,:类错误记录器
def初始化(文件)
@file=::file.new(文件“a+”)
@file.sync=true
结束
def puts(味精)
@file.puts
@file.write(“--ERROR--{Time.now.strftime(“%d%b%Y%H:%M:%S%z”)}:”)
@file.puts(msg)
结束
结束
类应用程序
如果使用Passenger,重新打开标准输出并将其重定向到文件不是一个好主意。在我的情况下,这会导致乘客无法启动。阅读本期文章
这将是正确的方法:
logger = ::File.open('log/sinatra.log', 'a+')
Sinatra::Application.use Rack::CommonLogger, logger
这是可行的,但我真的很想知道如何使用Rack::CommonLogger发送带有时间戳的消息。MyLoggerMaddleware调用(env)的第一行不应该是:env['Rack.errors']=@logger吗?另外,我不想记录每个请求,只想记录警告和错误消息。但我希望它是可配置的,以便我可以设置日志记录的级别,如“调试”、“信息”、“警告”、“错误”。。。顺便说一句,我的应用程序不是Rails应用程序。没有config.ru文件。这是一个简单的Sinatra应用程序。我希望使用一个现有的标准,但不知道那是什么。也许我得带上你给我看的CommonLogger,自己动手做?config.ru
是Rack的配置文件,而不是Rails的配置文件。Sinatra和Rails都是基于机架的,因此您也可以在Sinatra应用程序中使用config.ru
。首先发布在此处的文件链接已更改。目前这对我来说不起作用。它对Sinatra或机架日志记录没有影响。我尝试了你的解决方案,它很有效。我想知道为什么它必须在config.ru中?一个我不是100%在那里的文件,你介意评论一下其中的一些行吗?