レコメンデーションサービス

このサービスは、ユーザーが閲覧中の既存の商品 ID に基づいて、おすすめ商品のリストを取得する役割を担います。

レコメンデーションサービスのソースコード

自動計装

この Python ベースのサービスは、Python 用の OpenTelemetry 自動計装を利用しています。 これは opentelemetry-instrument Python ラッパーを活用してスクリプトを実行することで実現されています。 サービスの DockerfileENTRYPOINT コマンドで設定できます。

ENTRYPOINT [ "opentelemetry-instrument", "python", "recommendation_server.py" ]

トレース

トレースの初期化

OpenTelemetry SDK は __main__ コードブロックで初期化されます。 このコードはトレーサープロバイダーを作成し、使用するスパンプロセッサーを設定します。 エクスポートエンドポイント、リソース属性、サービス名は、環境変数に基づいて OpenTelemetry 自動計装によって自動的に設定されます。

tracer = trace.get_tracer_provider().get_tracer("recommendation")

自動計装されたスパンへの属性の追加

自動計装されたコードの実行中に、コンテキストから現在のスパンを取得できます。

span = trace.get_current_span()

スパンへの属性の追加は、スパンオブジェクトの set_attribute を使用して行います。 ListRecommendations 関数では、スパンに属性が追加されます。

span.set_attribute("app.products_recommended.count", len(prod_list))

新しいスパンの作成

新しいスパンは、OpenTelemetry Tracer オブジェクトの start_as_current_span を使用して作成し、アクティブなコンテキストに配置できます。 with ブロックと組み合わせて使用すると、ブロックの実行が終了したときにスパンは自動的に終了します。 これは get_product_list 関数で行われています。

with tracer.start_as_current_span("get_product_list") as span:

メトリクス

メトリクスの初期化

OpenTelemetry SDK は __main__ コードブロックで初期化されます。 このコードはメータープロバイダーを作成します。 エクスポートエンドポイント、リソース属性、サービス名は、環境変数に基づいて OpenTelemetry 自動計装によって自動的に設定されます。

meter = metrics.get_meter_provider().get_meter("recommendation")

カスタムメトリクス

現在利用可能なカスタムメトリクスは以下のとおりです。

  • app_recommendations_counter:サービス呼び出しごとのレコメンデーション商品数の累積カウント

自動計装メトリクス

以下のメトリクスは、自動計装を通じて利用可能です。 これは、レコメンデーションサービスの Docker イメージをビルドする際に opentelemetry-bootstrap の一部としてインストールされる opentelemetry-instrumentation-system-metrics によって提供されます。

  • runtime.cpython.cpu_time
  • runtime.cpython.memory
  • runtime.cpython.gc_count

ログ

ログの初期化

OpenTelemetry SDK は __main__ コードブロックで初期化されます。 以下のコードは、バッチプロセッサー、OTLP ログエクスポーター、およびロギングハンドラーを持つロガープロバイダーを作成します。 最後に、アプリケーション全体で使用するロガーを作成します。

logger_provider = LoggerProvider(
    resource=Resource.create(
        {
            'service.name': service_name,
        }
    ),
)
set_logger_provider(logger_provider)
log_exporter = OTLPLogExporter(insecure=True)
logger_provider.add_log_record_processor(BatchLogRecordProcessor(log_exporter))
handler = LoggingHandler(level=logging.NOTSET, logger_provider=logger_provider)

logger = logging.getLogger('main')
logger.addHandler(handler)

ログレコードの作成

ロガーを使用してログを作成します。 使用例は ListRecommendations 関数と get_product_list 関数にあります。

logger.info(f"Receive ListRecommendations for product ids:{prod_list}")

ご覧のとおり、初期化の後は、標準的な Python と同じ方法でログレコードを作成できます。 OpenTelemetry ライブラリは各ログレコードにトレース ID とスパン ID を自動的に付加し、これによりログとトレースの相関が可能になります。

注意事項

Python 用のログはまだ実験的であり、変更が加えられる可能性があります。 このサービスの実装は Python ログの例に従っています。