Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 在Sinatra中使用Rack::CommonLogger_Ruby_Logging_Sinatra_Rack_Error Logging - Fatal编程技术网

Ruby 在Sinatra中使用Rack::CommonLogger

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'

我用Sinatra编写了一个小型web服务器。我希望能够将消息记录到日志文件中。我已经通读了和www.sinatrarb.com/intro.html,我看到Rack有一个叫做Rack::CommonLogger的东西,但是我找不到任何关于如何访问和使用它记录消息的示例。我的应用程序很简单,所以我将其作为顶级DSL编写,但如果需要的话,我可以从SinatraBase中将其子类化。

我遵循了我在这篇文章中找到的内容-摘录如下

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%在那里的文件,你介意评论一下其中的一些行吗?