アンチパターン: API プロキシ内で MessageLogging ポリシーを複数回呼び出す

現在、ApigeeApigee ハイブリッドのドキュメントを表示しています。
Apigee Edge のドキュメントを表示する。

Apigee の MessageLogging ポリシーを使用すると、API プロキシのデベロッパーは、カスタム メッセージを Cloud Logging または syslog エンドポイントに記録できます。入力パラメータ、リクエスト ペイロード、レスポンス コード、エラー メッセージ(該当する場合)など、API リクエストに関連するすべての重要な情報をログに記録して、後から参照したりデバッグに活用したりできます。このポリシーではバックグラウンド プロセスを使用してロギングを実行しますが、ポリシーの使用にあたってはいくつかの注意事項があります。

アンチパターン

MessageLogging ポリシーを使用すると、API リクエストと、その API リクエストで発生した問題のデバッグに関する詳細情報を効率的に取得できます。ただし、PostClientFlow 以外のフローでは、同じ API プロキシ内で、同じ MessageLogging ポリシーを複数回使用することや、チャンクに複数の MessageLogging ポリシーのログデータが含まれると、悪影響が生じる可能性があります。これは、Apigee によって MessageLogging ポリシー用に外部エンドポイントへの接続が開かれるためです。ポリシーが TCP 経由で TLS を使用する場合、syslog エンドポイントと同様に、TLS 接続を確立するための追加オーバーヘッドが生じます。

以下に、API プロキシの例を使用してこの仕組みを説明します。

API プロキシ

次の例では、「LogRequestInfo」という名前の MessageLogging ポリシーがリクエスト フロー内に置かれ、「LogResponseInfo」という名前の別の MessageLogging ポリシーがレスポンス フロー内に置かれています。どちらも ProxyEndpoint の PreFlow 内に配置されています。API プロキシがリクエストを受け取るとすぐに、バックグラウンドで LogRequestInfo ポリシーが実行されます。LogResponseInfo ポリシーは、プロキシがターゲット サーバーからレスポンスを受け取った後、API クライアントにレスポンスを返す前に実行されます。この場合、2 つの TLS 接続が確立される可能性があるので、その分だけ多くのシステム リソースが消費されます。

さらに、API プロキシの実行中にエラーが発生した場合にのみ実行される「LogErrorInfo」という名前の MessageLogging ポリシーもあります。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
  ...
<FaultRules>
    <FaultRule name="fault-logging">
        <Step>
            <Name>LogErrorInfo</Name>
        </Step>
    </FaultRule>
</FaultRules>
<PreFlow name="PreFlow">
    <Request>
      <Step>
        <Name>LogRequestInfo</Name>
      </Step>
    </Request>
  </PreFlow>
  <PreFlow name="PreFlow">
    <Response>
      <Step>
        <Name>LogResponseInfo</Name>
      </Step>
    </Response>
  </PreFlow>
  ...
</ProxyEndpoint>

MessageLogging ポリシー

次のポリシー構成の例では、TCP 経由の TLS を使用して、サードパーティのログサーバーにデータが記録されます。同じ API プロキシ内でこのような複数のポリシーが使用される場合、TLS 接続の確立と管理のオーバーヘッドにより、システムメモリや CPU サイクルがより多く占有されるため、大規模なパフォーマンスの問題につながります。MessageLogging を使用して Cloud Logging エンドポイントにログを記録した場合にも、同様の悪影響が発生します。

LogRequestInfo ポリシー

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MessageLogging name="LogRequestInfo">
  <Syslog>
    <Message>[3f509b58 tag="{organization.name}.{apiproxy.name}.{environment.name}"] Weather request for WOEID {request.queryparam.w}.</Message>
    <Host>logs-01.loggly.com</Host>
    <Port>6514</Port>
    <Protocol>TCP</Protocol>
    <FormatMessage>true</FormatMessage>
    <SSLInfo>
        <Enabled>true</Enabled>
    </SSLInfo>
  </Syslog>
  <logLevel>INFO</logLevel>
</MessageLogging>

