Antipatrón: Invoca la política MessageLogging varias veces en un proxy de API

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

La política de MessageLogging de Apigee permite que los desarrolladores de proxy de API registren mensajes personalizados en los extremos de Cloud Logging o syslog. Cualquier información importante relacionada con la solicitud a la API, como los parámetros de entrada, la carga útil de la solicitud, el código de respuesta y los mensajes de error (si existen), etcétera, se puede registrar para referencia posterior o para depuración. Si bien la política usa un proceso en segundo plano para realizar el registro, hay advertencias con el uso de la política.

Antipatrón

La política de MessageLogging proporciona una manera eficiente de obtener más información sobre una solicitud a la API y depurar cualquier problema que se presente con esa solicitud. Sin embargo, usar la misma política de MessageLogging más de una vez o tener varias políticas de MessageLogging registrando los datos en fragmentos en el mismo proxy de API en flujos que no son PostClientFlow podría dar como resultado consecuencias adversas. Esto se debe a que Apigee abre una conexión a un extremo externo para una política de MessageLogging. Si la política usa TLS sobre TCP, al igual que con los extremos de syslog, hay una sobrecarga adicional para establecer una conexión TLS.

Veamos esto con la ayuda de un proxy de API de ejemplo.

proxy de API

En el siguiente ejemplo, se agrega una política de MessageLogging llamada “LogRequestInfo” en el flujo de solicitudes, y se agrega otra política MessageLogging llamada “LogResponseInfo” al flujo de respuesta. Ambos se encuentran en el flujo de preprocesamiento de ProxyEndpoint. La política de LogRequestInfo se ejecuta en segundo plano apenas el proxy de API recibe la solicitud, y la política de LogResponseInfo se ejecuta después de que el proxy recibió una respuesta del servidor de destino, pero antes de que el proxy muestre la respuesta al cliente de la API. Esto consumirá recursos adicionales del sistema, ya que se pueden establecer dos conexiones TLS.

Además, hay una política de MessageLogging llamada “LogErrorInfo” que se ejecuta solo si se genera un error durante la ejecución del proxy de la 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 configuraciones de política de ejemplo siguientes, 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 del establecimiento y administración de conexiones TLS ocupará memorias del sistema y ciclos de CPU adicionales, lo que generaría problemas de rendimiento a gran escala. Se producen fectos negativos similares si se usa MessageLogging para acceder a los extremos 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 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

  • Hay una mayor sobrecarga de red debido a las conexiones con los extremos de registros generadas varias veces durante el flujo del proxy de API
  • Si el servidor syslog es lento o no puede controlar el gran volumen causado por varias llamadas syslog, generará una presión posterior en el procesador de mensajes, lo que dará como resultado un procesamiento lento de la solicitud y errores de latencia alta o de tiempo de espera de puerta de enlace 504.
  • Si la política de MessageLogging se coloca en flujos distintos del flujo PostClient, existe la posibilidad de que la información no se registre, ya que la política de MessageLogging no se ejecutará si ocurre 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 alguna de las políticas colocadas antes de la política LogRequestInfo en el flujo de solicitud falla.
      o
    • Si el servidor de destino falla con algún error (HTTP 4XX, 5XX). En esta situación, cuando no se muestra una respuesta correcta, la política LogResponseInfo no se ejecutará.

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

Práctica recomendada

  • Dentro del flujo del proxy, usa una o más instancias de la política ExtractVariables o la política de JavaScript para establecer todas las variables de flujo que se registrarán en una variable de contexto. Esto hará que estén disponibles para la política MessageLogging que se ejecuta más adelante.
  • Usa una única política MessageLogging para registrar todos los datos necesarios en PostClientFlow, que se va a ejecutar de forma incondicional.
  • Si usas syslog, usa el protocolo UDP si no se requiere la entrega garantizada de los mensajes al Servidor syslog y TLS/SSL no es obligatorio.

La política MessageLogging se diseñó para desasociar de la funcionalidad real de la API, incluido el manejo de errores. Por lo tanto, si la invocas en PostClientFlow, que está fuera del procesamiento de solicitudes y respuestas, significa que siempre registrará los datos, independientemente de si la API funcionó o no.

A continuación, se muestra un ejemplo que invoca 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>
 ...

Aquí tienes 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>

Debido a que las variables de respuesta no están disponibles en PostClientFlow después de un flujo de error, es importante configurar explícitamente las variables woeid y weather.response* mediante ExtractVariables o políticas JavaScript.

Lecturas adicionales