すべてのプロダクト
Search
ドキュメントセンター

Function Compute:Tracing Analysis

最終更新日:Aug 30, 2024

このトピックでは、Node.jsランタイム環境でのトレース分析機能について説明します。

背景

Alibaba Cloud Tracing AnalysisはOpenTracing標準を採用しており、オープンソースコミュニティと互換性があります。 Tracing Analysisは、分散アプリケーションの開発者にさまざまな機能を提供します。 たとえば、開発者は分散トレースのクエリと診断、分散トポロジの動的な検出、アプリケーションのパフォーマンスのリアルタイムな要約を行うことができます。

Function ComputeはTracing Analysisと統合します。 Jaeger SDKまたはOpenTelemetryを使用してトレース情報をアップロードし、関数の呼び出しを追跡できます。 Tracing Analysisは、サーバーレスアーキテクチャのパフォーマンスボトルネックの分析と診断に役立ちます。 これにより、サーバーレスシナリオでの開発と診断の効率が向上します。

概要

Tracing Analysisは、Function Computeコンソールで設定できます。 詳細については、「トレース分析の有効化」をご参照ください。

サービスのTracing Analysisを有効にすると、Function Computeはシステムで消費された時間を自動的に記録します。 時間は、コールドスタート時間、イニシャライザ関数の実行時間、及び関数の実行時間を含む。 次の図のシステムスパンの詳細については、「スパン名の説明」をご参照ください。 Tracing Analysis

ビジネス側の関数で消費された時間を記録できます。 たとえば、[カスタムスパンの作成] を使用して、関数内でApsaraDB RDSやApsara File Storage NASなどのサービスにアクセスするのにかかる時間を記録できます。

サンプルコード

Node.jsランタイム環境でのFunction Computeのトレース分析では、OpenTracing仕様のJaeger実装に基づいて、次の方法を使用してカスタムスパンを作成できます。

OpenTelemetry用SDKの使用 (推奨)

Node.jsコードでは、SDK for OpenTelemetryを使用してコードのインストルメンテーションを実行し、データをTracing Analysisに報告できます。 完全なサンプルコードについては、「nodejs-tracing-openTelemetry」をご参照ください。

サンプルコードの詳細を次に示します。

  • プロジェクトディレクトリにpackage.jsonの依存関係ファイルを設定します。

      "dependencies": {
        "@opentelemetry/api": "^1.0.2",
        "@opentelemetry/exporter-jaeger": "0.25.0",
        "@opentelemetry/exporter-zipkin": "0.25.0",
        "@opentelemetry/instrumentation": "0.25.0",
        "@opentelemetry/instrumentation-http": "0.25.0",
        "@opentelemetry/resources": "0.25.0",
        "@opentelemetry/semantic-conventions": "0.25.0",
        "@opentelemetry/sdk-trace-node": "0.25.0",
        "@opentelemetry/sdk-trace-base": "0.25.0"
      }
  • データをTracing Analysisに報告します。

    module.exports.handler = function(event, context, callback)
    {
        tracer = require('./tracer')('fc-tracer',context.tracing.jaegerEndpoint);
    
        var spanContext = contextFromString( context.tracing.openTracingSpanContext);
    
        startMySpan(spanContext);
    
        callback(null,'success');
    }
  • スパンの作成に使用するトレーサーオブジェクトを作成します。

    module.exports = (serviceName,endpoint) => {
      const provider = new NodeTracerProvider({
        resource: new Resource({
          [SemanticResourceAttributes.SERVICE_NAME]: serviceName,
        }),
      });
    
      let exporter = new JaegerExporter({endpoint:endpoint});
    
      provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
      provider.register();
    
      registerInstrumentations({
        instrumentations: [
          new HttpInstrumentation(),
        ],
      });
    
      return opentelemetry.trace.getTracer('http-example');
    };
  • Function ComputeでContextのトレース情報を取得し、トレース情報をSpanContextに変換します。

    function contextFromString(value){
      const arr = value.split(`:`);
      const spanContext={
        traceId:`0000000000000000`+arr[0],
        spanId:arr[1],
        traceFlags:api.TraceFlags.SAMPLED,
        isRemote:true
      }
      return spanContext;
    }
  • トレーサーを作成し、変換されたコンテキストを使用して子スパンを作成します。 スパンは、呼び出しトレースで名前が付けられ、時間が設定された継続的に実行可能なコードスニペットを表します。 スパンに基づいて子スパンを作成することもできます。

    function startMySpan(spanContext){
      var FcSpan=api.trace.wrapSpanContext(spanContext);
      var ctx = api.trace.setSpan(api.ROOT_CONTEXT,FcSpan);
      tracer.startActiveSpan("fc-operation",undefined,ctx,parentSpan => {
        parentSpan.setAttribute("version","fc-v1");
        sleep(150);
        child();
        parentSpan.end()
      })
    }
    
    function child(){
      tracer.startActiveSpan("fc-operation-child",span =>{
        sleep(100);
        span.addEvent("timeout");
        span.end();
      })
    }

JaegerのSDKを使用する

JaegerのSDKを使用して、コードのインストルメンテーションを実行し、データをTracing Analysisに報告できます。 完全なサンプルコードについては、「nodejs-tracing」をご参照ください。

サンプルコードの詳細を次に示します。

  • プロジェクトディレクトリにpackage.jsonの依存関係ファイルを設定します。

    "dependencies": {
      "jaeger-client": "^3.19.0"
    }
  • データをTracing Analysisに報告します。

    module.exports.handler = function(event, context, callback)
    {
      tracer=newTracer(context);
    
      var invokeSpanContext = spanContext.fromString(context.tracing.openTracingSpanContext);
    
      startMySpan(invokeSpanContext);
    
      callback(null,'success')
    }
  • コンテキストのトレース情報に基づいて、トレーサーオブジェクトを作成します。

    function newTracer(context){
      var config = {
        serviceName: 'fc-tracer',
        reporter: {
          // Provide the traces endpoint; this forces the client to connect directly to the Collector and send spans over HTTP
          collectorEndpoint: context.tracing.jaegerEndpoint,
          flushIntervalMs: 10,
        },
        sampler: {
          type: "const",
          param: 1
        },
      };
      var options = {
        tags: {
          'version': 'fc-v1',
        },
      };
      var tracer = initTracer(config, options);
      return tracer
    }
  • SpanContextを変換し、カスタムスパンを作成します。 スパンに基づいて子スパンを作成することもできます。

    function startMySpan(spanContext){
      var parentSpan = tracer.startSpan("fc-operation", {
        childOf: spanContext
      });
      sleep(150);
      child(parentSpan.context())
      parentSpan.finish();
    }
    
    function child(spanContext){
      var childSpan = tracer.startSpan("fc-operation-child", {
        childOf: spanContext
      });
      childSpan.log({event:"timeout"});
      sleep(100);
      childSpan.finish();
    }