Hay varias formas de enviar métricas personalizadas a Datadog desde una función de Lambda.
Creación de métricas personalizadas a partir de logs o trazas (traces): si tus funciones de Lambda ya envían datos de trazas o logs a Datadog, y los datos que quieres consultar se encuentran en un log o una traza existente, puedes generar métricas personalizadas a partir de logs y trazas sin volver a desplegar ni hacer cambios en el código de tu aplicación.
(Obsoleto) Envío de métricas personalizadas mediante la biblioteca Lambda de Datadog: la biblioteca Lambda de Datadog para Python, Node.js y Go admite el envío de métricas personalizadas de forma sincrónica desde el tiempo de ejecución a Datadog con el bloqueo de la invocación cuando DD_FLUSH_TO_LOG se define como false. Además de la sobrecarga del rendimiento, los envíos de métricas también pueden sufrir errores intermitentes debido a la falta de reintentos por problemas transitorios de red. Datadog recomienda utilizar la Datadog Lambda Extension en su lugar.
(No recomendado) Uso de una biblioteca de terceros: la mayoría de las bibliotecas de terceros no envían métricas como distribuciones y pueden dar lugar a resultados mal contabilizados. También pueden sufrir errores intermitentes debido a la falta de reintentos por problemas transitorios de red.
Cuando Datadog recibe varios puntos de métricas count o gauge 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.
Una función de Lambda puede iniciar muchos entornos de ejecución de forma simultánea cuando hay un aumento de tráfico. La función puede llegar a enviar puntos de métricas count o gauge que se sobrescriben entre sí y generan resultados mal contabilizados. 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 todos ellos se cuentan.
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 gauge, utiliza avg tanto para las agregaciones temporales como espaciales. Para monitorizar la distribución de un tipo de métrica count, 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.
Para enviar métricas históricas (solo se permiten marcas de tiempo dentro de los últimos 20 minutos), debes utilizar el Datadog Forwarder, ya que la Datadog Lambda Extension solo puede enviar métricas con la marca de tiempo actual debido a la limitación del protocolo de StatsD.
Cuando se utiliza el 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 haber un impacto notable en el rendimiento de Lambda y también un impacto en el coste de CloudWatch. Para evitar la sobrecarga, puedes agregar los puntos de datos en tu aplicación. Consulta el siguiente ejemplo de 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)
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.
Datadog recomienda utilizar la Datadog Lambda Extension para enviar métricas personalizadas como distribución desde los tiempos de ejecución de Lambda admitidos.
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
)}
Instala la última versión de java-dogstatsd-client y, luego, sigue el código de ejemplo que aparece abajo para enviar tus métricas personalizadas como distribución.
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;// importar el compilador del cliente statsdimportcom.timgroup.statsd.NonBlockingStatsDClientBuilder;importcom.timgroup.statsd.StatsDClient;publicclassHandlerimplementsRequestHandler<APIGatewayV2ProxyRequestEvent,APIGatewayV2ProxyResponseEvent>{// instanciar el cliente statsdprivatestaticfinalStatsDClientStatsd=newNonBlockingStatsDClientBuilder().hostname("localhost").build();@OverridepublicAPIGatewayV2ProxyResponseEventhandleRequest(APIGatewayV2ProxyRequestEventrequest,Contextcontext){// enviar una métrica de distribuciónStatsd.recordDistributionValue("my.custom.java.metric",1,newString[]{"tag:value"});APIGatewayV2ProxyResponseEventresponse=newAPIGatewayV2ProxyResponseEvent();response.setStatusCode(200);returnresponse;}static{// asegurarse de que todas las métricas se descargan antes del cierreRuntime.getRuntime().addShutdownHook(newThread(){@Overridepublicvoidrun(){System.out.println("[runtime] shutdownHook triggered");try{Thread.sleep(300);}catch(InterruptedExceptione){System.out.println("[runtime] sleep interrupted");}System.out.println("[runtime] exiting");}});}}
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.
Datadog recomienda utilizar la función de Lambda del Datadog Forwarder para enviar métricas personalizados desde tiempos de ejecución de Lambda que no son compatibles con la Lambda Datadog Extension.
Si no te interesa recopilar las trazas de tu función de Lambda, define la variable de entorno DD_TRACE_ENABLED como false en tu función de Lambda.
Si no te interesa recopilar los logs de tu función de Lambda, define el parámetro del stack tecnológico de CloudFormation DdForwardLog como false en el Forwarder.
Importa y utiliza una función auxiliar de la biblioteca Lambda de Datadog, como lambda_metric o sendDistributionMetric, para enviar tus métricas personalizadas con el código de ejemplo que aparece abajo.
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"}
Este método de envío de métricas personalizadas ya no es compatible y está deshabilitado para todos los clientes nuevos. Migra a una de las soluciones recomendadas.
Nota: Si vas a migrar a una de las soluciones recomendadas, tendrás que empezar a instrumentar tus métricas personalizadas con nombres de métrica nuevos cuando las envíes a Datadog. No puede existir de forma simultánea el mismo nombre de métrica tanto como tipo de métrica de distribución como de no distribución.
<TAG_LIST> es opcional, se separa por comas y debe ir precedido de #. La etiqueta function_name:<name_of_the_function> se aplica automáticamente a las métricas personalizadas.
Nota: La suma de cada marca de tiempo se utiliza para counts y el último valor de una marca de tiempo dada se utiliza para gauges. No se recomienda imprimir una sentencia de log cada vez que aumenta una métrica, ya que esto hace que el análisis de logs tarde más. Actualiza continuamente el valor de la métrica en tu código e imprime una sentencia de log para esa métrica antes de que la función termine de ejecutarse.