Antipattern: richiamare il criterio MessageLogging più volte in un proxy API

Stai visualizzando la documentazione di Apigee e Apigee hybrid.
Visualizza la documentazione di Apigee Edge.

I criteri MessageLogging di Apigee consentono agli sviluppatori di proxy API di registrare messaggi personalizzati negli endpoint Cloud Logging o syslog. Qualsiasi informazione importante relativa alla richiesta API, come parametri di input, payload della richiesta, codice di risposta, messaggi di errore (se presenti) e così via, può essere registrata per riferimento futuro o per il debug. Sebbene il criterio utilizzi un processo in background per eseguire il logging, esistono avvertenze relative al suo utilizzo.

Antipattern

I criteri MessageLogging forniscono un modo efficiente per ottenere maggiori informazioni su una richiesta API e per eseguire il debug di eventuali problemi riscontrati con la richiesta API. Tuttavia, l'utilizzo della stessa norma MessageLogging più di una volta o la presenza di più norme MessageLogging che registrano i dati in blocchi nello stesso proxy API in flussi diversi da PostClientFlow potrebbe avere implicazioni negative. Questo perché Apigee apre una connessione a un endpoint esterno per un criterio MessageLogging. Se il criterio utilizza TLS su TCP, come per gli endpoint syslog, è presente un overhead aggiuntivo per stabilire una connessione TLS.

Spieghiamone il funzionamento con l'aiuto di un proxy API di esempio.

Proxy API

Nell'esempio seguente, una policy MessageLogging denominata "LogRequestInfo" viene inserita nel flusso di richiesta e un'altra policy MessageLogging denominata "LogResponseInfo" viene aggiunta al flusso di risposta. Entrambi si trovano in ProxyEndpoint PreFlow. Il criterio LogRequestInfo viene eseguito in background non appena il proxy API riceve la richiesta, mentre il criterio LogResponseInfo viene eseguito dopo che il proxy ha ricevuto una risposta dal server di destinazione ma prima che il proxy restituisca la risposta al client API. In questo modo verranno utilizzate risorse di sistema aggiuntive, poiché potrebbero essere stabilite due connessioni TLS.

Inoltre, esiste un criterio MessageLogging denominato "LogErrorInfo" che viene eseguito solo se si verifica un errore durante l'esecuzione del proxy API.

<?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>

Norme sul logging dei messaggi

Nelle seguenti configurazioni dei criteri di esempio, i dati vengono registrati nei server di log di terze parti utilizzando TLS su TCP. Se nello stesso proxy API viene utilizzato più di uno di questi criteri, il sovraccarico di stabilire e gestire le connessioni TLS occuperebbe ulteriore memoria di sistema e cicli della CPU, causando problemi di prestazioni su larga scala. Effetti negativi simili si verificano se utilizzi MessageLogging per registrare gli endpoint di Cloud Logging.

Norme 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>

Norme 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>

Norme 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>

Impatto

  • Aumento dell'overhead di rete dovuto alla creazione di connessioni agli endpoint di log più volte durante il flusso del proxy API.
  • Se il server syslog è lento o non è in grado di gestire l'elevato volume causato da più chiamate syslog, si verificherà una contropressione sul processore di messaggi, con conseguente elaborazione lenta delle richieste e potenzialmente latenza elevata o errori di timeout del gateway 504.
  • Se la policy MessageLogging viene inserita in flussi diversi dal flusso PostClient, è possibile che le informazioni non vengano registrate, in quanto la policy MessageLogging non verrà eseguita se si verifica un errore prima dell'esecuzione di questa policy.

    Nell'esempio ProxyEndpoint precedente, le informazioni non verranno registrate nei seguenti casi:

    • Se una delle policy posizionate prima della policy LogRequestInfo nel flusso di richiesta non va a buon fine.
      oppure
    • Se il server di destinazione non funziona e restituisce un errore (HTTP 4XX, 5XX). In questa situazione, quando non viene restituita una risposta riuscita, la policy LogResponseInfo non viene eseguita.

    In entrambi i casi, il criterio LogErrorInfo verrà eseguito e registrerà solo le informazioni relative agli errori.

Best practice

  • All'interno del flusso proxy, utilizza una o più istanze del criterio ExtractVariables o del criterio JavaScript per impostare tutte le variabili di flusso da registrare in una variabile di contesto. In questo modo, saranno disponibili per il criterio MessageLogging che viene eseguito in un secondo momento.
  • Utilizza una singola policy MessageLogging per registrare tutti i dati richiesti in PostClientFlow, che viene eseguito in modo incondizionato.
  • Se utilizzi syslog, utilizza il protocollo UDP se la consegna garantita dei messaggi al server syslog non è richiesta e TLS/SSL non è obbligatorio.

La policy MessageLogging è stata progettata per essere disaccoppiata dalla funzionalità effettiva dell'API, inclusa la gestione degli errori. Pertanto, richiamarlo in PostClientFlow, che si trova al di fuori dell'elaborazione di richieste/risposte, significa che registrerà sempre i dati indipendentemente dal fatto che l'API abbia avuto esito positivo o meno.

Ecco un esempio di invocazione del criterio MessageLogging in PostClientFlow:

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

Ecco un esempio di criterio MessageLogging, LogInfo, che registra tutti i dati:

<?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>

Poiché le variabili di risposta non sono disponibili in PostClientFlow dopo un flusso di errori, è importante impostare esplicitamente le variabili woeid e weather.response* utilizzando le policy ExtractVariables o JavaScript.

Per approfondire