I’m attempting to setup logging in my simple classic-style sinatra app. (v1.3.2) I define all of my setup in an environment.rb file like this:
require 'sinatra'
require 'couchrest'
require 'couchrest_model'
require 'json'
require "net/http"
require "uri"
require 'shotgun' # to auto-restart server on page reload
enable :run, :logging
# CouchDB setup
configure do
SiteConfig = OpenStruct.new(
:url_base => 'http://localhost:4567/',
:url_base_db => 'http://localhost:5984/',
:db_name => 'adrequest'
)
end
# Logging setup
logger = Logger.new('vehicle.log')
use Rack::CommonLogger, logger
My app file looks like this:
require './environment'
class Vehicle < CouchRest::Model::Base
use_database CouchRest.database!((SiteConfig.url_base_db || '') + SiteConfig.db_name)
property :url, String
timestamps!
validates_presence_of :url
end
get '/*' do
requesturl = params[:splat].first
@vehicle = Vehicle.new
@vehicle.url = requesturl
@vehicle.save
puts "logger: #{env['rack.logger']}"
puts "env: #{ENV['RACK_ENV']}"
logger.info "written to DB"
end
not_found do
halt 404, 'page not found'
end
Results in:
logger: #<Rack::NullLogger:0x007fb4f4ccc238>
env: development
The app creates a the ‘vehicle.log’ file, but it’s empty. How do I get logger.info to write to my ‘vehicle.log’ file?
I’ve read the Sinatra README here: http://www.sinatrarb.com/intro#Logging. It seems to imply that all that I need is the:
enable :logging
and then sinatra will take the rest of the configuration from Rack::CommonLogger, but it doesn’t say how to do that exactly…
Thanks in advance for any ideas!
The reason that “logger” never gets enabled in the app file is because it has local scope in the environment.rb file. In general, a Ruby variable that is defined in a file is scoped locally within that file.
My solution for this was to make the “logger” variable global:
While usage of global variables are generally frowned upon, this app is simple enough that it’s probably ok. Nevertheless, if the app were to get larger it would probably make sense to look at a more module-based app and handle configuration in a different way. (Maybe with Modules, or configu.ru file?)
I’m not sure if this is the “ideal” solution, so if anyone has any better ideas please comment.
Incidentally, the SiteConfig variable defined in the environment.rb file turns out to be a constant (you can see this by doing
puts "SiteConfig: #{defined? SiteConfig}"), which is why it’s value can be “seen” in the separate app file.