Crea métricas personalizadas para trabajos de AWS Glue
- victoriagimenez5
- 29 jul
- 3 Min. de lectura
Actualizado: 19 ago

Como sabes, CloudWatch te permite publicar métricas personalizadas desde tus aplicaciones. Estas son métricas que no son proporcionadas directamente por los servicios de AWS.
Tradicionalmente, estas métricas se publicaban llamando a la API PutMetricData de CloudWatch desde tu aplicación, generalmente usando el SDK de AWS para el lenguaje de tu preferencia.
Con el nuevo formato de métricas embebidas de CloudWatch (EMF), puedes simplemente incluir las métricas personalizadas dentro de los logs que tu aplicación envía a CloudWatch, y CloudWatch extraerá automáticamente estas métricas de los registros. Luego, puedes graficarlas desde la consola de CloudWatch e incluso configurar alarmas y notificaciones como lo harías con cualquier métrica estándar.
Esto funciona en cualquier entorno desde el cual envíes logs a CloudWatch: instancias EC2, máquinas on-prem, contenedores Docker/Kubernetes en ECS/EKS, funciones Lambda, etc.
En este caso, nos centraremos en crear métricas personalizadas para las ejecuciones de trabajos de AWS Glue. El objetivo final es crear una alarma de CloudWatch para identificar si una ejecución fue exitosa o no. La siguiente solución lo resuelve:

Infraestructura
Creamos la infraestructura y los permisos necesarios con Terraform:
Regla de evento y destino
hcl
resource "aws_cloudwatch_event_rule" "custom_glue_job_metrics" {
name = "CustomGlueJobMetrics"
description = "Create custom metrics from glue job events
is_enabled = true
event_pattern = jsonencode({
"source": ["aws.glue"],
"detail-type": ["Glue Job State Change"]
})
}
resource "aws_cloudwatch_event_target" "custom_glue_job_metrics" {
target_id = "CustomGlueJobMetrics"
rule = aws_cloudwatch_event_rule.custom_glue_job_metrics.name
arn = aws_lambda_function.custom_glue_job_metrics.arn
retry_policy {
maximum_event_age_in_seconds = 3600
maximum_retry_attempts = 0
}
}
Lambda y permisos
resource "aws_lambda_function" "custom_glue_job_metrics" {
function_name = "CustomGlueJobMetrics"
filename = "python/handler.zip"
source_code_hash = filebase64sha256("python/handler.zip")
role = aws_iam_role.custom_glue_job_metrics.arn
handler = "handler.handler"
runtime = "python3.9"
timeout = 90
tracing_config {
mode = "PassThrough"
}
}
resource "aws_lambda_permission" "allow_cloudwatch" {
statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.custom_glue_job_metrics.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.custom_glue_job_metrics.arn
}Roles y políticas IAM
resource "aws_iam_role" "custom_glue_job_metrics" {
name = "CustomGlueJobMetrics"
assume_role_policy = jsonencode({
Version : "2012-10-17",
Statement : [{
Effect : "Allow",
Principal : {
Service : "lambda.amazonaws.com"
},
Action : "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy" "custom_glue_job_metrics" {
name = "CustomGlueJobMetrics"
role = aws_iam_role.custom_glue_job_metrics.id
policy = jsonencode({
Version : "2012-10-17",
Statement : [{
Effect : "Allow",
Action : [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
Resource : "arn:aws:logs:*:*:*"
}]
})
}Ya con esto, hemos creado la regla de eventos, su destino, una función Lambda (donde se ejecutará handler.py) y sus permisos necesarios.
Usamos el Event Bus por defecto.
Código Python
from aws_embedded_metrics import metric_scope
@metric_scope
def handler(event, _context, metrics):
glue_job_name = event["detail"]["jobName"]
glue_job_run_id = event["detail"]["jobRunId"]
metrics.set_namespace(f"GlueBasicMetrics")
metrics.set_dimensions(
{"JobName": glue_job_name}, {"JobName": glue_job_name, "JobRunId": glue_job_run_id}
)
if event["detail-type"] == "Glue Job State Change":
state = event["detail"]["state"]
if state not in ["SUCCEEDED", "FAILED", "TIMEOUT", "STOPPED"]:
raise AttributeError("State is not supported.")
metrics.put_metric(key=state.capitalize(), value=1, unit="Count"
if state == "SUCCEEDED":
metrics.put_metric(key="Failed", value=0, unit="Count")
else:
metrics.put_metric(key="Succeeded", value=0, unit="Count")Este código crea un nuevo namespace (GlueBasicMetrics) dentro de CloudWatch con dos dimensiones (JobName y JobName, JobRunId). Se actualiza cada vez que se ejecuta un Glue Job, ya que el evento "Glue Job State Change" es el que dispara la Lambda.
Instalación de módulos y librerías
Como vimos en Terraform, importamos el código como un archivo .zip. Es fundamental que el código Python, el módulo aws-embedded-metrics y cualquier otra dependencia estén al mismo nivel dentro del .zip.

Instalación del módulo:
pip3 install aws-embedded-metricsAlarma de CloudWatch
Ahora que tenemos las métricas, creamos la alarma de CloudWatch para detectar fallos en la ejecución:
resource "aws_cloudwatch_metric_alarm" "job_failed" {
alarm_name = "EtlJobFailed"
metric_name = "Failed"
namespace = "GlueBasicMetrics"
period = "60"
statistic = "Sum"
comparison_operator = "GreaterThanOrEqualToThreshold"
threshold = "1"
evaluation_periods = "1"
treat_missing_data = "ignore"
dimensions = {
JobName = "IotEtlTransformationJob"
}
alarm_actions = ["aws_sns_topic.mail.arn", "aws_sns_topic.chatbot.arn"]
}}
En este ejemplo, usamos una lista de temas SNS para enviar notificaciones por email o chatbot. Asegúrate de crear los tópicos necesarios para activar las alertas.
Conclusión
¡Y eso es todo!
Con unas pocas líneas de Terraform y Python, creamos una solución que monitorea el estado de ejecución de Glue Jobs, publica métricas personalizadas en CloudWatch y lanza alarmas automáticas en caso de fallo.
Esta práctica te ayuda a cumplir con los Pilares de Eficiencia Operativa y Eficiencia del Rendimiento del Well-Architected Framework de AWS.

Martín Carletti
Cloud Engineer
Teracloud
If you want to know more about Cloudwatch, we suggest checking Your AWS invoice is getting bigger and bigger because of CloudWatch Logs, and you don't know why? To learn more about cloud computing, visit our blog for first-hand insights from our team. If you need an AWS-certified team to deploy, scale, or provision your IT resources to the cloud seamlessly, send us a message here.



