簡體   English   中英

在Sinatra中使用Rack :: CommonLogger

[英]Use Rack::CommonLogger in Sinatra

我有一個與Sinatra一起編寫的小型Web服務器。 我希望能夠將消息記錄到日志文件中。 我通過http://www.sinatrarb.com/api/index.html和www.sinatrarb.com/intro.html閱讀,我看到Rack有一個名為Rack :: CommonLogger的東西,但我找不到如何訪問和用於記錄消息的任何示例。 我的應用程序很簡單所以我把它寫成頂級DSL,但我可以切換到從SinatraBase繼承它,如果這是所需要的一部分。

Rack::CommonLogger不會為你的主應用程序提供記錄器,它只會像Apache那樣記錄請求。

自己檢查代碼: https//github.com/rack/rack/blob/master/lib/rack/common_logger.rb

所有Rack應用程序都具有使用HTTP Request env調用的調用方法,如果您檢查此中間件的調用方法,則會發生以下情況:

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在這種情況下是主要的應用程序,中間件是剛剛注冊的請求開始的時候,那么你的類中間件獲得[狀態,頭部,身軀]三聯,然后調用專用日志方法與參數,返回您的應用首先返回的相同三元組。

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方法只是從請求env中獲取一些信息,然后登錄構造函數調用中指定的記錄器,如果沒有logger實例,那么它將轉到rack.errors記錄器(它似乎在那里)默認情況下是一個)

使用它的方式(在你的config.ru ):

logger = Logger.new('log/app.log')

use Rack::CommonLogger, logger
run YourApp

如果您想在所有應用中都有一個通用記錄器,您可以創建一個簡單的記錄器中間件:

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
use MyLoggerMiddleware, logger
run MyApp

希望這可以幫助。

在你的config.ru

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

我按照我在這篇博文上發現的內容 - 摘錄如下

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

然后使用putsprint 它對我有用。

class ErrorLogger
  def initialize(file)
    @file = ::File.new(file, "a+")
    @file.sync = true
  end

  def puts(msg)
    @file.puts
    @file.write("-- ERROR -- #{Time.now.strftime("%d %b %Y %H:%M:%S %z")}: ")
    @file.puts(msg)
  end
end


class App < Sinatra::Base

  if production?
    error_logger = ErrorLogger.new('log/error.log')

    before {
      env["rack.errors"] =  error_logger
    }
  end

  ...

end

如果您使用Passenger,重新打開STDOUT並將其重定向到文件不是一個好主意。 在我的情況下,它導致乘客無法啟動。 請閱讀https://github.com/phusion/passenger/wiki/Debugging-application-startup-problems#stdout-redirection以解決此問題。

這將是正確的方式:

logger = ::File.open('log/sinatra.log', 'a+')
Sinatra::Application.use Rack::CommonLogger, logger

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM