23tux
23tux

Reputation: 14726

Sinatra doesn't show exceptions in log file

I'm coming from Rails to sinatra, and I have some problems using logging. I have a Sinatra app, that does it's logging like so:

  configure do
    Logger.class_eval { alias :write :'<<' }
    logger = Logger.new("log/#{settings.environment}.log")
    use Rack::CommonLogger, logger
  end

All requests are logged properly, I see sth like

127.0.0.1 - - [25/May/2013 10:34:21] "GET / HTTP/1.1" 200 30 0.0021
127.0.0.1 - - [25/May/2013 10:34:22] "GET /favicon.ico HTTP/1.1" 404 18 0.0041

Inside the log files. But I also want to log application errors to the logfile. When I start my app in production env with RACK_ENV=production rackup config.ru and I an error occurs, it only logs a 500 http status, but not the error itself. The error is shown inside the console. This is fine for development, but not for production. The errors should appear inside the log file for later debugging.

Here is my config.ru

require 'rubygems'
require 'bundler'
Bundler.require(:default, ENV['RACK_ENV'].to_sym)
disable :run
Encoding.default_external = Encoding::UTF_8

use Rack::ShowExceptions
use Rack::Session::Pool

require File.expand_path '../app.rb', __FILE__
run App

And this is my app.rb

class App < Sinatra::Base
  configure do
    set :public_folder, Proc.new { File.join(root, "public") }
    Logger.class_eval { alias :write :'<<' }
    logger = Logger.new("log/#{settings.environment}.log")
    use Rack::CommonLogger, logger
  end

  get '/' do
    raise "ERROR"
    erb :home, layout: :layout
  end
end

I've played around with the enable :logging, :dump_errors, :raise_errors inside the configure do block, but that doesn't anything. Is it, because I'm using sinatra as a modular application? Inside the get "/" route I can access the variables set inside the configure block.

So any idea, what the best practise is, to log errors to a file with sinatra?

Upvotes: 2

Views: 4486

Answers (2)

fguillen
fguillen

Reputation: 38772

The only way I made Sinatra to move error messages to a file was:

$stderr.reopen(<the file path>)

More elaborated example:

class App < Sinatra::Base
  configure do
    set :logging, true
    set :root, File.dirname(__FILE__)
  end

  configure :development, :production do
    # console log to file
    log_path = "#{root}/log" 
    Dir.mkdir(log_path) unless File.exist?(log_path)
    log_file = File.new("#{log_path}/#{settings.environment}.log", "a+")
    log_file.sync = true
    $stdout.reopen(log_file)
    $stderr.reopen(log_file)
  end
end

Upvotes: 1

draxxxeus
draxxxeus

Reputation: 1523

Read the docs here: http://www.sinatrarb.com/intro.html#Logging

Note that logging is only enabled for Sinatra::Application by default, so if you inherit from Sinatra::Base, you probably want to enable it yourself:

class MyApp < Sinatra::Base
  configure :production, :development do
    enable :logging
  end
end

Upvotes: 3

Related Questions