Antipatrón: invocar la política MessageLogging varias veces en un proxy de APIs

Estás consultando la documentación de Apigee y Apigee Hybrid.
Consulta la documentación de Apigee Edge.

La política MessageLogging de Apigee permite a los desarrolladores de proxies de API registrar mensajes personalizados en los endpoints de Cloud Logging o syslog. Se puede registrar cualquier información importante relacionada con la solicitud de la API, como los parámetros de entrada, la carga útil de la solicitud, el código de respuesta, los mensajes de error (si los hay), etc., para consultarla más adelante o para depurar. Aunque la política usa un proceso en segundo plano para registrar los datos, hay algunas advertencias que debes tener en cuenta al usarla.

Antipatrón

La política MessageLogging proporciona una forma eficaz de obtener más información sobre una solicitud a la API y de depurar cualquier problema que se produzca con ella. Sin embargo, usar la misma política MessageLogging más de una vez o tener varias políticas MessageLogging que registren datos en fragmentos en el mismo proxy de API en flujos distintos de PostClientFlow puede tener consecuencias negativas. Esto se debe a que Apigee abre una conexión a un endpoint externo para una política MessageLogging. Si la política usa TLS a través de TCP, como ocurre con los endpoints de syslog, se añade la sobrecarga de establecer una conexión TLS.

A continuación, explicaremos su funcionamiento con la ayuda de un ejemplo de proxy de API.

proxy de API

En el siguiente ejemplo, se coloca una política MessageLogging llamada "LogRequestInfo" en el flujo Request y se añade otra política MessageLogging llamada "LogResponseInfo" al flujo Response. Ambos están en el PreFlow de ProxyEndpoint. La política LogRequestInfo se ejecuta en segundo plano en cuanto el proxy de API recibe la solicitud, y la política LogResponseInfo se ejecuta después de que el proxy haya recibido una respuesta del servidor de destino, pero antes de que el proxy devuelva la respuesta al cliente de la API. Esto consumirá recursos adicionales del sistema, ya que es posible que se establezcan dos conexiones TLS.

Además, hay una política MessageLogging llamada "LogErrorInfo" que solo se ejecuta si se produce un error durante la ejecución del proxy de 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>

Política de registro de mensajes

En las siguientes configuraciones de políticas de ejemplo, los datos se registran en servidores de registro de terceros mediante TLS a través de TCP. Si se usa más de una de estas políticas en el mismo proxy de API, la sobrecarga de establecer y gestionar conexiones TLS ocuparía memoria del sistema y ciclos de CPU adicionales, lo que provocaría problemas de rendimiento a gran escala. Se producen efectos negativos similares si se usa MessageLogging para registrarse en los endpoints de Cloud Logging.

Política 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>

Política de 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>

Política 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>

Impacto

  • Aumento de la sobrecarga de la red debido a que se establecen conexiones con los endpoints de registro varias veces durante el flujo del proxy de API.
  • Si el servidor syslog es lento o no puede gestionar el gran volumen provocado por varias llamadas syslog, se producirá una contrapresión en el procesador de mensajes, lo que provocará que el procesamiento de las solicitudes sea lento y que se produzcan errores de latencia alta o de tiempo de espera de la puerta de enlace 504.
  • Si la política MessageLogging se coloca en flujos distintos del flujo PostClient, es posible que la información no se registre, ya que la política MessageLogging no se ejecutará si se produce algún error antes de la ejecución de esta política.

    En el ejemplo de ProxyEndpoint anterior, la información no se registrará en las siguientes circunstancias:

    • Si falla alguna de las políticas que se han colocado antes de la política LogRequestInfo en el flujo de solicitudes.
      o
    • Si el servidor de destino falla con algún error (HTTP 4XX o 5XX). En esta situación, cuando no se devuelve una respuesta correcta, no se ejecutará la política LogResponseInfo.

    En ambos casos, se ejecutará la política LogErrorInfo y solo se registrará la información relacionada con el error.

Práctica recomendada

  • En el flujo del proxy, usa una o varias instancias de la política ExtractVariables o de la política JavaScript para definir todas las variables de flujo que se van a registrar en una variable de contexto. De esta forma, estarán disponibles para la política MessageLogging que se ejecuta más adelante.
  • Usa una sola política MessageLogging para registrar todos los datos necesarios en PostClientFlow, que se ejecuta incondicionalmente.
  • Si usas syslog, utiliza el protocolo UDP si no es necesario que los mensajes se entreguen al servidor syslog y TLS/SSL no es obligatorio.

La política MessageLogging se ha diseñado para que esté desacoplada de la funcionalidad de la API, incluida la gestión de errores. Por lo tanto, si se invoca en PostClientFlow, que está fuera del procesamiento de solicitudes y respuestas, siempre registrará datos, independientemente de si la API se ha completado correctamente o no.

Aquí tienes un ejemplo de cómo invocar la política MessageLogging en PostClientFlow:

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

A continuación se muestra un ejemplo de una política MessageLogging, LogInfo, que registra todos los datos:

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

Como las variables de respuesta no están disponibles en PostClientFlow después de un Error Flow, es importante definir explícitamente las variables woeid y weather.response* mediante políticas ExtractVariables o JavaScript.

Más información