Datadog también puede ayudarte a recopilar métricas de recursos gestionados de AWS, como API Gateway, AppSync y SQS, para contribuir a la monitorización de toda tu aplicación serverless. Estas métricas se enriquecen con las etiquetas (tags) de los recursos de AWS correspondientes.
Datadog genera métricas de Lambda mejoradas a partir de tu tiempo de ejecución de Lambda de forma inmediata con baja latencia, granularidad de varios segundos y metadatos detallados para arranques en frío y etiquetas personalizados.
Las métricas de Lambda mejoradas se añaden a las métricas de Lambda predeterminadas que se habilitan con la integración de AWS Lambda. Las métricas mejoradas se distinguen por estar en el espacio de nombres aws.lambda.enhanced.*. Puedes consultar estas métricas en el Dashboard predeterminado para las métricas de Lambda mejoradas.
Están disponibles las siguientes métricas de Lambda mejoradas en tiempo real, con las etiquetas aws_account, region, functionname, cold_start, memorysize, executedversion, resource y runtime correspondientes.
Estas métricas son distribuciones: puedes consultarlas mediante las agregaciones count, min, max, sum y avg.
aws.lambda.enhanced.invocations
Mide el número de veces que se invoca una función en respuesta a un evento o a la invocación de una llamada a la API.
aws.lambda.enhanced.errors
Mide el número de invocaciones que fallaron debido a errores en la función.
aws.lambda.enhanced.max_memory_used
Mide la cantidad máxima de memoria (en MB) utilizada por la función.
aws.lambda.enhanced.duration
Mide los segundos transcurridos desde que el código de la función comienza a ejecutarse como resultado de una invocación hasta que deja de ejecutarse.
aws.lambda.enhanced.billed_duration
Mide el tiempo de funcionamiento facturado de la función (en incrementos de 100 ms).
aws.lambda.enhanced.init_duration
Mide el tiempo de inicialización (en segundos) de una función durante un arranque en frío.
aws.lambda.enhanced.runtime_duration
Mide los milisegundos transcurridos desde que el código de la función comienza a ejecutarse hasta que devuelve la respuesta al cliente, sin contar la duración posterior al tiempo de ejecución añadida por las ejecuciones de la extensión de Lambda.
aws.lambda.enhanced.post_runtime_duration
Mide los milisegundos transcurridos desde que el código de la función devuelve la respuesta al cliente hasta que la función deja de ejecutarse, lo que representa la duración añadida por las ejecuciones de la extensión de Lambda.
aws.lambda.enhanced.response_latency
Mide el tiempo transcurrido en milisegundos desde que se recibe la solicitud de invocación hasta que se envía el primer byte de respuesta al cliente.
aws.lambda.enhanced.response_duration
Mide el tiempo transcurrido en milisegundos desde que se envía al cliente el primer byte de respuesta hasta el último byte de respuesta.
aws.lambda.enhanced.produced_bytes
Mide el número de bytes devueltos por una función.
aws.lambda.enhanced.estimated_cost
Mide el coste total estimado de la invocación a la función (en dólares estadounidenses).
aws.lambda.enhanced.timeouts
Mide el número de veces que se agota el tiempo de espera de una función.
aws.lambda.enhanced.out_of_memory
Mide el número de veces que una función se queda sin memoria.
Si tus funciones de Lambda ya envían datos de trazas (traces) o logs a Datadog, y los datos que quieres consultar se capturan en un log o traza existente, puedes generar métricas personalizadas a partir de logs y trazas sin necesidad de volver a desplegar o hacer cambios en el código de tu aplicación.
Con las métricas basadas en logs, puedes registrar un recuento de logs que coincidan con una consulta o resumir un valor numérico contenido en un log, como la duración de una solicitud. Las métricas basadas en logs son una forma rentable de resumir los datos de los logs de todo el flujo (stream) de la ingesta. Obtén más información sobre la creación de métricas basadas en logs.
También puedes generar métricas a partir de todos los tramos (spans) ingeridos, independientemente de si están indexados por un filtro de retención. Obtén más información sobre la creación de métricas basadas en tramos.
fromdatadog_lambda.metricimportlambda_metricdeflambda_handler(event,context):lambda_metric("coffee_house.order_value",# Nombre de la métrica12.45,# Valor de la métricatags=['product:latte','order:online']# Etiquetas asociadas)
const{sendDistributionMetric}=require('datadog-lambda-js');asyncfunctionmyHandler(event,context){sendDistributionMetric('coffee_house.order_value',// Nombre de la métrica
12.45,// Valor de la métrica
'product:latte',// Primera etiqueta
'order:online'// Segunda etiqueta
);}
packagemainimport("github.com/aws/aws-lambda-go/lambda""github.com/DataDog/datadog-lambda-go")funcmain(){lambda.Start(ddlambda.WrapFunction(myHandler,nil))}funcmyHandler(ctxcontext.Context,eventMyEvent)(string,error){ddlambda.Distribution("coffee_house.order_value",// Nombre de la métrica
12.45,// Valor de la métrica
"product:latte","order:online"// Etiquetas asociadas
)}
packagecom.datadog.lambda.sample.java;importcom.amazonaws.services.lambda.runtime.Context;importcom.amazonaws.services.lambda.runtime.RequestHandler;importcom.amazonaws.services.lambda.runtime.events.APIGatewayV2ProxyRequestEvent;importcom.amazonaws.services.lambda.runtime.events.APIGatewayV2ProxyResponseEvent;// importa el compilador del cliente statsdimportcom.timgroup.statsd.NonBlockingStatsDClientBuilder;importcom.timgroup.statsd.StatsDClient;publicclassHandlerimplementsRequestHandler<APIGatewayV2ProxyRequestEvent,APIGatewayV2ProxyResponseEvent>{// crea la instancia del cliente statsdprivatestaticfinalStatsDClientStatsd=newNonBlockingStatsDClientBuilder().hostname("localhost").build();@OverridepublicAPIGatewayV2ProxyResponseEventhandleRequest(APIGatewayV2ProxyRequestEventrequest,Contextcontext){// envía una métrica de distribuciónStatsd.recordDistributionValue("my.custom.java.metric",1,newString[]{"tag:value"});APIGatewayV2ProxyResponseEventresponse=newAPIGatewayV2ProxyResponseEvent();response.setStatusCode(200);returnresponse;}static{// asegúrese de que todas las métricas se vacíen antes del cierreRuntime.getRuntime().addShutdownHook(newThread(){@Overridepublicvoidrun(){System.out.println("[runtime] shutdownHook activado");try{Thread.sleep(300);}catch(InterruptedExceptione){System.out.println("[runtime] sleep interrumpido");}System.out.println("[runtime] saliendo");}});}}
usingSystem.IO;// importa el cliente statsdusingStatsdClient;namespaceExample{publicclassFunction{staticFunction(){// crea la instancia del cliente statsdvardogstatsdConfig=newStatsdConfig{StatsdServerName="127.0.0.1",StatsdPort=8125,};if(!DogStatsd.Configure(dogstatsdConfig))thrownewInvalidOperationException("Cannot initialize DogstatsD. Set optionalExceptionHandler argument in the `Configure` method for more information.");}publicStreamMyHandler(Streamstream){// envía una métrica de distribuciónDogStatsd.Distribution("my.custom.dotnet.metric",1,tags:new[]{"tag:value"});// la lógica de tu función}}}
Instala el cliente DogStatsD para tu tiempo de ejecución.
En la mayoría de los casos, Datadog recomienda utilizar la extensión Datadog Lambda para enviar métricas personalizadas. Sin embargo, la extensión de Lambda solo puede enviar métricas con una marca de tiempo actual.
Para enviar métricas históricas, utiliza el Datadog Forwarder. Estas métricas pueden tener marcas de tiempo que estén dentro de la última hora.
fromdatadog_lambda.metricimportlambda_metricdeflambda_handler(event,context):lambda_metric("coffee_house.order_value",# Nombre de la métrica12.45,# Valor de la métricatags=['product:latte','order:online']# Etiquetas asociadas)# Envía una métrica con una marca de tiempo que esté dentro de los últimos 20 minutoslambda_metric("coffee_house.order_value",# Nombre de la métrica12.45,# Valor de la métricatimestamp=int(time.time()),# Unix epoch en segundostags=['product:latte','order:online']# Etiquetas asociadas)
const{sendDistributionMetric}=require('datadog-lambda-js');asyncfunctionmyHandler(event,context){sendDistributionMetric('coffee_house.order_value',// Nombre de la métrica
12.45,// Valor de la métrica
'product:latte',// Primera etiqueta
'order:online'// Segunda etiqueta
);// Envía una métrica con una marca de tiempo que esté dentro de los últimos 20 minutos
sendDistributionMetricWithDate('coffee_house.order_value',// Nombre de la métrica
12.45,// Valor de la métrica
newDate(Date.now()),// Fecha
'product:latte',// Primera etiqueta
'order:online',// Segunda etiqueta
);}
packagemainimport("github.com/aws/aws-lambda-go/lambda""github.com/DataDog/datadog-lambda-go")funcmain(){lambda.Start(ddlambda.WrapFunction(myHandler,nil))}funcmyHandler(ctxcontext.Context,eventMyEvent)(string,error){ddlambda.Distribution("coffee_house.order_value",// Nombre de la métrica
12.45,// Valor de la métrica
"product:latte","order:online"// Etiquetas asociadas
)// Envía una métrica con una marca de tiempo que esté dentro de los últimos 20 minutos
ddlambda.MetricWithTimestamp("coffee_house.order_value",// Nombre de la métrica
12.45,// Valor de la métrica
time.Now(),// Marca de tiempo
"product:latte","order:online"// Etiquetas asociadas
)}
require'datadog/lambda'defhandler(event:,context:)# Solo tienes que envolver el controlador de tu función (no las funciones auxiliares).Datadog::Lambda.wrap(event,context)doDatadog::Lambda.metric('coffee_house.order_value',# Nombre de la métrica12.45,# Valor de la métrica"product":"latte","order":"online"# Etiquetas asociadas)# Envía una métrica con una marca de tiempo que esté dentro de los últimos 20 minutosDatadog::Lambda.metric('coffee_house.order_value',# Nombre de la métrica12.45,# Valor de la métricatime:Time.now.utc,# Marca de tiempo"product":"latte","order":"online"# Etiquetas asociadas)endend
publicclassHandlerimplementsRequestHandler<APIGatewayV2ProxyRequestEvent,APIGatewayV2ProxyResponseEvent>{publicIntegerhandleRequest(APIGatewayV2ProxyRequestEventrequest,Contextcontext){DDLambdadd=newDDLambda(request,lambda);Map<String,String>myTags=newHashMap<String,String>();myTags.put("product","latte");myTags.put("order","online");dd.metric("coffee_house.order_value",// Nombre de la métrica12.45,// Valor de la métricamyTags);// Etiquetas asociadas}}
Escribe una función reutilizable que genere logs de tus métricas personalizadas en el siguiente formato:
{"m":"Nombre de la métrica","v":"Valor de la métrica","e":"Marca de tiempo Unix (segundos)","t":"Matriz de etiquetas"}
El uso del Forwarder para enviar muchos puntos de datos para la misma métrica y el mismo conjunto de etiquetas (por ejemplo, dentro de un gran bucle for) puede afectar el rendimiento de Lambda y el coste de CloudWatch.
Puedes agregar los puntos de datos de tu aplicación para evitar la sobrecarga.
Por ejemplo, en Python:
deflambda_handler(event,context):# Ineficiente cuando event['Records'] contiene muchos registrosforrecordinevent['Records']:lambda_metric("record_count",1)# Implementación mejoradarecord_count=0forrecordinevent['Records']:record_count+=1lambda_metric("record_count",record_count)
Cuando Datadog recibe varios puntos de métricas de recuento o calibre que comparten la misma marca de tiempo y el mismo conjunto de etiquetas, solo cuenta el punto más reciente. Esto funciona para las aplicaciones basadas en hosts porque el Datadog Agent agrega los puntos de métricas y les aplica una etiqueta host única.
Un función de Lambda puede iniciar muchos entornos de ejecución de forma simultánea cuando aumenta el tráfico. La función puede llegar a enviar puntos de métricas de recuento o calibre que se sobrescriben entre sí y generan resultados subestimados. Para evitar este problema, las métricas personalizadas generadas a partir de funciones de Lambda se envían como distribuciones, ya que los puntos de las métricas de distribución se agregan en el backend de Datadog y se cuentan todos los puntos de métricas.
Las distribuciones ofrecen las agregaciones avg, sum, max, min y count de forma predeterminada. En la página Metric Summary (Resumen de métrica), puedes habilitar agregaciones percentiles (p50, p75, p90, p95, p99) y también gestionar etiquetas. Para monitorizar la distribución de un tipo de métrica de calibre, utiliza avg tanto para las agregaciones temporales como espaciales. Para monitorizar la distribución de un tipo de métrica de recuento, utiliza sum tanto para las agregaciones temporales como espaciales. Lee la guía Consulta al gráfico para saber cómo funcionan las agregaciones temporales y espaciales.