X-Ray SDK for Node.js で注釈とメタデータを追加する - Node.js

# X-Ray SDK for Node.js で注釈とメタデータを追加する

X-Ray SDK for Node.js を使用してセグメントに注釈とメタデータを追加してみました。

https://docs.aws.amazon.com/ja_jp/xray/latest/devguide/xray-sdk-nodejs-segment.html


# 利用するアプリケーション

アプリケーションは以下のものを利用させてもらいました。

https://dev.classmethod.jp/articles/fargate-x-ray/

ちなみに ECS CLI を初めて利用しました。


# ソースコードの修正

## service-a

こちらは、注釈は既に存在していましたので、メタデータを追加します。

```js:/aws-xray-fargate/src/service-a/server.js
var XRay = require('aws-xray-sdk');
var AWS = XRay.captureAWS(require('aws-sdk'));
var http = XRay.captureHTTPs(require('http'));

const express = require('express');
var bodyParser = require('body-parser');
var queryString = require('querystring');

// Constants
const PORT = 8080;
const apiCNAME = process.env.API_CNAME || 'localhost';

// App
const app = express();

XRay.config([XRay.plugins.ECSPlugin]);
XRay.middleware.enableDynamicNaming();

app.use(bodyParser.urlencoded({extended: false}));
app.use(XRay.express.openSegment('service-a'));

app.get('/health', function(req, res) {
  res.status(200).send("Healthy");
});

app.get('/', function(req, res) {
  var seg = XRay.getSegment();
  seg.addAnnotation('service', 'service-b-request');　// 注釈
  seg.addMetadata('custom', 'value'); // メタデータ追加

  var reqData = queryString.stringify(req.body);

  var options = {
    host: apiCNAME,
    port: '80',
    path: '/create',
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'Content-Length': Buffer.byteLength(reqData)
    }
  };
```

## service-b

こちらは、注釈とメタデータを追加しています。

```js:/aws-xray-fargate/src/service-b/server.js
var XRay = require('aws-xray-sdk');
var AWS = XRay.captureAWS(require('aws-sdk'));

const express = require('express');

// Constants
const PORT = 8080;

// App
const app = express();

XRay.config([XRay.plugins.ECSPlugin]);
XRay.middleware.enableDynamicNaming();

app.use(XRay.express.openSegment('service-b'));

function randomIntInc(low, high) {
  return Math.floor(Math.random() * (high - low + 1) + low);
}

function sleep(callback) {
  var now = new Date().getTime();
  while (new Date().getTime() < now + randomIntInc(0, 1000)) { /* */ }
  callback();
}

app.get('/health', function(req, res) {
  res.status(200).send("Healthy");
});

app.post('/create', function(req, res) {
  var seg = XRay.getSegment();
  seg.addAnnotation('operation', 'create'); // 注釈
  seg.addMetadata('custom', 'value'); // メタデータ
  
  res.setHeader('Content-Type', 'application/json');

  var r = randomIntInc(1, 10)
  var st = 0;
  if (r % 2 == 0) {
    st = 200;
  } else {
    st = 403;
  }

  var data = {
    request: randomIntInc(1, 10000),
    status: st,
    time: new Date().getTime()
  };

  for (var i = 0; i < 5; i++) {
    sleep(function() {});
  }

  if (st == 200) {
      res.json(data);
  } else {
    res.status(st).send(data);
  }

});

app.use(XRay.express.closeSegment());

app.listen(PORT);
console.log('Running on http://0.0.0.0:' + PORT);
```

# 結果確認

## 未加工データ(Raw データ)

未加工データを確認してみます。

![スクリーンショット 2024-04-12 0.15.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/ade45555-ea41-7ec5-05a5-010a5ab6082c.png)

annotations（注釈）と metadata（メタデータ）を確認できました。

