Antipattern:在 API Proxy 中多次叫用 MessageLogging 政策

您目前查看的是 ApigeeApigee Hybrid 說明文件。
查看 Apigee Edge 說明文件。

API Proxy 開發人員可透過 Apigee 的 MessageLogging 政策,將自訂訊息記錄到 Cloud Logging 或 Syslog 端點。與 API 要求相關的重要資訊 (例如輸入參數、要求酬載、回應代碼、錯誤訊息 (如有) 等),都可以記錄下來,供日後參考或進行偵錯。雖然這項政策會使用背景程序執行記錄作業,但使用時仍須注意以下事項。

反模式

MessageLogging 政策可有效取得 API 要求的相關資訊,並偵錯 API 要求遇到的任何問題。不過,在 PostClientFlow 以外的流程中,如果多次使用相同的 MessageLogging 政策,或有多個 MessageLogging 政策在同一個 API Proxy 中記錄資料區塊,可能會造成不良影響。這是因為 Apigee 會為 MessageLogging 政策開啟與外部端點的連線。如果政策使用透過 TCP 的 TLS (如系統記錄端點),建立 TLS 連線時會產生額外負擔。

讓我們透過範例 API Proxy 加以說明。

API Proxy

在下列範例中,名為「LogRequestInfo」的 MessageLogging 政策會放在「要求」流程中,而名為「LogResponseInfo」的另一個 MessageLogging 政策則會新增至「回應」流程。兩者都位於 ProxyEndpoint PreFlow 中。API Proxy 收到要求後,LogRequestInfo 政策就會在背景執行,而 LogResponseInfo 政策則會在 Proxy 收到目標伺服器的回應「之後」,但「之前」Proxy 將回應傳回 API 用戶端時執行。這會耗用額外的系統資源,因為系統可能會建立兩條 TLS 連線。

此外,還有一個名為「LogErrorInfo」的 MessageLogging 政策,只有在 API Proxy 執行期間發生錯誤時才會執行。

<?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 週期,導致大規模效能問題。如果使用 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 Proxy 流程中多次建立記錄端點連線,導致網路作業負擔增加。
  • 如果系統記錄伺服器速度緩慢,或無法處理多個系統記錄呼叫造成的大量資料,就會對訊息處理器造成背壓,導致要求處理速度緩慢,並可能發生延遲時間過長或 504 閘道逾時錯誤。
  • 如果 MessageLogging 政策放置在 PostClient 流程以外的流程中,資訊可能不會記錄,因為如果在這項政策執行前發生任何失敗,系統就不會執行 MessageLogging 政策。

    在先前的 ProxyEndpoint 範例中,在下列情況下,系統不會記錄資訊:

    • 如果要求流程中 LogRequestInfo 政策之前的任何政策失敗。
    • 如果目標伺服器發生任何錯誤 (HTTP 4XX、5XX),在這種情況下,如果未傳回成功的回應,系統就不會執行 LogResponseInfo 政策。

    在這兩種情況下,系統都會執行 LogErrorInfo 政策,並只記錄與錯誤相關的資訊。

最佳做法

  • 在 Proxy 流程中,使用一或多個 ExtractVariables 政策JavaScript 政策,將要記錄到內容變數中的所有流程變數設為內容變數,以便稍後執行的 MessageLogging 政策使用。
  • 使用單一 MessageLogging 政策,在無條件執行的 PostClientFlow 中記錄所有必要資料。
  • 如果您使用系統記錄,且不要求郵件必須傳送到系統記錄伺服器,也不強制使用 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>
 ...

以下是 MessageLogging 政策 (LogInfo) 的範例,會記錄所有資料:

<?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 政策明確設定 woeidweather.response* 變數。

延伸閱讀