コンテンツにスキップ

可観測性 (Observability)

はじめに

Copilot では、Manifest にて以下のように設定することにより、Service のトレース収集を設定することができます。

observability:
  tracing: awsxray

Request-Driven Web Service の場合、Copilot は App Runner に組み込まれたトレース設定を有効にします。

Load Balanced Web ServiceBackend ServiceWorker Service の場合、Copilot は AWS OpenTelemetry Collector をサイドカーとしてデプロイします。

Service のインストルメント化

テレメトリーデータを送信するための Service のインストルメント化 (訳注: 計装、 アプリケーションに計測のためのコードを追加すること) は、各言語毎の SDKで行います。サンプルは、OpenTelemetry のドキュメントでサポートされている各言語で提供されています。また、AWS Distro for OpenTelemetry が提供するドキュメントやサンプルをご覧いただいたけます。

アプリケーションの例

これは、すべてのエンドポイントがインストルメント化された Express.js による小さな Service です。開始するには、必要な依存関係をインストールします。

npm install express \
    @opentelemetry/api \
    @opentelemetry/sdk-trace-node \
    @opentelemetry/auto-instrumentations-node \
    @opentelemetry/exporter-trace-otlp-grpc \
    @opentelemetry/id-generator-aws-xray \
    @opentelemetry/propagator-aws-xray

次に、以下を tracer.js に保存します。

tracer.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const { BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base");
const { Resource } = require("@opentelemetry/resources");
const { trace } = require("@opentelemetry/api");
const { AWSXRayIdGenerator } = require("@opentelemetry/id-generator-aws-xray");
const { SemanticResourceAttributes } = require("@opentelemetry/semantic-conventions");
const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
const { AWSXRayPropagator } = require("@opentelemetry/propagator-aws-xray");
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-grpc");
const { getNodeAutoInstrumentations } = require("@opentelemetry/auto-instrumentations-node");

module.exports = (serviceName) => {
  const tracerConfig = {
    idGenerator: new AWSXRayIdGenerator(),
    instrumentations: [getNodeAutoInstrumentations()],
    resource: Resource.default().merge(
      new Resource({
        [SemanticResourceAttributes.SERVICE_NAME]: serviceName,
      })
    ),
  };

  const tracerProvider = new NodeTracerProvider(tracerConfig);
  const otlpExporter = new OTLPTraceExporter();

  tracerProvider.addSpanProcessor(new BatchSpanProcessor(otlpExporter));
  tracerProvider.register({
    propagator: new AWSXRayPropagator(),
  });

  return trace.getTracer("example-instrumentation");
};

tracer.js は、OpenTelemetry プロトコルを使用して Express.js サーバからトレースを自動的にエクスポートするように構成されたトレーサーを返す関数をエクスポートします。この関数を app.js で使用し、Service 名として copilot-observability を渡します。

app.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
'use strict';
const tracer = require('./tracer')('copilot-observability');
const app = require("express")();
const port = 8080;

app.get("/", (req, res) => {
    res.send("Hello World");
});

app.listen(port, () => {
    console.log(`Listening for requests on http://localhost:${port}`);
});

これで、Copilot を使用してこの Service をデプロイし、Manifest で observability を有効にすると、この Service によって生成されたトレースを確認できます

トレースログのインクルード

Attention

このセクションは Request-Driven Web Services には適用されません。

Copilot はコレクターで ECS resource detector を構成するため、Service によって生成されたトレースには、サービスがログを記録しているロググループが含まれます。 ログにトレース ID を含めると、トレースに関連するログが X-Ray でトレースと一緒に表示されます。これは、トレースを理解しデバッグするのに便利です。

X-Ray は OpenTelemetry とは少し異なる形式トレース ID をフォーマットするので、OpenTelemetry のトレース ID を取得して X-Ray 用にフォーマットするには、このような関数が必要になります。

function getXRayTraceId(span) {
    const id = span.spanContext().traceId;
    if (id.length < 9) {
        return id;
    }

    return "1-" + id.substring(0, 8) + "-" + id.substring(8);
}

次に、X-Ray トレース ID をログに次のように含めることができます。

console.log("[%s] A useful log message", getXRayTraceId(span));

CloudWatch でトレースを表示する

Service をインストルメント化し Copilot を使用してデプロイすることで、Service のトレースを表示する準備が整いました。Service のインストルメント化の方法によっては、AWSコンソールにトレースが表示される前に、数回リクエストを送信する必要があります。

まず、CloudWatch のコンソールを開き、メニューの X-Ray トレース/サービスマップ をクリックします。ここでは、相互作用しているサービスのビジュアルマップを見ることができます。 X-Ray Service Map

次に、メニューの X-Ray トレース/トレース をクリックし、リストからトレースを選択すると、特定のトレースの詳細を表示することができます。

この例では、js-copilot-observability という Service が内部で Express.js のミドルウェアを実行し、AWS SDK for Javascript を使って s3:listBuckets を呼び出していることが分かります。 X-Ray Trace Details