LogResponseInfo ポリシー

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MessageLogging name="LogResponseInfo">
  <Syslog>
    <Message>[3f509b58 tag="{organization.name}.{apiproxy.name}.{environment.name}"] Status: {response.status.code}, Response {response.content}.</Message>
    <Host>logs-01.loggly.com</Host>
    <Port>6514</Port>
    <Protocol>TCP</Protocol>
    <FormatMessage>true</FormatMessage>
    <SSLInfo>
        <Enabled>true</Enabled>
    </SSLInfo>
  </Syslog>
  <logLevel>INFO</logLevel>
</MessageLogging>

LogErrorInfo ポリシー

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MessageLogging name="LogErrorInfo">
  <Syslog>
    <Message>[3f509b58 tag="{organization.name}.{apiproxy.name}.{environment.name}"] Fault name: {fault.name}.</Message>
    <Host>logs-01.loggly.com</Host>
    <Port>6514</Port>
    <Protocol>TCP</Protocol>
    <FormatMessage>true</FormatMessage>
    <SSLInfo>
        <Enabled>true</Enabled>
    </SSLInfo>
  </Syslog>
  <logLevel>ERROR</logLevel>
</MessageLogging>

影響

  • API プロキシフローでログ エンドポイントへの接続を何度も確立することが原因で、ネットワーク オーバーヘッドが増加します。
  • syslog サーバーが低速であるか、複数の syslog 呼び出しで大量のボリュームを処理できない場合、Message Processor に対するバック プレッシャーが発生して、リクエスト処理が低速になり、大幅なレイテンシや 504 Gateway Timeout エラーが発生する可能性があります。
  • PostClient フロー以外のフローに MessageLogging ポリシーが配置されている場合、情報がログに記録されない可能性があります。これは、MessageLogging ポリシーの実行前になんらかのエラーが発生すると、MessageLogging ポリシーが実行されないためです。

    上記の ProxyEndpoint の例の場合、次の状況では、情報はログに記録されません。

    • リクエスト フロー内の LogRequestInfo ポリシーより前に配置されたいずれかのポリシーが失敗した場合。
      または
    • なんらかのエラー(HTTP 4XX、5XX)によってターゲット サーバーに障害が発生した場合。この状況で正常なレスポンスが返されない場合は、LogResponseInfo ポリシーが実行されません。

    どちらの場合も LogErrorInfo ポリシーが実行され、エラー関連の情報のみがログに記録されます。

ベスト プラクティス

  • プロキシフロー内で、ExtractVariables ポリシーまたは JavaScript ポリシーの 1 つ以上のインスタンスを使用して、コンテキスト変数に記録されるすべてのフロー変数を設定します。これにより、後で実行する MessageLogging ポリシーで使用できるようになります。
  • 無条件に実行される PostClientFlow の中で単一の MessageLogging ポリシーを使用して、必要なすべてのデータをログに記録します。
  • Syslog を使用する場合、syslog サーバーへのメッセージの配信を保証する必要がなく、TLS/SSL の使用が必須ではない場合には、UDP プロトコルを使用します。

MessageLogging ポリシーは、エラー処理など、実際の API 機能から分離されるように設計されています。したがって、リクエスト / レスポンス処理の範囲外である PostClientFlow 内でこのポリシーを呼び出すと、API が成功したかどうかにかかわらず、常にデータがログに記録されます。

次に、PostClientFlow 内で MessageLogging ポリシーを呼び出す例を示します。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 ...
<PostClientFlow>
        <Request/>
        <Response>
            <Step>
                <Name>LogInfo</Name>
            </Step>
        </Response>
</PostClientFlow>
 ...

次に、すべてのデータを記録する「LogInfo」という名前の MessageLogging ポリシーを使用します。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MessageLogging name="LogInfo">
  <Syslog>
    <Message>[3f509b58 tag="{organization.name}.{apiproxy.name}.{environment.name}"] Weather request for WOEID {woeid} Status: {weather.response.code}, Response {weather.response}, Fault: {fault.name:None}.</Message>
    <Host>logs-01.loggly.com</Host>
    <Port>6514</Port>
    <Protocol>TCP</Protocol>
    <FormatMessage>true</FormatMessage>
    <SSLInfo>
        <Enabled>true</Enabled>
    </SSLInfo>
  </Syslog>
  <logLevel>INFO</logLevel>
</MessageLogging>

エラーフローに続く PostClientFlow 内ではレスポンス変数を使用できないため、ExtractVariables ポリシーまたは JavaScript ポリシーを使用して、woeid 変数と weather.response* 変数を明示的に設定することが重要です。

関連情報