web-dev-qa-db-ja.com

Sinatraにログインしますか?

Sinatraでメッセージを記録する方法がわかりません。リクエストをログに記録するのではなく、アプリの特定のポイントでカスタムメッセージを記録することを考えています。たとえば、URLを取得するとき、_"Fetching #{url}"_をログに記録します。

私が欲しいものは次のとおりです。

  • ログレベルを指定する機能(例:logger.info("Fetching #{url}")
  • 開発およびテスト環境では、メッセージはコンソールに書き込まれます。
  • 本番環境では、現在のログレベルに一致するメッセージのみを書き出します。

これは_config.ru_で簡単に行うことができると思いますが、どの設定を有効にするか、そして自分でLoggerオブジェクトを手動で作成する必要がある場合(さらには、使用するLoggerのクラス:Logger、_Rack::Logger_、または_Rack::CommonLogger_)。

(StackOverflowにも同様の質問があることは知っていますが、私の質問に直接答えているものはないようです。既存の質問を教えていただければ、この質問を重複としてマークします)。

53
Kyle Fox

Sinatra 1.3には、上記のとおり正確に使用できるロガーオブジェクトが付属しています。 「 The Bleeding Edge 」で説明されているように、Edge Sinatraを使用できます。 1.3をリリースするまでそれほど長くはないでしょう。

Sinatra 1.2で使用するには、次のようにします。

require 'sinatra'
use Rack::Logger

helpers do
  def logger
    request.logger
  end
end
46

私は個人的にシナトラにログインします:

require 'sinatra'
require 'sequel'
require 'logger'
class MyApp < Sinatra::Application
  configure :production do
    set :haml, { :ugly=>true }
    set :clean_trace, true

    Dir.mkdir('logs') unless File.exist?('logs')

    $logger = Logger.new('logs/common.log','weekly')
    $logger.level = Logger::WARN

    # Spit stdout and stderr to a file during production
    # in case something goes wrong
    $stdout.reopen("logs/output.log", "w")
    $stdout.sync = true
    $stderr.reopen($stdout)
  end

  configure :development do
    $logger = Logger.new(STDOUT)
  end
end

# Log all DB commands that take more than 0.2s
DB = Sequel.postgres 'mydb', user:'dbuser', password:'dbpass', Host:'localhost'
DB << "SET CLIENT_ENCODING TO 'UTF8';"
DB.loggers << $logger if $logger
DB.log_warn_duration = 0.2
16
Phrogz

nicornロギングまたはその他のミドルウェアを使用している場合、IOストリーム)、ロガーをSTDOUTまたはSTDERRに簡単に設定できます。

# Unicorn.rb
stderr_path "#{app_root}/shared/log/Unicorn.stderr.log"
stdout_path "#{app_root}/shared/log/Unicorn.stdout.log"

# sinatra_app.rb
set :logger, Logger.new(STDOUT) # STDOUT & STDERR is captured by Unicorn
logger.info('some info') # also accessible as App.settings.logger

これにより、リクエストヘルパーとしてロガーにアクセスするだけでなく、アプリケーションスコープでメッセージをインターセプトできます

7
lfender6445

別のソリューションを次に示します。

module MySinatraAppLogger
  extend ActiveSupport::Concern

  class << self
    def logger_instance
      @logger_instance ||= ::Logger.new(log_file).tap do |logger|
        ::Logger.class_eval { alias :write :'<<' }
        logger.level = ::Logger::INFO
      end
    end

    def log_file
      @log_file ||= File.new("#{MySinatraApp.settings.root}/log/#{MySinatraApp.settings.environment}.log", 'a+').tap do |log_file|
        log_file.sync = true
      end
    end
  end

  included do
    configure do
      enable :logging
      use Rack::CommonLogger, MySinatraAppLogger.logger_instance
    end

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

  def logger
    MySinatraAppLogger.logger_instance
  end
end

class MySinatraApp < Sinatra::Base
  include MySinatraAppLogger
  get '/' do
    logger.info params.inspect
  end
end

もちろん、configureブロックとbeforeブロックをMySinatraAppに直接配置することにより、ActiveSupport :: Concernなしで実行できますが、このアプローチの気に入っている点は、非常にクリーンなことです。メインアプリクラスから完全に抽象化されています。

また、変更できる場所を見つけるのも非常に簡単です。たとえば、SOは、開発中にコンソールにログを記録することについて尋ねられました。ここで、あなたがする必要があるのは、log_file 方法。

3
Isaac Betesh