今更X-Rayに入門してみた

# はじめに
X-Ray使うとApplication中心に各サービス間の通信をトレースあれこれできていいと聞いたが、どういうものか?仕組みがピンと来てなかったのでチュートリアルをやったよ、というチュートリアル。

# [AWS X-Ray とは何ですか](http://docs.aws.amazon.com/ja_jp/xray/latest/devguide/aws-xray.html)

- X-Ray SDK (Java/Node.js/Python/Go/.NET)を自分のアプリケーションに組み込んで、
- X-Ray デーモンと通信すると、
- GUIでかっこいいService mapとかTrace見れる、

やつ。

# チュートリアルやってみた
まんま[AWS X-Rayの開始方法](http://docs.aws.amazon.com/ja_jp/xray/latest/devguide/xray-gettingstarted.html)をやっただけです... まだの人はちゃんと読もう、公式チュートリアル!

流れとして、

- EBでjava web server立てて、
- 必要なrole権限をiamから設定して、
- EBにサンプルX-RayアプリDeployすると、
- X-RayでかっこいいService map/traceが見れる

というもの。
ここで手順詳細書こうとするとほぼ↑のコピペになるので簡単に記載します。
詳細はそちらのチュートリアルページをご確認ください。

(なお、最初は[【新機能】AWS X-Rayを試してみた #reinvent](https://dev.classmethod.jp/cloud/aws/aws-x-ray/)にあるように、x-ray topからサンプルアプリをcloud formation経由で作ろうとしたが、`No Solution Stack named '64bit Amazon Linux 2017.03 v4.3.0 running Node.js' found.`とか言われて諦めた。)

## 1. EB立てる
javaのweb appを立てる。(図は3.のdeployもした後)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26677/2dcff00e-01d2-c1c5-f10f-21e9fd770247.png)



## 2.EBのiam role設定
EBとともに作成された`aws-elasticbeanstalk-ec2-role`とかに`AWSXrayFullAccess/AmazonS3FullAccess/AmazonDynamoDBFullAccess`をアタッチ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26677/e38c7f05-a636-1517-db13-68a9c0aef3fd.png)



## 3. サンプルゲーム?をdeploy
[eb-java-scorekeep-xray-gettingstarted-v1.3.zip](https://github.com/awslabs/eb-java-scorekeep/releases/download/xray-gs-v1.3/eb-java-scorekeep-xray-gettingstarted-v1.3.zip)をDLしてdeploy
(1.の図参照)

## 4. アプリにアクセス
session作って、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26677/b6ef3a2a-fdea-4858-c8c3-8a2576fb908a.png)

OXゲーム?...
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26677/4ba13a0a-5999-3b51-84eb-46f9ab8a7ff5.png)

EBのurlにアクセスするとこんなアプリができるので、チュートリアルどおりゲーム?を遊んでみてrequestを生成。

## 5. X-Ray開いてみる
Sevice map見えたり、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26677/1bdc26c3-1380-ef6f-6a45-89713131e9fc.png)
それぞれのnode開くとdetail見えたり、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26677/29425181-fa45-4cba-fb2d-a80af415b0a4.png)
traceも見えたりする。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26677/188c27bb-39c1-9b76-4746-328a72212604.png)

# 仕組みについて
## X-Ray SDKの呼び出し
そのままチュートリアル記載の通りですが、

```src/main/java/scorekeep/WebConfig.java
...
import com.amazonaws.xray.AWSXRay;
import com.amazonaws.xray.AWSXRayRecorderBuilder;
import com.amazonaws.xray.javax.servlet.AWSXRayServletFilter;
import com.amazonaws.xray.plugins.EC2Plugin;
import com.amazonaws.xray.plugins.ElasticBeanstalkPlugin;
import com.amazonaws.xray.strategy.sampling.LocalizedSamplingStrategy;
...
@Configuration                                                            
public class WebConfig {                                                  
  private static final Logger logger = LoggerFactory.getLogger(WebConfig.class);
                                                                          
  @Bean                                                                   
  public Filter TracingFilter() {                                         
    return new AWSXRayServletFilter("Scorekeep");                         
  }                                                                                                                                              
...
  static {                                                                
    AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard().wit
                                                                          
    URL ruleFile = WebConfig.class.getResource("/sampling-rules.json");   
    builder.withSamplingStrategy(new LocalizedSamplingStrategy(ruleFile));
...

```
という感じにSDKをimportして、`sampling-rules.json`記載の条件でtraceするくだりを入れておきます。
でその中身は、「/api/以下のPOSTをすべて」や「/api/session/以下のGETを5%で」など記載があります。

```src/main/resources/sampling-rules.json
{
  "version": 1,
  "rules": [
    {
      "description": "Resource creation.",
      "service_name": "*",
      "http_method": "POST",
      "url_path": "/api/*",
      "fixed_target": 1,
      "rate": 1.0
    },
    {
      "description": "Session polling.",
      "service_name": "*",
      "http_method": "GET",
      "url_path": "/api/session/*",
      "fixed_target": 0,
      "rate": 0.05
    },
...
```

基本的に他の言語も同様で大本でSDKでのtraceを宣言しておいて、あとは`sampling-rules.json`の条件に従う。という形になっています。
[X-Ray SDK for Go の設定](http://docs.aws.amazon.com/ja_jp/xray/latest/devguide/xray-sdk-go-configuration.html)
[X-Ray SDK for Python の設定](http://docs.aws.amazon.com/ja_jp/xray/latest/devguide/xray-sdk-python-configuration.html)
など。

## [X-Ray デーモン](http://docs.aws.amazon.com/ja_jp/xray/latest/devguide/xray-daemon.html)
udp 2000 portをlistenするもので、linuxのrpmなどは公式からDLできます。
また、EBの場合には`XrayEnabled`オプションを有効いすればあがるようです。
だいたいweb appと同じEC2なりEBなりインスタンスにいるのかな?

# 終わりに
思ったこととして、

- アプリにlogger?/tracer?埋め込むのでパフォーマンス影響どのくらいあるのだろう?
- 自作X-Ray SDK?を作るにはどの程度気楽なのだろうか?
    - SDKに対応言語がない場合に
    - applicationで直接tracer仕込むのちょっとやだというか、
    - 原理的にはX-Rayデーモンに直接request投げつければいいのだからlogパースして送るなりするbatch書いたらうごくのか?

とちゃんと使いこなすにはまだまだお勉強が必要そうで。
[AWS re:invent 2017: Deep-Dive for AWS X-Ray (DEV402)](http://newsvideo.su/tech/video/233051)
[AWS Summit Series 2017: London - Deep Dive: AWS X-Ray](http://newsvideo.su/tech/video/227832)

以上。