web-dev-qa-db-fra.com

Vous vous connectez à Sinatra?

J'ai du mal à comprendre comment enregistrer des messages avec Sinatra. Je ne cherche pas à enregistrer les demandes, mais plutôt des messages personnalisés à certains points de mon application. Par exemple, lors de la récupération d'une URL, je voudrais enregistrer "Fetching #{url}".

Voici ce que j'aimerais:

  • La possibilité de spécifier des niveaux de journalisation (ex: logger.info("Fetching #{url}"))
  • Dans les environnements de développement et de test, les messages seraient écrits sur la console.
  • En production, écrivez uniquement les messages correspondant au niveau de journal actuel.

Je suppose que cela peut facilement être fait dans config.ru, Mais je ne suis pas sûr à 100% du paramètre que je veux activer, et si je dois créer manuellement un objet Logger moi-même (et en outre, quelle classe de Logger utiliser: Logger, Rack::Logger, ou Rack::CommonLogger).

(Je sais qu'il y a des questions similaires sur StackOverflow, mais aucune ne semble répondre directement à ma question. Si vous pouvez me diriger vers une question existante, je la marquerai comme une copie).

53
Kyle Fox

Sinatra 1.3 sera livré avec un tel objet enregistreur, exactement utilisable comme ci-dessus. Vous pouvez utiliser Edge Sinatra comme décrit dans " The Bleeding Edge ". Ce ne sera pas si long avant la sortie de la 1.3, je suppose.

Pour l'utiliser avec Sinatra 1.2, faites quelque chose comme ceci:

require 'sinatra'
use Rack::Logger

helpers do
  def logger
    request.logger
  end
end
46
Konstantin Haase

Je me connecte personnellement à Sinatra via:

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

Si vous utilisez quelque chose comme nicorn logging ou autre middleware qui correspond à IO streams, vous pouvez facilement configurer un enregistreur sur STDOUT ou 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

cela vous permet d'intercepter des messages à la portée de l'application, plutôt que d'avoir simplement accès à l'enregistreur comme assistant de demande

7
lfender6445

Voici une autre solution:

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

Bien sûr, vous pouvez le faire sans ActiveSupport :: Concern en plaçant les blocs configure et before directement dans MySinatraApp, mais ce que j'aime dans cette approche, c'est qu'elle est très propre - toute la configuration de journalisation est totalement abstrait de la classe principale de l'application.

Il est également très facile de repérer où vous pouvez le changer. Par exemple, le SO a demandé de le faire se connecter à la console en cours de développement. Il est assez évident ici que tout ce que vous devez faire est un peu de logique si-alors dans le log_file méthode.

3
Isaac Betesh