aws-xray
The unofficial AWS X-Ray Tracing SDK for Ruby. It enables you to capture in-coming HTTP requests and out-going HTTP requests and send them to xray-agent automatically.
AWS X-Ray is a ditributed tracing system. See more detail about AWS X-Ray at official document.
Features
- Propagatin support in both single and multi thread environment.
- Rack middleware.
- Faraday middleware.
- net/http hook.
- Tracing HTTP request/response.
- Tracing errors.
- Annotation and metadata support.
Installation
Add this line to your application's Gemfile:
gem 'aws-xray'
And then execute:
$ bundle
Usage
Rails app
Just require aws/xray/rails
. It uses your application name by default.
e.g. Legacy::MyBlog
-> legacy-my-blog
.
# Gemfile
gem 'aws-xray', require: 'aws/xray/rails'
To trace out-going HTTP requests, see below.
Rack app
# config.ru
require 'aws-xray'
Aws::Xray.config.name = 'my-app'
use Aws::Xray::Rack
This allow your app to trace in-coming HTTP requests.
To trace out-going HTTP requests, use Faraday middleware.
Faraday.new('...', headers: { 'Host' => 'down-stream-app-id' } ) do |builder|
builder.use Aws::Xray::Faraday
# ...
end
If you don't use any Service Discovery tools, pass the down stream app name to the Faraday middleware:
Faraday.new('...') do |builder|
builder.use Aws::Xray::Faraday, 'down-stream-app-id'
# ...
end
non-Rack app (like background jobs)
require 'aws-xray'
# Build HTTP client with Faraday builder.
# You can set the down stream app id to Host header as well.
client = Faraday.new('...') do |builder|
builder.use Aws::Xray::Faraday, 'down-stream-app-id'
# ...
end
# Start new tracing context then perform arbitrary actions in the block.
Aws::Xray.trace(name: 'my-app-batch') do |seg|
client.get('/foo')
Aws::Xray::Context.current.child_trace(name: 'fetch-user', remote: true) do |sub|
# DB access or something to trace.
end
end
Hooks
You can enable all the hooks with:
# Gemfile
gem 'aws-xray', require: 'aws/xray/hooks/all'
net/http hook
To monkey patch net/http and records out-going http requests automatically, just require aws/xray/hooks/net_http
:
If you can pass headers for net/http client, you can setup subsegment name via X-Aws-Xray-Name
header:
Net::HTTP.start(host, port) do |http|
req = Net::HTTP::Get.new(uri, { 'X-Aws-Xray-Name' => 'target-app' })
http.request(req)
end
If you can't access headers, e.g. external client library like aws-sdk or dogapi-rb, setup subsegment name by Aws::Xray::Context#overwrite
:
client = Aws::Sns::Client.new
response = Aws::Xray::Context.current.overwrite(name: 'sns') do
client.create_topic(...)
end
Multi threaded environment
Tracing context is thread local. To pass current tracing context, copy current tracing context:
Thread.new(Aws::Xray::Context.current.copy) do |context|
Aws::Xray::Context.with_given_context(context) do
# Do something
end
end
Configurations
X-Ray agent location
aws-xray does not send any trace data dby efault. Set AWS_XRAY_LOCATION
environment variable like AWS_XRAY_LOCATION=localhost:2000
or set proper aws-agent location with configuration interface like Aws::Xray.config.client_options = { host: "localhost", port: 2000 }
.
In container environments, we often run xray agent container beside application container.
For that case, pass AWS_XRAY_LOCATION
environment variable to container to specify host and port of xray agent.
docker run --link xray:xray --env AWS_XRAY_LOCATION=xray:2000 my-application
Excluded paths
To avoid tracing health checking requests, use "excluded paths" configuration.
- Environment variable:
AWS_XRAY_EXCLUDED_PATHS=/health_check,/another_check
- Global configuration:
Aws::Xray.config.excluded_paths = ['/health_check', '/another_check', %r{/token/.+}]
Recording application version
aws-xray automatically tries to set application version by reading app_root/REVISION
file.
If you want to set another version, set it with:
# In initialization phase.
Aws::Xray.config.version = 'deadbeef'
Default annotation and metadata
aws-xray records hostname by default.
If you want to record specific annotation in all of your segments, configure like:
Aws::Xray.config.default_annotation = Aws::Xray.config.default_annotation.merge(key: 'value')
Keys must be alphanumeric characters with underscore and values must be one of String or Integer or Boolean values.
For metadata:
Aws::Xray.config. = Aws::Xray.config..merge(key: ['some', 'meaningful', 'value'])
Note: See official document about annotation and metadata in AWS X-Ray.
Error handlers
When aws-xray fails to send segments due to system call errors, it logs errors to stderr by default. If you want to track these errors, for example with Sentry, you can configure your own error handler:
Aws::Xray.config.segment_sending_error_handler = MyCustomErrorHandler.new
The error handler must be callable object and receive 2 arguments and 2 keyword arguments. See Aws::Xray::DefaultErrorHandler
more detail.
Optionaly, aws-xray offers an error handler which integrats with Sentry. To use it:
Aws::Xray.config.segment_sending_error_handler = Aws::Xray::ErrorHandlerWithSentry.new
Development
After checking out the repo, run bin/setup
to install dependencies. 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 tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/taiki45/aws-xray.
License
The gem is available as open source under the terms of the MIT License.