```json
{
    "Id": "1-6617f962-0fead41e32caf8146f72004c",
    "Duration": 0.056,
    "LimitExceeded": false,
    "Segments": [
        {
            "Id": "361d36665fae1848",
            "Document": {
                "id": "361d36665fae1848",
                "name": "xray-fargate-b-alb-2033835677.ap-northeast-1.elb.amazonaws.com",
                "start_time": 1712847202.793,
                "trace_id": "1-6617f962-0fead41e32caf8146f72004c",
                "end_time": 1712847202.795,
                "parent_id": "c76cdde33fbe28a9",
                "http": {
                    "request": {
                        "url": "http://xray-fargate-b-alb-2033835677.ap-northeast-1.elb.amazonaws.com/create",
                        "method": "POST",
                        "user_agent": "",
                        "client_ip": "54.199.245.177",
                        "x_forwarded_for": true
                    },
                    "response": {
                        "status": 200
                    }
                },
                "aws": {
                    "ecs": {
                        "container": "ip-10-0-29-139.ap-northeast-1.compute.internal"
                    },
                    "xray": {
                        "package": "aws-xray-sdk",
                        "sdk_version": "3.6.0",
                        "sdk": "X-Ray for Node.js"
                    }
                },
                "annotations": {
                    "operation": "create"
                },
                "metadata": {
                    "default": {
                        "custom": "value"
                    }
                },
                "service": {
                    "name": "unknown",
                    "version": "unknown",
                    "runtime": "node",
                    "runtime_version": "v8.17.0"
                },
                "origin": "AWS::ECS::Container"
            }
        },
        {
            "Id": "55a67bb023274b30",
            "Document": {
                "id": "55a67bb023274b30",
                "name": "xray-fargate-a-alb-958764649.ap-northeast-1.elb.amazonaws.com",
                "start_time": 1712847202.749,
                "trace_id": "1-6617f962-0fead41e32caf8146f72004c",
                "end_time": 1712847202.805,
                "http": {
                    "request": {
                        "url": "http://xray-fargate-a-alb-958764649.ap-northeast-1.elb.amazonaws.com/",
                        "method": "GET",
                        "user_agent": "ApacheBench/2.3",
                        "client_ip": "126.89.102.137",
                        "x_forwarded_for": true
                    },
                    "response": {
                        "status": 200
                    }
                },
                "aws": {
                    "ecs": {
                        "container": "ip-10-0-13-28.ap-northeast-1.compute.internal"
                    },
                    "xray": {
                        "package": "aws-xray-sdk",
                        "sdk_version": "3.6.0",
                        "sdk": "X-Ray for Node.js"
                    }
                },
                "annotations": {
                    "service": "service-b-request"
                },
                "metadata": {
                    "default": {
                        "custom": "value"
                    }
                },
                "service": {
                    "name": "unknown",
                    "version": "unknown",
                    "runtime": "node",
                    "runtime_version": "v8.17.0"
                },
                "origin": "AWS::ECS::Container",
                "subsegments": [
                    {
                        "id": "c76cdde33fbe28a9",
                        "name": "xray-fargate-b-alb-2033835677.ap-northeast-1.elb.amazonaws.com",
                        "start_time": 1712847202.749,
                        "end_time": 1712847202.805,
                        "http": {
                            "request": {
                                "url": "http://xray-fargate-b-alb-2033835677.ap-northeast-1.elb.amazonaws.com/create",
                                "method": "POST"
                            },
                            "response": {
                                "status": 200,
                                "content_length": 50
                            }
                        },
                        "namespace": "remote"
                    }
                ]
            }
        }
    ]
}
```

## service-a

![スクリーンショット 2024-04-12 0.13.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/b1374c57-f8d1-5a2c-3474-897401301da0.png)

![スクリーンショット 2024-04-12 0.13.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/dd14aece-606b-0e31-538c-57ef6aca6cdc.png)

## service-b

![スクリーンショット 2024-04-12 0.12.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/15c33dfa-aca4-1a54-c09e-b652fa938601.png)

![スクリーンショット 2024-04-12 0.12.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/f7dcc4cd-c11c-8485-1079-ba2127932984.png)


# その他

ログのところが、There was an error while making a request to StartQuery となっているが、特定の AWS サービスからのログはここに表示されません。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/deploy_servicelens_CloudWatch_agent_logintegration.html

*`SDK for Java は、一連の標準アプリケーションログ記録フレームワークと CloudWatch Logs のネイティブサポートの両方をサポートします。次のステップを完了する前に、 の標準セットアップを完了しておく必要がありますAWS X-Ray SDK for Java
サポートされているランタイムは、Amazon EC2、CloudWatch Container Insights が有効な Amazon EKS、および Lambda です。`*