Blabbermouth
An interface that blabs your business (errors, logging, instrumentation, etc.) to listening bystanders. There are a number of core bystanders provided, either built-in or through additional gems, for things like stdout, rails logger, rollbar, librato, etc.
When using blabbermouth you can configure which bystanders are listening in to the events and messages being reported, which allows you to easily log/track/instrument your application across multiple services. For example, the librato
and rollbar
bystanders can be powerful when used alongside one another, in order to do things like graph success vs. error rates in Librato and report the full corresponding exceptions and backtraces to Rollbar.
Blabbermouth can also provide redundancy by reporting to multiple services and is a great way to test out new providers (think Librato vs. New Relic), or to A/B test things like messaging queues when evaluating new gems or third party services.
Getting Started
Add the blabbermouth gem to your Gemfile:
gem 'blabbermouth'
Then run bundle install
.
You can also install additional bystanders by adding the appropriate gem(s) to your Gemfile. For example, if you wanted to use the rails logger and rollbar:
gem 'blabbermouth'
gem 'blabbermouth-rails'
gem 'blabbermouth-rollbar'
By default blabbermouth is configured with the stdout
bystander, which will log all messages to standard output. If you use the blabbermouth-rails
gem, this is overridden and defaults to the rails logger. This means that when you call something like Blabbermouth.error
without telling it which bystanders you'd like listening, the defaults will be used.
If you want to set a different default bystander or add other bystanders to the defaults, you can configure blabbermouth to do so (usually in /config/initializers/blabbermouth.rb
):
Blabbermouth.configure do |config|
# Replace the default bystander with Rollbar and Librato
config.bystanders = [:rollbar, :librato]
# Or add Rollbar to the existing default bystanders (either :stdout or
# :rails depending on what gems you're using)
config.bystanders << :rollbar
end
Usage
The simplest way to start using blabbermouth is to just call the provided core methods directly on the Blabbermouth
module:
# info - logs an event as info with an optional message and data hash
Blabbermouth.info('my_app.some_namespace.my_action', 'App did something', data: {some: 'other data'})
# error - logs an exception with an optional data hash
begin
# do stuff
rescue => e
Blabbermouth.error('my_app.action.failed', e, data: {other: ['arguments', 'can go here']})
end
# increment - increment a counter (or log a 'tick' depending on the bystander) with an optional integer and data hash
Blabbermouth.increment('my_app.some_counter', 3) # increment by 3, default is 1
# count - log a total count with an optional data hash
Blabbermouth.count('my_app.total_things', 250)
# time - logs a timed duration with an optional data hash, can execute and time a block for you
Blabbermouth.time('my_app.some_job.execution_time', 30, data: {job_args: {whatever: 'stuff'}})
Blabbermouth.time('my_app.my_block.execution_time') do
sleep 30
end
This will use the default configured bystander(s), but you can also override those defaults when calling the method:
# blabs an error to librato and rollbar, will NOT post to the default bystanders
Blabbermouth.error('my_app.some_action.failed', e, :rollbar, :librato, data: {key: 'value'})
# you can also instantiate an object and call your method on that if you prefer that syntax (I usually do :)
Blabbermouth.new(:rollbar, :librato).error('my_app.some_action.failed', e, data: {key: 'value'})
# if you want to post to your default bystander as well, you'll have to specify it
# this example assumes your default bystander is configured as :stdout
Blabbermouth.new(:stdout, :rollbar, :librato).error('my_app.some_action.failed', e)
# or you could reference the configured defaults to be a bit more dynamic
bystanders = Blabbermouth.configuration.bystanders + [:rollbar, :librato]
Blabbermouth.error('my_app.some_action.failed', e, *bystanders)
You can also instantiate a Blabbermouth::Blabber
object, pre-configured with bystanders, then re-use that object without needing to override the defaults for every method call.
# create a blabber that will blab to the rails log and to librato
blabber = Blabbermouth::Blabber.new(:rails, :librato) # Blabbermouth.new will also work
blabber.increment('my_app.my_key') # increment a librato counter by 1 and log the increment action to the rails log
If you happen to be using a custom bystander and you've defined additional methods you'd like to use with blabbermouth, there is some metaprogramming to allow you to do so fairly easily. You cannot use the direct Blabbermouth.my_method
syntax, but you can instantiate a Blabbermouth::Blabber
with your bystander and call your method through that object. For example, if you've defined a bystander that has a gauge
method (which is not defined currently as part of the core set of methods), you can still call that method through your blabber object:
# create a blabber using your custom bystander
blabber = Blabbermouth::Blabber.new(:my_bystander)
blabber.gauge('my_app.some_key', my_args) # calls the #gauge method on your bystander
Blabbermouth will check whether a bystander responds to a method before trying to call it, which means you can mix and match bystanders and even if you call a method not supported by one, the rest will still be called.
# create a blabber using your custom bystander and the rails logger
blabber = Blabbermouth::Blabber.new(:my_bystander, :rails)
# this will call the #gauge method on your custom bystander but not
# on the rails bystander, which does not have the method defined
blabber.gauge('my_app.some_key', my_args)
# if your bystander doesn't have a method defined (let's say error)
# then it will be skipped when calling that method
blabber.error('my_app.some_error', e) # will log the error to the rails logger, but not to your bystander
Available Bystanders
There are a number of core bystanders you can use to get started. The stdout
bystander is built into blabbermouth, and a few other useful ones are provided by core extension gems.
Stdout
The :stdout
bystander is built-in and provided with the core blabbermouth
gem. It will format any messages sent to it and log them to standard output. In the future I'd like to provide a way to override the formatting of the logged messages (more easily than monkeypatching the Stdout#log_message
method or extending to your own custom bystander and overriding that method).
Syslog
The :syslog
bystander is provided by the blabbermouth-syslog
gem and is similar to the stdout
bystander, except it logs messages using the default configured Syslog::Logger
.
Rails
The :rails
bystander is provided by the blabbermouth-rails
gem and is similar to the stdout
bystander, except it logs messages using the default configured Rails.logger
.
Rollbar
The :rollbar
bystander is provided by the blabbermouth-rollbar
gem. It logs your messages to Rollbar, which can be useful for logging errors and other info because it can be configured to pass along lots of additional data about requests, sessions, etc.
The rollbar
gem is a dependency of blabbermouth-rollbar
so you don't need to require it separately, but you will need to configure it and provide credentials the same way you would if you were using it directly.
Librato
The :librato
bystander is provided by the blabbermouth-librato
gem, and will ping Librato. Librato provides excellent tools to instrument various actions in your application, and it's a great way to track things like background jobs, execution time/performance in production environments, etc.
The librato-metrics
gem is a dependency of blabbermouth-librato
so you don't need to require it separately, but you will need to configure it and provide credentials the same way you would if you were using it directly.
New Relic
The :new_relic
bystander is provided by the blabbermouth-new_relic
gem, and will log your errors, messages and metrics with NewRelic using your application's configured NewRelic::Agent
, which is provided by the newrelic_rpm gem.
Redis
Not Yet Implemented
Custom Bystanders
TODO document creating your own custom bystanders
Testing
Since any code that uses blabbermouth will blab to the configured bystanders, you might be seeing output or sending data to third party services when running tests (depending on your configuration). If you want to disable this, you can gag blabbermouth by setting the gagged
configuration option in your test environment. For example:
Blabbermouth.configure do |config|
config.gagged = Rails.env.test?
end
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request