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

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

アンチパターン

MessageLogging ポリシーは、API リクエストに関する詳細情報を参照して、API リクエスト関連の問題のデバッグに活用するための効率的な手段となります。しかし、PostClientFlow 以外のフローにおいて同一の API プロキシ内で、同一の MessageLogging ポリシーを複数回使用したり、複数の MessageLogging ポリシーを使用してデータをチャンク形式で記録したりすると、悪影響が生じる可能性があります。これは、Apigee Edge では、MessageLogging ポリシーを実行する場合に外部の syslog サーバーへの接続を開くためです。このとき、ポリシーが TCP 上で TLS を使用する場合、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>
    

Message Logging ポリシー

次の例のポリシー構成では、TCP 上で TLS を使用して、データがサードパーティ製のログサーバーに記録されます。このようなポリシーが複数あり、すべて同一の API プロキシ内で使用される場合は、TLS 接続を確立し、管理するためのオーバーヘッドによってシステムメモリや CPU サイクルがより多く占有され、大規模なパフォーマンス問題につながります。

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 ゲートウェイ タイムアウト エラーが生じる可能性があります。
  • Private Cloud のセットアップではファイル ロギングが使用されるため、Message Processor によって同時に開かれるファイル記述子の数が増加します。
  • PostClient 以外のフロー内に MessageLogging ポリシーが配置されている場合、情報がログに記録されなくなる可能性があります。MessageLogging ポリシーを実行する前になんらかの障害が発生した場合、このポリシーは実行されなくなるためです。

    前述の ProxyEndpoint の例では、次の状況下では情報はログに記録されません。

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

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

ベスト プラクティス

  • ExtractVariables ポリシーまたは JavaScript ポリシーを使用して、記録するすべてのフロー変数を設定し、これらの変数が MessageLogging ポリシーで使用されるようにします。
  • PostClientFlow は無条件に実行されるため、このフロー内で単一の MessageLogging ポリシーを使用して、必要なすべてのデータを記録します。
  • 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* 変数を明示的に設定することが重要です。

関連情報