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

Stai visualizzando la documentazione relativa a Apigee e Apigee ibrido.
Visualizza la documentazione di Apigee Edge.

Il criterio MessageLogging di Apigee consente agli sviluppatori di proxy API di registrare messaggi personalizzati in Cloud Logging o endpoint syslog. Tutte le informazioni importanti relative alla richiesta API, come i parametri di input, il payload della richiesta, il codice di risposta, gli eventuali messaggi di errore e così via, possono essere registrate per riferimento futuro o per il debug. Sebbene il criterio utilizzi un processo in background per eseguire il logging, l'utilizzo del criterio richiede un'attenzione particolare.

Antipattern

Il criterio MessageLogging fornisce un modo efficiente per ottenere ulteriori informazioni su una richiesta API e per eseguire il debug di eventuali problemi riscontrati con la richiesta API. Tuttavia, l'utilizzo dello stesso criterio MessageLogging più di una volta o la presenza di più criteri MessageLogging registrano i dati in blocchi nello stesso proxy API in flussi diversi da PostClientFlow potrebbero 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 nel caso degli endpoint syslog, aumenta l'overhead associato alla creazione di una connessione TLS.

Spieghiamo tutto questo con l'aiuto di un proxy API di esempio.

proxy API

Nell'esempio seguente, nel flusso di richiesta viene inserito un criterio MessageLogging denominato "LogRequestInfo" e al flusso di risposta viene aggiunto un altro criterio MessageLogging denominato "LogResponseInfo". Entrambi si trovano nel ProxyEndpoint PreFlow. Il criterio LogRequestInfo viene eseguito in background non appena il proxy API riceve la richiesta e 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. Ciò consumerà risorse di sistema aggiuntive poiché potrebbero essere stabilite due connessioni TLS.

Inoltre, esiste un criterio MessageLogging denominato "LogErrorInfo" che viene eseguito solo in caso di 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>

Criterio di logging dei messaggi

Nelle configurazioni di criteri di esempio che seguono, i dati vengono registrati su server di log di terze parti utilizzando TLS su TCP. Se nello stesso proxy API viene utilizzato più di uno di questi criteri, l'overhead associato alla creazione e alla gestione di connessioni TLS occuperebbe ulteriore memoria di sistema e cicli di CPU, causando problemi di prestazioni su larga scala. Si verificano effetti negativi simili se si utilizza MessageLogging per accedere agli endpoint Cloud Logging.

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

Criterio di 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 connessione ripetuta agli endpoint di log durante il flusso proxy API.
  • Se il server syslog è lento o non è in grado di gestire l'elevato volume causato da più chiamate syslog, causerà una pressione negativa sul processore di messaggi, con conseguente rallentamento dell'elaborazione delle richieste e potenzialmente elevata latenza o errori 504 di timeout del gateway.
  • Se il criterio MessageLogging viene inserito in flussi diversi da PostClient, è possibile che le informazioni non vengano registrate, poiché il criterio MessageLogging non viene eseguito in caso di errore prima dell'esecuzione di questo criterio.

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

    • Se uno dei criteri posizionati prima del criterio LogRequestInfo nel flusso di richiesta non va a buon fine.
      oppure
    • In caso di errore del server di destinazione (HTTP 4XX, 5XX). In questo caso, se non viene restituita una risposta positiva, il criterio LogResponseInfo non verrà eseguito.

    In entrambi i casi, il criterio LogErrorInfo verrà eseguito e registrerà solo le informazioni relative all'errore.

Best practice

  • All'interno del flusso del proxy, utilizza una o più istanze del criterio Takeout o del criterio JavaScript per impostare tutte le variabili di flusso che devono essere registrate in una variabile di contesto. In questo modo saranno disponibili per il criterio MessageLogging che verrà eseguito in un secondo momento.
  • Utilizza un singolo criterio 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.

Il criterio MessageLogging è stato progettato per essere disaccoppiato dalle funzionalità effettive dell'API, inclusa la gestione degli errori. Pertanto, richiamandolo in PostClientFlow, che non rientra nell'elaborazione di richiesta/risposta, i dati verranno sempre registrati indipendentemente dall'esito positivo o negativo dell'API.

Ecco un esempio di richiamo 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 errore, è importante impostare in modo esplicito le variabili woeid e weather.response* utilizzando i criteri di tipo ExtractVariables o JavaScript.

Per approfondire