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

Stai visualizzando la documentazione di Apigee Edge.
Consulta la documentazione di Apigee X.
info

La policy MessageLogging di Apigee Edge consente agli sviluppatori di proxy API di registrare messaggi personalizzati in syslog o su disco (solo Edge for Private Cloud). Tutte le informazioni importanti relative alla richiesta API, come i parametri di input, il payload della richiesta, il codice di risposta, i messaggi di errore (se presenti) e così via, possono essere registrate per riferimento futuro o per il debug. Sebbene la policy utilizzi un processo in background per eseguire la registrazione, esistono delle limitazioni all'utilizzo della policy.

Antipattern

La policy MessageLogging fornisce 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 policy MessageLogging più di una volta o l'utilizzo di più policy MessageLogging per registrare i dati in blocchi nello stesso proxy API in flussi diversi da the PostClientFlow può avere implicazioni negative. Questo perché Apigee Edge apre una connessione a un server syslog esterno per una policy MessageLogging. Se la policy utilizza TLS su TCP, è 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 della richiesta e un'altra policy MessageLogging denominata "LogResponseInfo" viene aggiunta al flusso della risposta. Entrambe si trovano in ProxyEndpoint PreFlow. La policy LogRequestInfo viene eseguita in background non appena il proxy API riceve la richiesta, mentre la policy LogResponseInfo viene eseguita 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 consumate risorse di sistema aggiuntive, poiché potrebbero essere stabilite due connessioni TLS.

Inoltre, esiste una policy MessageLogging denominata "LogErrorInfo" che viene eseguita 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>

Policy MessageLogging

Nelle seguenti configurazioni delle policy di esempio, i dati vengono registrati nei server di log di terze parti utilizzando TLS su TCP. Se nello stesso proxy API viene utilizzata più di una di queste policy, l'overhead di stabilire e gestire le connessioni TLS occuperà ulteriore memoria di sistema e cicli della CPU, causando problemi di prestazioni su larga scala.

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

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

Policy 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 ai server di log più volte durante il flusso del proxy API.
  • Se il server syslog è lento o non è in grado di gestire il volume elevato causato da più chiamate syslog si verificherà una contropressione sul processore di messaggi, con conseguente elaborazione lenta delle richieste e potenzialmente elevata latenza o errori di timeout del gateway 504.
  • Aumento del numero di descrittori di file simultanei aperti dal processore di messaggi nelle configurazioni di Private Cloud in cui viene utilizzata la registrazione dei file.
  • Se la policy MessageLogging viene inserita in flussi diversi da PostClientFlow, è possibile che le informazioni non vengano registrate, poiché la policy MessageLogging non verrà eseguita se si verifica un errore prima dell'esecuzione di questa policy.

    Nell'esempio precedente di ProxyEndpoint, le informazioni non verranno registrate nelle seguenti circostanze:

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

    In entrambi i casi, la policy LogErrorInfo verrà eseguita e registrerà solo le informazioni relative all'errore.

Best practice

  • Utilizza una policy ExtractVariables o una policy JavaScript per impostare tutte le variabili di flusso da registrare, rendendole disponibili per la policy MessageLogging.
  • Utilizza una singola policy MessageLogging per registrare tutti i dati richiesti in PostClientFlow, che viene eseguito in modo incondizionato.
  • Utilizza il protocollo UDP, in cui non è richiesta la consegna garantita dei messaggi al server syslog e TLS/SSL non è obbligatorio.

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

Ecco un esempio di invocazione della policy 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 policy 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