yarxyarx creates a slim wrapper around the AWS SDK for Go that facilitates instrumentation with the AWS X-Ray SDK for Go without needing to make extensive changes to your code. Unlike some of the other platforms with X-Ray support, like python, integrating X-Ray into Go code can be a pain. A couple of lines of code are all you need to add X-Ray's monkey-patches in python. In Go, though, you need to call specific versions of AWS SDK APIs, wrap your HTTP clients, change your incoming HTTP handlers, and use X-Ray's SQL() function instead of sql.Open(). If you didn't keep all this in mind during development, you'll be fighting an uphill battle to get X-Ray traces out of your AWS applications. To make this easier, yarxyarx implements several "hooks" that are transparently added to your code using wrapknish. wrapknish generates wrapper packages with an identical API to the original, and allows you to swap out specific implementations as needed. In our case, we hook several things:
net/http
's HTTP client type and functionsgolang.org/x/net/context/ctxhttp
's context-ful functionsgithub.com/aws/aws-lambda-go/lambda
's Lambda handler initialization (in order to store the context transparently)github.com/aws/aws-sdk-go/aws/session
's session initialization (in order to wrap newly created service clients with X-Ray)- the APIs of each service client under
github.com/aws/aws-sdk-go/service/
For service client APIs, like s3
's ListBuckets()
, there are a lot of overrides we need to make. For each API, we need to make both the WithContext()
version (i.e., s3.ListBucketsWithContext()
) and the context-less version (s3.ListBuckets()
) see the X-Ray segment context. The overrides themselves are generated by the generate_api_context_go.py
script; the created hooks are fed into wrapknish to create the final package. When this is done, you can just replace your AWS service import paths like this:
import "github.com/aws/aws-sdk-go/service/s3"
becomes
import "xray_github.com/aws/aws-sdk-go/service/s3"
and X-Ray will trace your S3 actions without needing to make any other changes.
Obviously, you'll need the AWS SDK for Go:
go get github.com/aws/aws-sdk-go
yarxyarx runs wrapknish in order to create the hooked APIs. You need to have wrapknish installed somewhere in your $PATH.
To compile the wrapped code, you will also need the X-Ray SDK for Go:
go get github.com/aws/aws-xray-sdk-go
git clone https://github.com/guardicore/yarxyarx.git
cd yarxyarx
./generate_xray_hooks
The generated hooked packages will be under ./generated_pkgs
. Import these instead of the regular HTTP/AWS SDK packages and you're good to go.