概要
SQSを中継したAWSサービス間の連携・分散トレーシングの取得方法についてまとめ
サービス間を中継するSQSの監視を実施することによって以下のことが実現できます
- プロダクトで利用しているAWSサービス間の連携をEntity Mapとして可視化
- 各サービスごとの処理速度を可視化(Transaction)
前提
アプリケーションの使用言語
TypeScript
アプリケーションの構成
ECS -> SQS -> Lambda
上記の構成はあくまで例であり、
Lambda -> SQS -> Lambdaのような構成でも今回紹介する方法は実施可能です。
ECSではAPM監視・分散トレーシングの設定済み
LambdaではnewrelicライブラリのsetLambdaHandlerで監視設定を導入済み
newrelicライブラリのバージョンは
10.1.2
LambdaのトリガーとしてSQSが設定されている
SQS送信側のコード
AWS SDKでSQS送信時に、newrelicライブラリ経由で取得した情報をmessageAttribute
属性として付与します
ここで必要な手順は2つです
① NewRelic上で分散トレーシングを実施するため、トレース情報を送信する
② 上記で取得したトレース情報(Traceparentなど)をSQS登録時にパラメータとして持たせる
まず、①を実施し、②で使用するパラメータを返す関数を作成します
getMessageAttributes(): AWS.SQS.MessageBodyAttributeMap {
const currentHeaders: Record<
string,
string | number | string[] | undefined
> = {};
// newrelicライブラリを用いて分散トレーシングを実施する上で必要な情報をNewRelicに送信
newrelic.getTransaction().insertDistributedTraceHeaders(currentHeaders);
// 上記で取得した情報をSQSに送信するデータ用に加工する
Object.entries(currentHeaders).forEach((header) => {
if (typeof header[1] === 'string') {
this.attributes[header[0]] = {
StringValue: header[1] || '',
DataType: 'String',
};
}
});
return this.attributes;
}
SQSにキューを登録する処理では、上記で取得したトレース情報をmessageAttributes
として設定します(②の手順)
{
id: id,
body: body,
messageAttributes: getSQSMessageAttributes(),
}
SQS受信側のコード
受信したSQS EventからmessageAttributesを取得し、newrelicライブラリを用いて、SQSのヘッダ情報取得処理を実装します。
// event: SQSEvent
const previousHeader: {[key: string]: string} = {};
Object.keys(event['Records'][0].messageAttributes).forEach(key => {
previousHeader[key] = String(event['Records'][0].messageAttributes[key].stringValue);
});
newrelic.getTransaction().acceptDistributedTraceHeaders('Queue', previousHeader);
分散トレーシングの確認
実装・デプロイが完了した後、NewRelicの管理画面から分散トレーシングが取得できているかを確認します。
① NewRelicのメニューから以下のページを確認する
APM & Services > ECSサービス > Distributed Tracing
② SQSキューを登録する処理のパスを選択する
ECSサービスがSQSを経由してLambda関数を呼び出している図が確認できればOK!
参考・関連記事