Where does RACK log to?
It depends. Many developers define their app log file to app/servername.log or just to the current path where the Rack app is loaded.
Yes you can change it's path.
Usually you get a config.ru file with something like:
log = File.new("sinatra.log", "a+")
$stdout.reopen(log)
$stderr.reopen(log)
# optionally to sync logs while the server is running
$stderr.sync = true
$stdout.sync = true
and/or
configure do
LOGGER = Logger.new("sinatra.log")
enable :logging, :dump_errors
set :raise_errors, true
end
in this case the log file is located under appdir/sinatra.log. But remember this code can be anywhere in your Rack app, so please seek for "log" in your application directory.
$ cd projectname
$ grep -ri 'log' *
have fun and post here your config.ru and/or the mainprojectfile.rb.
How do I get SInatra and Rack to output to my Logger instance?
I'm not using WEBrick but Thin (set :server, 'thin'
) Anyway according to Sinatra configuration I redirect rack.errors
to my $logger
:
class IOToLog < IO
def initialize(logger)
@logger = logger
end
def write(string)
@logger.debug {"SINATRA #{string.strip}"}
end
end
IOTOLOG = IOToLog.new($logger)
before {
env["rack.errors"] = IOTOLOG
}
and the output is:
2017-06-21 15:44:46.166 DEBUG SINATRA 127.0.0.1 - - [21/Jun/2017:15:44:46 +0200] "GET /wd/hub/status HTTP/1.1" 200 83 0.0004
2017-06-21 15:44:51.167 DEBUG SINATRA 127.0.0.1 - - [21/Jun/2017:15:44:51 +0200] "GET /wd/hub/status HTTP/1.1" 200 83 0.0004
BTW I've tried env["rack.logger"] = $logger
but with no luck.
Use Rack::CommonLogger in Sinatra
Rack::CommonLogger
won't provide a logger to your main app, it will just logs the request like Apache would do.
Check the code by yourself: https://github.com/rack/rack/blob/master/lib/rack/common_logger.rb
All Rack
apps have the call method that get's invoked with the HTTP Request env, if you check the call method of this middleware this is what happens:
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
The @app
in this case is the main app, the middleware is just registering the time the request began at, then it class your middleware getting the [status, header, body] triple, and then invoke a private log method with those parameters, returning the same triple that your app returned in the first place.
The logger
method goes like:
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
As you can tell, the log
method just grabs some info from the request env, and logs in on a logger that is specified on the constructor call, if there is no logger instance then it goes to the rack.errors
logger (it seems there is one by default)
The way to use it (in your config.ru
):
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
run YourApp
If you want to have a common logger in all your app, you could create a simple logger middleware:
class MyLoggerMiddleware
def initialize(app, logger)
@app, @logger = app, logger
end
def call(env)
env['mylogger'] = @logger
@app.call(env)
end
end
To use it, on your config.ru
:
logger = Logger.new('log/app.log')
use Rack::CommonLogger, logger
use MyLoggerMiddleware, logger
run MyApp
Hope this helps.
How to filter sensitive information when logging with Sinatra and Rack Logger
You can try to intercept the call to write and filter out sensitive messages like so :
logger = Logger.new("my_common.log")
logger.instance_eval do
def write(msg)
self.send(:<<, msg) if !msg.match /SUPER SENSITIVE INFO HERE/
end
end
then, configure Rack::CommonLogger to use this instance of the logger:
config.middleware.use Rack::CommonLogger, logger
Related Topics
Rails 3. How to Explicitly Round a Number to Two Decimal Places in The Model
Rails Guides Offline Documentation
How to Retrieve Exif Information of an Image in Rails
Specify Custom Index Name When Using Add_Reference
Error Nomethoderror: Undefined Method 'Debug_Rjs=' for Actionview::Base:Class
How Do Open a File for Writing Only If It Doesn't Already Exist in Ruby
Is There a Definitive Reference Document for Ruby Syntax
Sorting an Array of Arrays in Ruby
Using %I and %I Symbol Array Literal
How to Install and Use Slim Template Engine with Middleman
Error When Installing Ruby 2.1.3 with Rvm
Ruby on Rails Foreach with Bootstrap3 Row Class
Ror, Can't Iterate from Datetime/Timewithzone
Fresh Install of Rvm in Ubuntu Isn't Letting Me Install Gems (Zlib Error)
How to Share Worker Among Two Different Applications on Heroku