ECSでのみxray-sdk-goが動かない原因と解消法

# なにをやりたかったのか
- golangでつくってるApplicationにAPMを仕込みたかった
- 環境はECSで動かしているので、親和性を考えてX-Rayを使うことを選んだ

# どんな感じに作った?

- Applicationはこんな感じのものを想定
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318649/477ce059-4346-d578-9ab8-e55dd69a1a64.png)

- パッケージ管理は **mod** を利用
- x-rayは **amazon/aws-xray-daemon** を利用
- ECSでhostの指定は **AWS_XRAY_DAEMON_ADDRESS** を指定
- 具体的なコードはこんな感じ

```golang:main.go
package main

import (
	"github.com/gin-gonic/gin"
	apm "project/apm"
)

// GinRouter is router that API method router.
func main() {
	router := gin.Default()
	
	// helth check
	router.GET("/helth", func(c *gin.Context) {
		apm.TraceSeg(c, "/helth")

		c.JSON(200, gin.H{
				"message": "helth check ok",
		})
	})

	// other URI
    // ...

    router.Run(":8080")
}
```

```golang:apm.go
package main

import (
	"context"
	"github.com/aws/aws-xray-sdk-go/xray"
	_ "github.com/aws/aws-xray-sdk-go/plugins/ecs"
)

func TraceSeg(c context.Context, service string) (*context.Context) {
	ctx, seg := xray.BeginSegment(c, service)
	seg.Close(nil)

	return &ctx
}

func TraceSubSeg(c context.Context, service string) (*context.Context) {
	ctx, subSeg := xray.BeginSubsegment(c, service)
	subSeg.Close(nil)

	return &ctx
}
```

```yaml:task_difinition
version: '2'
services:
    api:
        image: xxxxx:${CI_BUILD_REF}
        mem_limit: xxxxMB
        cpu_shares: xxxx
        ports:
            - "0:8080"
        links:
            - xray-daemon
        environment:
            AWS_REGION: xxxx
            AWS_XRAY_DAEMON_ADDRESS: "xray-daemon:2000"
            SERVICE: xxxxx
        logging:
            driver: "awslogs"
            options:
                awslogs-region: "ap-northeast-1"
                awslogs-group: "xxxxx"
                awslogs-create-group: "true"
    xray-daemon:
        image: amazon/aws-xray-daemon
        hostname: xray-deamon
        mem_limit: xxxxB 
        cpu_shares: xx
        ports:
            - "2000:2000/udp"
        environment:
            AWS_REGION: xxxxx
```

# どうなったか
- localでテストしたとき　→動いた
- docker on EC2 →動いた
- ECS →動かなかった

    ```
    [Trace] Beginning segment named /helth 
    [Trace] Closing segment named /helth 
    [Error] write udp 127.0.0.1:52419->127.0.0.1:2000: write: connection refused 
    ```
※ ENVやprocessには変数は受け渡されていた

```
# EC2で動いているdocker processに変数が渡されているかの確認
[ec2-user@ip-172-28-22-74 ~]$ sudo sed "s/\x0/\n/g" /proc/5351/environ 
~
AWS_XRAY_DAEMON_ADDRESS=xray-daemon:2000 
~

# run している containerから変数は見れるか
root@559381b52506:/# env 
GOLANG_VERSION=1.12.1 
~
AWS_XRAY_DAEMON_ADDRESS=xray-daemon:2000 
~
```

# なぜ動かない？
AWSに問い合わせをしたところ、 **AWS X-Ray SDK for Go の 1.0.0-rc.8 より古いバージョンでは同様の事象が発生しえる** とのこと

# 確認してみる
modを利用してバージョン管理しているので、modの中身を見てみる

```
$ cat go.mod | grep xray 
github.com/aws/aws-xray-sdk-go v0.9.4 
```
→ 「v0.9.4」を利用している

go get -u でバージョンアップしてみる

```
$ go clean -cache
$ go get -u github.com/aws/aws-xray-sdk-go
↓
$ go build
$ grep xray go.mod 
        github.com/aws/aws-xray-sdk-go v0.9.4
```
→　変わらない...

git commitを確認する

```
$ cd $GOPATH/src/github.com/aws/aws-xray-sdk-go
$ git log -1
commit 5ffa743a8b8db87a9d4449c2f63fe95a4a53a8c5 (HEAD -> master, origin/master, origin/HEAD)
Author: Christopher Radek <cjradek@gmail.com>
Date:   Tue Apr 9 13:59:20 2019 -0700

    upkeep: adds -race to travis test scripts (#104)
```
<img width="1105" alt="aws_aws-xray-sdk-go__AWS_X-Ray_SDK_for_the_Go_programming_language_.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318649/b5aae3a7-4fdc-2727-2ea3-a5a6a8cb0f88.png">
→　一致した。ということは最新バージョンは取れているはず。

# 何故modで「1.0.0-rc.x」が指定されないのか
A. マイナーバージョンだから

マイナーバージョンを利用する場合は直接modを編集してあげる必要がある模様

```
[before]
$ cat go.mod | grep xray 
github.com/aws/aws-xray-sdk-go v0.9.4 

[after]
$ cat go.mod | grep xray 
github.com/aws/aws-xray-sdk-go v1.0.0-rc.11

# こんな感じに動く
$ go build
go: finding github.com/aws/aws-xray-sdk-go v1.0.0-rc.11
go: finding github.com/aws/aws-sdk-go v1.17.12
go: finding github.com/stretchr/testify v1.1.4
go: finding github.com/davecgh/go-spew v0.0.0-20160907170601-6d212800a42e
go: finding github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0
go: finding github.com/DATA-DOG/go-sqlmock v1.2.0
go: finding golang.org/x/text v0.0.0-20190306152657-5d731a35f486
go: finding golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95
go: finding golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e
go: downloading github.com/aws/aws-xray-sdk-go v1.0.0-rc.11
go: extracting github.com/aws/aws-xray-sdk-go v1.0.0-rc.11
```

# まとめ
- xray-sdk-goを利用したAPMをECS上に乗せるときはバージョンに気をつけよう
- modを利用している場合は手動でマイナーバージョンに切り替えよう