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

API プロキシのデベロッパーは Apigee Edge の MessageLogging ポリシーを使用して、カスタム メッセージを 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&quo>t<; standalone="yes"?
Messag>eLo<gging >name=<"L>ogRequestInfo"
  Syslog
    Message[3f509b58 tag="{organization.name}.{apiproxy.name}.{environment.name}"]< Weather> requ<est >for WOEID {request<.quer>ypara<m.w}>./Me<ssage>
    <Hostlogs>-01<.loggly.c>om/Ho<st
    Port65>14/P<ort
    Protoc>olTCP</Protoc>ol
    Fo<rmatMes>sage<true/For>matMe<ssage
  >  S<SLInfo
>   <     Ena>bled<true/Enab>l<ed
    /SSLInfo>
  /Syslog
  logLevelINFO/logLevel
/MessageLogging

LogResponseInfo ポリシー

<?xml version="1.0" encoding="UTF-8&quo>t<; standalone="yes"?
Message>Log<ging n>ame=&<quot;Lo>gResponseInfo"
  Syslog
    Message[3f509b58 tag="{organization.name}.{apiproxy.name}.{environment.name}"] Status: {r<esponse.>statu<s.co>de}, Response {res<ponse>.cont<ent}>./Me<ssage>
    <Hostlogs>-01<.loggly.c>om/Ho<st
    Port65>14/P<ort
    Protoc>olTCP</Protoc>ol
    Fo<rmatMes>sage<true/For>matMe<ssage
  >  S<SLInfo
>   <     Ena>bled<true/Enab>l<ed
    /SSLInfo>
  /Syslog
  logLevelINFO/logLevel
/MessageLogging

LogErrorInfo ポリシー

<?xml version="1.0" encoding="UTF-8&quo>t<; standalone="yes"?
Mess>age<Loggin>g nam<e=">;LogErrorInfo"
  Syslog
    Message[3f509b58 tag="{organization.name}.{apiproxy.name}.{<environm>ent.n<ame}>"] Fault name<: {fa>ult.n<ame}>./Me<ssage>
    <Hostlogs>-01<.loggly.c>om/Ho<st
    Port65>14/P<ort
    Protoc>olTCP</Protoc>ol
    Fo<rmatMes>sage<true/For>matMe<ssage
  >  S<SLInfo
>   <     Ena>bledt<rue/Enabl>e<d
    /SSLInfo
>  /Syslog
  logLevelERROR/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&quo>t; sta<ndalone=">yes"<?
 ...
P>ostClient<Flow
   >     Request/<
   >     Response
   <    >     St<ep
  >             < Name>LogInfo/N<ame
     > <      /Step
   >     /Response
/PostClientFlow
 ...

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

<?xml version="1.0" encoding="UTF-8&quo>t<; standalone="yes"?>
Me<ssageL>oggin<g name=>"LogInfo"
  Syslog
    Message[3f509b58 tag="{organization.name}.{apiproxy.name}.{environment.name}"] Weather request for WOEID {woeid} Status: {weather.response.code}, Resp<onse {we>ather<.res>ponse}, Fault: {fa<ult.n>ame:N<one}>./Me<ssage>
    <Hostlogs>-01<.loggly.c>om/Ho<st
    Port65>14/P<ort
    Protoc>olTCP</Protoc>ol
    Fo<rmatMes>sage<true/For>matMe<ssage
  >  S<SLInfo
>   <     Ena>bled<true/Enab>l<ed
    /SSLInfo>
  /Syslog
  logLevelINFO/logLevel
/MessageLogging

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

関連情報