Antipattern: invocar a política MessageLogging várias vezes num proxy de API

Está a ver a documentação do Apigee e do Apigee Hybrid.
Veja a documentação do Apigee Edge.

A política MessageLogging do Apigee permite que os programadores de proxy de API registem mensagens personalizadas em registos na nuvem ou pontos finais syslog. Todas as informações importantes relacionadas com o pedido da API, como parâmetros de entrada, payload do pedido, código de resposta, mensagens de erro (se existirem), etc., podem ser registadas para referência posterior ou para depuração. Embora a política use um processo em segundo plano para realizar o registo, existem ressalvas quanto à utilização da política.

Antipattern

A política MessageLogging oferece uma forma eficiente de obter mais informações sobre um pedido de API e depurar quaisquer problemas encontrados com o pedido de API. No entanto, a utilização da mesma política MessageLogging mais do que uma vez ou a existência de várias políticas MessageLogging registam dados em blocos no mesmo proxy de API em fluxos que não sejam o PostClientFlow, o que pode ter implicações adversas. Isto deve-se ao facto de o Apigee abrir uma ligação a um ponto final externo para uma política MessageLogging. Se a política usar TLS sobre TCP, como com os pontos finais syslog, existe uma sobrecarga adicional de estabelecimento de uma ligação TLS.

Vamos explicar isto com a ajuda de um exemplo de proxy de API.

proxy de API

No exemplo seguinte, uma política MessageLogging denominada "LogRequestInfo" é colocada no fluxo de pedidos e outra política MessageLogging denominada "LogResponseInfo" é adicionada ao fluxo de respostas. Ambos estão no PreFlow do ProxyEndpoint. A política LogRequestInfo é executada em segundo plano assim que o proxy da API recebe o pedido, e a política LogResponseInfo é executada depois de o proxy ter recebido uma resposta do servidor de destino, mas antes de o proxy devolver a resposta ao cliente da API. Isto vai consumir recursos de sistema adicionais, uma vez que podem ser estabelecidas duas ligações TLS.

Além disso, existe uma política MessageLogging denominada "LogErrorInfo" que é executada apenas se ocorrer um erro durante a execução do 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 Registo de Mensagens

Nas seguintes configurações de políticas de exemplo, os dados estão a ser registados em servidores de registo de terceiros através de TLS sobre TCP. Se for usada mais do que uma destas políticas no mesmo proxy de API, a sobrecarga de estabelecer e gerir ligações TLS ocuparia memória do sistema e ciclos da CPU adicionais, o que levaria a problemas de desempenho em grande escala. Ocorrem efeitos negativos semelhantes se usar MessageLogging para registar nos pontos finais do 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

  • Sobrecarga de rede aumentada devido ao estabelecimento de ligações aos pontos finais de registo várias vezes durante o fluxo do proxy de API.
  • Se o servidor syslog for lento ou não conseguir processar o elevado volume causado por várias chamadas syslog, vai causar contrapressão no processador de mensagens, o que resulta num processamento lento de pedidos e, potencialmente, numa latência elevada ou em erros de tempo limite do gateway 504.
  • Se a política MessageLogging for colocada em fluxos que não sejam o fluxo PostClient, existe a possibilidade de as informações não serem registadas, uma vez que a política MessageLogging não é executada se ocorrer alguma falha antes da execução desta política.

    No exemplo ProxyEndpoint anterior, as informações não são registadas nas seguintes circunstâncias:

    • Se alguma das políticas colocadas antes da política LogRequestInfo no fluxo de pedidos falhar.
      ou
    • Se o servidor de destino falhar com qualquer erro (HTTP 4XX, 5XX). Nesta situação, quando não é devolvida uma resposta bem-sucedida, a política LogResponseInfo não é executada.

    Em ambos os casos, a política LogErrorInfo é executada e regista apenas as informações relacionadas com erros.

Prática recomendada

  • No fluxo de proxy, use uma ou mais instâncias da política ExtractVariables ou da política JavaScript para definir todas as variáveis de fluxo que vão ser registadas numa variável de contexto. Isto torna-as disponíveis para a política MessageLogging que é executada mais tarde.
  • Use uma única política MessageLogging para registar todos os dados necessários no PostClientFlow, que é executado incondicionalmente.
  • Se estiver a usar o syslog, use o protocolo UDP se a entrega garantida de mensagens ao servidor syslog não for necessária e o TLS/SSL não for obrigatório.

A política MessageLogging foi concebida para ser separada da funcionalidade real da API, incluindo o processamento de erros. Por conseguinte, invocá-lo no PostClientFlow, que está fora do processamento de pedidos/respostas, significa que regista sempre dados, independentemente de a API ter sido bem-sucedida ou não.

Segue-se um exemplo que invoca a política de registo de mensagens em PostClientFlow:

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

Segue-se um exemplo de uma política MessageLogging, LogInfo, que regista todos os dados:

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

Uma vez que as variáveis de resposta não estão disponíveis no PostClientFlow após um fluxo de erros, é importante definir explicitamente as variáveis woeid e weather.response* através de políticas ExtractVariables ou JavaScript.

Leitura complementar