Sensible Logging
A logging extension with sensible defaults for Sinatra apps.
Features
- Add a request UUID (or use an existing one if present in the
X-Request-IdHTTP header) for use in logs, your app or other middlewares - Trim the request logs to the bare minimal (inspired by lograge):
- method
- path
- requesting IP address
- status
- duration
- params if a
GETrequest
Example log line:
method=GET path=/contact client=192.168.1.254 status=200 duration=0.124 params={"category"=>"question"}
- Tagged logging, with some sensible defaults:
- severity
- subdomain
- environment
- request UUID
Example log line:
[INFO] [www.gb] [staging] [6004bb70-7b6d-43b6-a2cf-72d0336663ba] @todo tidy sql query
Usage
- Add
sensible_loggingto yourGemfileand install withbundle install:
gem 'sensible_logging'
- In your
app.rbregister the module and then define your logging configuration:
require 'sensible_logging'
class App < Sinatra::Base
register Sinatra::SensibleLogging
# Initialise Sensible Logging to add our middlewares.
sensible_logging(
logger: Logger.new($stdout)
)
# Configure the log level for different environments
configure :production do
set :log_level, Logger::INFO
end
# Requests will be logged in a minimal format
get '/' do
'Hello!'
end
get '/about' do
# The standard Sinatra logger helper will use the Sensible Logging gem
logger.info('About page')
end
get '/contact' do
# In addition to the default tags, you can add additional ones by using the `tagged` block on the `logger` helper
# [INFO] [localhost] [development] [a9d0183d-a3c3-4081-b502-38dcf4c3c4d7] [todo] Contact page
logger.tagged('todo') do |logger|
logger.info('Contact page')
end
end
# rest of code omitted
Available options
There are a number of options that you can pass into sensible_logging:
logger: The logging object. Default:Logger.new($stdout)use_default_log_tags: Includes the subdomain,RACK_ENVand unique request ID in the log tags. Default:truetld_length: For example, if your domain waswww.google.comthis would result inwwwbeing tagged as your subdomain. If your domain iswww.google.co.uk, set this value to2to correctly identify the subdomain aswwwrather thanwww.google. Default:1.log_tags: An array of additional log tags to include. This can be strings, or you can include alambdathat will be evaluated. Thelambdais passed a RackRequestobject, and it must return an array of string values. Default:[]exclude_params: An array of parameter names to be excluded fromGETrequests. By default,GETparameters are outputted in logs. If for example with the requesthttp://google.com/?one=dog&two=catyou didn't want theonelogged, you would setexclude_paramsto be['one']Default:[]include_log_severity: Includes the log severity in the tagged output, such asINFO,DEBUGetc Default:true
Sensible Logger will also respect the following Sinatra settings:
log_level: The level at which your logger object should respect logs. See above example. Default:Logger::DEBUG
Examples
There is an example Sinatra app included in this repo. Here's how to use it:
bundle install
cd examples
rackup
With the app running, run some curl commands against it:
curl 'localhost:9292/hello?one=two&two=three'
You should notice in the logs:
- Standard Sinatra
loggerhelper works out of the box within apps with tags. - Excluded parameters are not included, in this example
twobased onconfig.ru - The request log is minimal compared to out of the box Sinatra.
env['request_id']is now available to group log lines from the same request together, or to use in additional services such as Sentry.
FAQ
Why is the timestamp absent?
To quote lograge (which was the inspiration for this library):
The syntax is heavily inspired by the log output of the Heroku router. It doesn't include any timestamp by default, instead, it assumes you use a proper log formatter instead.
Releasing
- Update the version number
lib/sensible_logging/version.rb - Create a git commit and tag with the new version number
- Create a new PR with this change and once approved, merge to
main - Create a new PR with changes in
mainto be merged intostablesince the last release - Once approved and merged in, locally, run:
bundle exec rake releasewhich will build and push the new gem to Rubygems
Authors
By David Winter with contributions from Mark Sta Ana & Anthony King
License
MIT