AffiliationId
AffiliationId is a middleware collection for different frameworks and gems with the purpose of making end-to-end request tracing as easy as possible.
The concept is really simple and it's meant to work like this:
- A request that reaches a web app or API it's the entry point and should have a unique ID.
- That ID is propagated throughout the app in all parts that are a consequence of the initial request, things like: requests to third-party APIs, Sidekiq jobs, error trackers, etc.
- The ID is included in all the logs statements so they can be traced based on the ID
Although there are tools like OpenTelemetry, which is great, that is a much more complex tool and brings a lot of overhead that maybe is not worth it for some applications or teams.
Currently implemented middleware:
- Rack
- Rails
- Faraday
- Sidekiq
Installation
Add this line to your application's Gemfile:
gem 'affiliation_id'
And then execute:
$ bundle install
Or install it yourself as:
$ gem install affiliation_id
Usage
Under the hood AffiliationId uses SecureRandom.uuid
to generate unique ID's when needed.
# Get current ID
AffiliationId.current_id
=> '93f971bb-b889-4223-ac57-5d39f34051a4'
.current_id
is memoized and subsequent calls will return the same value
# Set ID
AffiliationId.current_id = 'myID'
AffiliationId.current_id
=> 'myID'
# Overwrite current_id with a new generated value
AffiliationId.current_id
=> '93f971bb-b889-4223-ac57-5d39f34051a4'
AffiliationId.renew_current_id!
=>'55e94f67-5fce-4226-98d5-4c149684debe'
AffiliationId.current_id
=> '55e94f67-5fce-4226-98d5-4c149684debe'
# Reset/Clear current_id
AffiliationId.current_id
=> '55e94f67-5fce-4226-98d5-4c149684debe'
AffiliationId.reset!
=> nil
Rack
The middleware for rack based applications is inspired from the Rails version of this middleware ActionDispatch::RequestId.
It looks at the X-Affiliation-ID
, if the header is found and a value is present, this will be set as the Affiliation.current_id
throughout the request, otherwise an random ID is generated.
To use the middleware, it needs to be added to the app middleware stack.
# config.ru
require 'affiliation_id/middleware/rack'
use AffiliationId::Middleware::Rack
run MyApp.new
Rails
In true Rails fashion, this works out of the box after installing the gem. Although it still depends on ActionDispatch::RequestId which is included by default in all new Rails apps.
Faraday
By using the Faraday middleware the, all requests will include a header X-Affiliation-ID
with the value of AffiliationID.current_id
.
require 'affiliation_id/middleware/faraday'
# ...
conn = Faraday.new do |f|
f.request :affiliation_id # include AffiliationID.current_id in the request headers
f.adapter :net_http # Use the Net::HTTP adapter
end
Sidekiq
For more information on how Sidekiq Middleware works, I suggest reading id directly from the Sidekiq documentation.
Configuration example:
# sidekiq_initializer.rb
require 'affiliation_id/middleware/sidekiq_client'
require 'affiliation_id/middleware/sidekiq_server'
Sidekiq.configure_client do |config|
config.client_middleware do |chain|
chain.add AffiliationId::Middleware::SidekiqClient
end
end
Sidekiq.configure_server do |config|
config.client_middleware do |chain|
chain.add AffiliationId::Middleware::SidekiqClient
end
config.server_middleware do |chain|
chain.add AffiliationId::Middleware::SidekiqServer
end
end
Configuration
# affiliation_id_initializer.rb
AffiliationId.configure do |config|
# By default AffiliationId.current_id will raise an AffiliationId::MissingCurrentId exception if the value was not previously set.
# To opt in to the behavior of generating the id automatically config the following setting to false.
# config.enforce_explicit_current_id = false (Default: true)
# AffiliationId uses 'X-Request-ID' as the default header name.
# This can be changed by the following config.
# config.header_name = 'My-Custom-Header' (Default: 'X-Request-ID')
end
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and the created tag, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/siklodi-mariusz/affiliation_id. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the AffiliationId project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.