Monitorizar memoria y errores de funciones Lambda

A la hora de monitorizar estadísticas sobre la ejecución de nuestras funciones Lambda, Cloudwatch ya nos ofrece algunas builtin como:

  • Cantidad de throttles
  • Número de invocaciones
  • Número de errores “genéricos”
  • Duración (media y total)

Pero si queremos ver estadísticas sobre memoria o errores según sean por consumo excesivo de memoria o por timeout, no los tenemos disponibles por defecto.

Para conseguir información de este tipo de errores, tendremos que recurrir a crear filtros de métricas (metric filters) de los LOGs que deja Lambda en Cloudwatch. Por ejemplo, con el siguiente script, recorremos todas los grupos de LOGs de Lambda (aquellos que empiezan por /aws/lambda/) y creamos unas cuantas métricas en cada uno de ellos, para poder después obtener estadísticas:

#!/bin/bash

# Based on https://gist.github.com/sandfox/337129afa5555af6372d4eae536b20f0
prefix="/aws/lambda/"

for log_group in $(aws logs describe-log-groups --log-group-name-prefix $prefix --query "logGroups[].logGroupName" --output text) ; do

    fn_name=${log_group#$prefix};

    aws logs put-metric-filter \
		  --log-group-name "$log_group" \
		  --filter-name lambda-memory-usage \
		  --filter-pattern '[ x="REPORT", x="RequestId:", request_id, x="Duration:", duration, x="ms", x="Billed", x="Duration:", billed_duration, x="ms", x="Memory", x="Size:", memory_size, x="MB", x="Max", x="Memory", x="Used:", memory_used, x="MB"]' \
		  --metric-transformations "metricNamespace=Custom/Lambda,metricName=${fn_name}-MemoryUsed,metricValue=\$memory_used"

    aws logs put-metric-filter \
		  --log-group-name "$log_group" \
		  --filter-name lambda-memory-size \
		  --filter-pattern '[ x="REPORT", x="RequestId:", request_id, x="Duration:", duration, x="ms", x="Billed", x="Duration:", billed_duration, x="ms", x="Memory", x="Size:", memory_size, x="MB", x="Max", x="Memory", x="Used:", memory_used, x="MB"]' \
		  --metric-transformations "metricNamespace=Custom/Lambda,metricName=${fn_name}-MemorySize,metricValue=\$memory_size"

    # Errores que se dan cuando la ejecución se pasa del máximo de memoria permitido
    aws logs put-metric-filter \
      --log-group-name "${log_group}" \
      --filter-name lambda-memory-errors \
      --filter-pattern 'Process exited before completing request' \
      --metric-transformations "metricNamespace=Custom/Lambda,metricName=${fn_name}-MemoryErrors,metricValue=1,defaultValue=0"

    # Errores que se dan cuando la ejecución se pasa del máximo de tiempo permitido
    aws logs put-metric-filter \
      --log-group-name "${log_group}" \
      --filter-name lambda-timeout-errors \
      --filter-pattern 'Task timed out after' \
      --metric-transformations "metricNamespace=Custom/Lambda,metricName=${fn_name}-TimeoutErrors,metricValue=1,defaultValue=0"

done

Una vez creados, y pasados cierto tiempo para poder obtener datos, en la sección de métricas de Cloudwatch, tendremos una nueva categoría, Custom/Lambda, donde tendremos el listado de nuevas métricas, por cada función Lambda:

Podremos seleccionar estas estadísticas para poder visualizar los datos en un gráfico:

También podremos consultar estos datos desde la CLI:

aws cloudwatch get-metric-statistics --namespace Custom/Lambda --metric-name my_function_name-MemoryUsed --start-time $(date --date "1 day ago" +%s) --end-time $(date +%s)  --period 300 --statistics Average
{
    "Label": "my_function_name-MemoryUsed",
    "Datapoints": [
        {
            "Timestamp": "2019-08-29T04:10:00Z",
            "Average": 84.32894736842105,
            "Unit": "None"
        },
        {
            "Timestamp": "2019-08-28T18:10:00Z",
            "Average": 82.94736842105263,
            "Unit": "None"
        },
        {
            "Timestamp": "2019-08-29T08:10:00Z",
            "Average": 83.72368421052632,
            "Unit": "None"
        },
        {
            "Timestamp": "2019-08-28T22:10:00Z",
            "Average": 84.63157894736842,
            "Unit": "None"
        },
        {
            "Timestamp": "2019-08-29T12:10:00Z",
            "Average": 83.59210526315789,
            "Unit": "None"
        },
        {
            "Timestamp": "2019-08-29T02:10:00Z",
            "Average": 83.17105263157895,
            "Unit": "None"
        },
        {
            "Timestamp": "2019-08-28T16:10:00Z",
            "Average": 84.35526315789474,
            "Unit": "None"
        },
        {
            "Timestamp": "2019-08-29T06:10:00Z",
            "Average": 83.85526315789474,
            "Unit": "None"
        },
        {
            "Timestamp": "2019-08-29T10:10:00Z",
            "Average": 84.48684210526316,
            "Unit": "None"
        },
        {
            "Timestamp": "2019-08-28T20:10:00Z",
            "Average": 85.0657894736842,
            "Unit": "None"
        },
        {
            "Timestamp": "2019-08-29T00:10:00Z",
            "Average": 84.97368421052632,
            "Unit": "None"
        },
        {
            "Timestamp": "2019-08-29T14:10:00Z",
            "Average": 82.57894736842105,
            "Unit": "None"
        }
    ]
}
comments powered by Disqus

Relacionado