ServiceMonitor y PodMonitor de Prometheus: ¡No te pierdas los nuevos conceptos!

black flat screen tv turned on near black and gray audio component

Descubre las diferencias entre dos de los CRDs más utilizados del Operador Prometheus y cómo usar cada uno de ellos.

Conceptos de Prometheus: ServiceMonitor y PodMonitor

Foto de Ibrahim Boran en Unsplash

ServiceMonitor y PodMonitor son términos que comenzarás a ver más a menudo cuando se hable de usar Prometheus. Hemos cubierto mucho sobre Prometheus en artículos anteriores. Es una de las principales referencias cuando hablamos de monitoreo en un entorno nativo de la nube y está especialmente enfocado en el ecosistema de Kubernetes.

Prometheus tiene un nuevo modelo de implementación bajo el Marco del Operador de Kubernetes en tiempos recientes. Eso ha generado varios cambios en términos de recursos y cómo configuramos varios aspectos del monitoreo de nuestras cargas de trabajo. Algunos de estos conceptos ahora se gestionan como Definición de Recurso Personalizado (CRD) que se incluyen para simplificar la configuración del sistema y estar más alineados con las capacidades de la propia plataforma de Kubernetes. Esto es genial pero, al mismo tiempo, cambia cómo necesitamos usar esta excelente herramienta de monitoreo para cargas de trabajo nativas de la nube.

Hoy, cubriremos dos de estos nuevos CRDs, uno de los más relevantes: ServiceMonitor y PodMonitor. Estos son los nuevos objetos que especifican los recursos que estarán bajo el alcance de monitoreo para la plataforma, y cada uno de ellos cubre un tipo diferente de objeto, como puedes imaginar: Servicios y Pods.

Cada uno de ellos tiene su archivo de definición con sus campos y metadatos particulares, y para destacarlos, presentaré un ejemplo para cada uno de ellos a continuación:

Service Monitor

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    serviceMonitorSelector: prometheus
  name: prometheus
  namespace: prometheus
spec:
  endpoints:
  - interval: 30s
    targetPort: 9090
    path: /metrics
  namespaceSelector:
    matchNames:
    - prometheus
  selector:
    matchLabels:
      operated-prometheus: "true"

Pod Monitor

apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: front-end
  labels:
    name: front-end
spec:
  namespaceSelector:
    matchNames:
      - sock-shop
  selector:
    matchLabels:
      name: front-end
  podMetricsEndpoints:
  - targetPort: 8079

Como puedes ver, las definiciones de los componentes son muy similares y muy intuitivas, enfocándose en el selector para detectar qué pods o servicios debemos monitorear y algunos datos sobre el objetivo específico del monitoreo, para que Prometheus sepa cómo extraerlos.

Si deseas echar un vistazo más en detalle a cualquier opción que puedas configurar en este CRD, te recomendaría que eches un vistazo a esta URL que incluye una documentación detallada campo por campo de los CRDs más comunes:

Estos componentes pertenecerán a la definición de tus cargas de trabajo, lo que significa que la creación y el mantenimiento de estos objetos serán responsabilidad de los desarrolladores de la aplicación.

Eso es genial por varias razones:

  • Incluirá el aspecto de Monitoreo del propio componente, por lo que nunca olvidarás agregar la configuración de un componente específico. Eso significa que se puede incluir en los archivos YAML duplicados o en el Helm Chart o en recursos de Kustomize como otro recurso necesario.
  • Descentralizará la configuración de monitoreo haciéndola más ágil, y progresará a medida que lo hagan los componentes de software.
  • Reducirá el impacto en otros componentes monitoreados ya que no hay necesidad de actuar en ningún archivo o recurso estándar, por lo que cualquier carga de trabajo diferente continuará funcionando como se espera.

Ambos objetos son muy similares en sus propósitos ya que ambos extraen todos los endpoints que coinciden con el selector que agregamos. Entonces, ¿en qué casos debería usar uno u otro?

La respuesta será sencilla. Por defecto, optarás por un ServiceMonitor porque proporcionará las métricas del propio servicio y de cada uno de los endpoints que tiene el servicio, por lo que cada uno de los pods que están implementando el servicio será descubierto y extraído como parte de esta acción.

Entonces, ¿en qué casos debería usar PodMonitor? Donde la carga de trabajo que estás tratando de monitorear no actúa detrás de un servicio, por lo que al no haber un servicio definido, no puedes usar ServiceMonitor. ¿Quieres algunos ejemplos de eso? ¡Traigamos algunos!

  • Servicios que interactúan usando otros protocolos que no son basados en HTTP, como Kafka, SQS/SNS, JMS, o similares.
  • Componentes como CronJobs, DaemonSets, o que no exponen ningún modelo de conexión entrante.

Así que espero que este artículo te ayude a entender la principal diferencia entre esos objetos y profundizar un poco más en cómo funcionan los nuevos recursos del Marco del Operador Prometheus. Continuaremos cubriendo otros aspectos en próximos artículos.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Desenredando las Políticas de Reclamación para Volúmenes Persistentes en Kubernetes

Desenredando las Políticas de Reclamación para Volúmenes Persistentes en Kubernetes

Descubre cómo la política puede afectar cómo se gestionan tus datos dentro del Clúster de Kubernetes

Como sabes, todo está bien en Kubernetes hasta que te enfrentas a una carga de trabajo con estado y necesitas gestionar sus datos. Todas las potentes capacidades que Kubernetes aporta al juego enfrentan muchos desafíos cuando hablamos de servicios con estado que requieren muchos datos. La mayoría de los desafíos tienen una solución hoy en día. Es por eso que muchas cargas de trabajo con estado, como bases de datos y otros sistemas de backend, también requieren mucho conocimiento sobre cómo definir varias cosas. Una de ellas es la política de retención del volumen persistente. Primero, definamos qué es la Política de Reclamación, y para hacerlo, usaré la definición oficial de la documentación:
Cuando un usuario ha terminado con su volumen, puede eliminar los objetos PVC de la API que permite la reclamación del recurso. La política de reclamación para un PersistentVolume le dice al clúster qué hacer con el volumen después de que ha sido liberado de su reclamación. Actualmente, los volúmenes pueden ser Retenidos, Reciclados o Eliminados.
Entonces, como puedes ver, tenemos tres opciones: Retener, Reciclar o Eliminar. Veamos cuál es el comportamiento de cada una de ellas.

Retener

Eso significa que los datos seguirán allí incluso si la reclamación ha sido eliminada. Todas estas políticas se aplican cuando el PVC original es eliminado. Antes de esa situación, los datos siempre permanecerán sin importar qué política usemos. Entonces, retener significa que incluso si eliminamos el PVC, los datos seguirán allí, y se almacenarán de manera que ningún otro PVC pueda reclamar esos datos. Solo un administrador puede hacerlo con el siguiente flujo:
  1. Eliminar el PersistentVolume.
  2. Limpiar manualmente los datos en el activo de almacenamiento asociado según corresponda.
  3. Eliminar manualmente el activo de almacenamiento asociado.

Eliminar

Eso significa que tan pronto como eliminemos el PVC, el PV y los datos serán liberados. Esto simplificará la tarea de limpieza y mantenimiento de tus volúmenes, pero al mismo tiempo, aumenta la posibilidad de que haya alguna pérdida de datos debido a un comportamiento inesperado. Como siempre, este es un compromiso que necesitas hacer. Siempre necesitamos recordarte que si intentas eliminar un PVC en uso activo por un Pod, el PVC no se elimina inmediatamente. La eliminación del PVC se pospone hasta que el PVC ya no sea utilizado activamente por ningún Pod para asegurar que no se pierdan datos, al menos cuando algún componente todavía está vinculado a él. En la misma política, algo similar sucede con el PV. Si un administrador elimina un PV adjunto a un PVC, el PV no se elimina inmediatamente. La eliminación del PV se pospone hasta que el PV ya no esté vinculado a un PVC.

Reciclar

Eso significa algo en el medio, funciona de manera similar a la política de Eliminar que explicamos anteriormente, pero no elimina el volumen en sí, sino que eliminará el contenido del PV, por lo que en la práctica será similar. Entonces, al final, ejecutará un comando similar a este rm -rf en el artefacto de almacenamiento en sí. Pero solo para que estés al tanto, esta política está actualmente obsoleta, y no deberías usarla en tus nuevas cargas de trabajo, pero todavía es compatible, por lo que puedes encontrar algunas cargas de trabajo que aún la están usando.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

¿Por qué es tan genial el modo agente de Prometheus?

¿Por qué es tan genial el modo agente de Prometheus?

Prometheus ha incluido una nueva capacidad en la versión 2.32.0 para optimizar el enfoque de un solo panel de vidrio 

A partir de la nueva versión próxima de Prometheus v2.32.0, tendremos una nueva característica importante a nuestra disposición: el Modo Agente. Y hay una fantástica publicación en el blog anunciando esta característica de uno de los rockstars del equipo de Prometheus: Bartlomiej Plotka, que recomiendo leer. Agregaré una sección de referencia al final del artículo. Intentaré resumir algunos de los puntos más relevantes aquí. Otra publicación sobre Prometheus, el sistema de monitoreo más crítico en las arquitecturas nativas de la nube de hoy en día, tiene su origen en el sistema de monitoreo Borgmon creado por Google en tiempos antiguos (alrededor del período 2010–2014). Basado en esta importancia, su uso ha estado creciendo increíblemente y fortaleciendo su relación con el ecosistema de Kubernetes. Hemos llegado a un punto en que Prometheus es la opción predeterminada para el monitoreo en prácticamente cualquier escenario que tenga una carga de trabajo relacionada con Kubernetes; algunos ejemplos son los que se muestran a continuación:
  • Prometheus es la opción predeterminada, incluyendo el Sistema de Monitoreo de Openshift
  • Prometheus tiene un Servicio Gestionado de Amazon a su disposición para ser utilizado en sus cargas de trabajo.
  • Prometheus está incluido en la Arquitectura de Referencia para Despliegues Nativos de la Nube de Azure.
Debido a esta popularidad y crecimiento, muchos casos de uso diferentes han planteado algunas mejoras que se pueden realizar. Algunos de ellos están relacionados con casos de uso específicos como el despliegue en el borde o proporcionar una vista global, o un solo panel de vidrio. Hasta ahora, si tengo varios despliegues de Prometheus, monitoreo un subconjunto específico de sus cargas de trabajo debido a que residen en diferentes redes o porque hay varios clústeres, puede confiar en la capacidad de escritura remota para agregar eso en un enfoque de vista global. La Escritura Remota es una capacidad que ha existido en Prometheus desde su creación. Las métricas que Prometheus está recopilando se pueden enviar automáticamente a un sistema diferente utilizando sus integraciones. Esto se puede configurar para todas las métricas o solo un subconjunto. Pero incluso con todo esto, están avanzando en esta capacidad, por lo que están introduciendo el modo Agente. El Modo Agente optimiza el caso de uso de escritura remota configurando la instancia de Prometheus en un modo específico para realizar este trabajo de manera optimizada. Ese modelo implica la siguiente configuración:
  • Desactivar consultas y alertas.
  • Cambiar el almacenamiento local por un TSDB WAL personalizado
Y lo notable es que todo lo demás es igual, por lo que seguiremos utilizando la misma API, descubriendo capacidades y configuración relacionada. ¿Y qué te proporcionará todo esto? Veamos los beneficios que obtendrás al hacerlo:
  • Eficiencia: El TSDB WAL personalizado mantendrá solo los datos que no pudieron ser enviados al lugar de destino; tan pronto como tenga éxito, eliminará esa pieza de datos.
  • Escalabilidad: Mejorará la escalabilidad, permitiendo una escalabilidad horizontal más fácil para la ingesta. Esto se debe a que este modo agente desactiva algunas de las razones por las que la autoestabilidad es compleja en el modo servidor normal de Prometheus. Una carga de trabajo con estado hace que la escalabilidad sea compleja, especialmente en escenarios de reducción de escala. Así que este modo llevará a una carga de trabajo «más sin estado» que simplificará este escenario y estará cerca del sueño de un sistema de ingesta de métricas de autoescalabilidad.
Esta característica está disponible como una bandera experimental en la nueva versión, pero ya fue probada con los trabajos de Grafana Labs, especialmente en el lado del rendimiento. Si deseas ver más detalles sobre esta característica, te recomendaría echar un vistazo al siguiente artículo: https://prometheus.io/blog/2021/11/16/agent/

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Prometheus Storage: Optimiza el uso del disco en tu implementación con estos trucos

Prometheus Storage: Optimiza el uso del disco en tu implementación con estos trucos

Descubre las propiedades que te permitirán un uso optimizado de tu almacenamiento en disco y ahorros al almacenar tus datos de monitoreo

Prometheus se ha convertido en un componente estándar en nuestras arquitecturas en la nube y el almacenamiento de Prometheus se está convirtiendo en un aspecto crítico. Así que voy a suponer que si estás leyendo esto ya sabes qué es Prometheus. Si este no es el caso, por favor tómate tu tiempo para echar un vistazo a otros artículos que he creado:

Sabemos que usualmente cuando monitoreamos usando Prometheus tenemos tantos exportadores disponibles a nuestra disposición y también que cada uno de ellos expone muchas métricas muy relevantes que necesitamos para rastrear todo lo que necesitamos y que lleva a un uso muy intensivo del almacenamiento disponible si no lo gestionamos adecuadamente.

Hay dos factores que afectan esto. El primero es optimizar el número de métricas que estamos almacenando y ya proporcionamos consejos para hacerlo en otros artículos como los que se muestran a continuación:

El otro es cuánto tiempo almacenamos las métricas llamado el “período de retención en Prometheus.” Y esta propiedad ha sufrido muchos cambios durante las diferentes versiones. Si te gustaría ver toda la historia, por favor echa un vistazo a este artículo de Robust Perception:

Las principales propiedades que puedes configurar son las siguientes:

  • storage.tsdb.retention.time: Número de días para almacenar las métricas por defecto a 15d. Esta propiedad reemplaza la obsoleta storage.tsdb.retention.
  • storage.tsdb.retention.size: Puedes especificar el límite de tamaño a utilizar. Este no es un límite estricto sino un mínimo, así que por favor define algún margen aquí. Unidades soportadas: B, KB, MB, GB, TB, PB, EB. Ej: “512MB”. Esta propiedad es experimental hasta ahora como puedes ver en la documentación oficial:

https://prometheus.io/docs/prometheus/latest/storage

¿Qué tal configurar esta configuración en el operador para Kubernetes? En ese caso, también tienes opciones similares disponibles en el archivo de configuración values.yaml para el chart como puedes ver en la imagen a continuación:

Prometheus Storage: Optimiza el uso del disco en tu implementación con estos trucos
values.yml para el Helm Chart del Operador de Prometheus

Esto debería ayudarte a obtener un despliegue optimizado de Prometheus que asegure todas las características que tiene Prometheus pero al mismo tiempo un uso óptimo de los recursos a tu disposición.

Además de eso, también deberías revisar las opciones de Servicio Gestionado que algunos proveedores tienen respecto a Prometheus, como los Servicios Gestionados de Amazon para Prometheus, como puedes ver en el enlace a continuación:

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Servicio AWS Prometheus para Proporcionar Más Disponibilidad a su Solución de Monitoreo

Servicio AWS Prometheus para Proporcionar Más Disponibilidad a su Solución de Monitoreo

Aprende qué proporciona el Servicio Administrado de Amazon para Prometheus y cómo puedes beneficiarte de él.

El monitoreo es uno de los temas candentes cuando hablamos de arquitecturas nativas de la nube. Prometheus es un proyecto de código abierto graduado de la Cloud Native Computing Foundation (CNCF) y una de las soluciones estándar de la industria cuando se trata de monitorear tu implementación nativa de la nube, especialmente cuando Kubernetes está involucrado.

Siguiendo su propia filosofía de proporcionar un servicio administrado para algunos de los proyectos de código abierto más utilizados pero totalmente integrado con el ecosistema de AWS, AWS lanza una vista previa general (en el momento de escribir este artículo): Servicio Administrado de Amazon para Prometheus (AMP).

Lo primero es definir qué es el Servicio Administrado de Amazon para Prometheus y qué características proporciona. Así que, esta es la definición de Amazon del servicio:

Un servicio de monitoreo totalmente administrado compatible con Prometheus que facilita el monitoreo de aplicaciones en contenedores de manera segura y a escala.

Y me gustaría dedicar algo de tiempo a algunas partes de esta oración.

  • Servicio totalmente administrado: Entonces, esto será alojado y manejado por Amazon, y solo vamos a interactuar con él usando API como lo hacemos con otros servicios de Amazon como EKS, RDS, MSK, SQS/SNS, y así sucesivamente.
  • Compatible con Prometheus: Entonces, eso significa que incluso si esta no es una instalación pura de Prometheus, la API será compatible. Así que los clientes de Prometheus que pueden usar Grafana u otros para obtener la información de Prometheus funcionarán sin cambiar sus interfaces.
  • Servicio a escala: Amazon, como parte del servicio administrado, se encargará de la escalabilidad de la solución. No necesitas definir un tipo de instancia o cuánta RAM o CPU necesitas. Esto será manejado por AWS.

Entonces, eso suena perfecto. Así que puedes pensar que vas a eliminar tu servidor de Prometheus, y comenzará a usar este servicio. Tal vez incluso estés escribiendo algo como helm delete prom… ¡ESPERA ESPERA!

Porque en este punto, esto no va a reemplazar tu servidor local de Prometheus, pero permitirá la integración con él. Así que, eso significa que tu servidor de Prometheus actuará como un recolector para toda la solución de monitoreo escalable que AMP está proporcionando, algo como puedes ver en la imagen a continuación:

Servicio AWS Prometheus para Proporcionar Más Disponibilidad a su Solución de Monitoreo
Arquitectura de Referencia para el Servicio de Prometheus de Amazon

Entonces, todavía vas a necesitar un servidor de Prometheus, eso es correcto, pero toda la complejidad se evitará y se aprovechará en el servicio administrado: La configuración de almacenamiento, alta disponibilidad, optimización de API, y así sucesivamente, se te proporcionará directamente.

Ingesta de información en el Servicio Administrado de Amazon para Prometheus

En este momento, hay dos formas de ingresar datos en el Servicio de Prometheus de Amazon:

  • Desde un servidor de Prometheus existente usando la capacidad y configuración de remote_write, lo que significa que cada serie que es recolectada por el Prometheus local será enviada al Servicio de Prometheus de Amazon.
  • Usando AWS Distro para OpenTelemetry para integrarse con este servicio usando el Receptor de Prometheus y los componentes Exportador de Escritura Remota de AWS Prometheus para obtener eso.

Resumen

Así que esta es una forma de proporcionar una instalación de nivel empresarial aprovechando todo el conocimiento que AWS tiene al alojar y gestionar esta solución a escala y optimizada en términos de rendimiento. Puedes centrarte en los componentes que necesitas para obtener las métricas ingresadas en el servicio.

Estoy seguro de que este no será el último movimiento de AWS en temas de observabilidad y gestión de métricas. Estoy seguro de que continuarán proporcionando más herramientas a las manos de los desarrolladores y arquitectos para definir soluciones optimizadas tan fácilmente como sea posible.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Prometheus Storage: ¿Cómo optimizar el uso del disco?

Prometheus Storage: ¿Cómo optimizar el uso del disco?

Aprende algunos trucos para analizar y optimizar el uso que estás haciendo de la TSDB y ahorrar dinero en tu implementación en la nube.

En publicaciones anteriores, discutimos cómo funcionaba la capa de almacenamiento para Prometheus y cuán efectiva era. Pero en los tiempos actuales, estamos en la era de la computación en la nube y sabemos que cada optimización técnica es también una optimización de costos, y es por eso que necesitamos ser muy diligentes con cualquier opción que usemos en cuanto a optimización.

Sabemos que usualmente cuando monitoreamos usando Prometheus tenemos muchos exportadores disponibles a nuestra disposición y también que cada uno de ellos expone muchas métricas muy relevantes que necesitamos para rastrear todo lo que necesitamos. Pero también, debemos ser conscientes de que hay métricas que no necesitamos en este momento o que no planeamos usar. Entonces, si no planeamos usarlas, ¿por qué queremos desperdiciar espacio en disco almacenándolas?

Así que, comencemos echando un vistazo a uno de los exportadores que tenemos en nuestro sistema. En mi caso, me gustaría usar una Aplicación de Contenedor BusinessWorks que expone métricas sobre su utilización. Si revisas su punto de acceso de métricas podrías ver algo como esto:

# HELP jvm_info Información de la versión de JVM
# TYPE jvm_info gauge
jvm_info{version="1.8.0_221-b27",vendor="Oracle Corporation",runtime="Java(TM) SE Runtime Environment",} 1.0
# HELP jvm_memory_bytes_used Bytes usados de un área de memoria JVM dada.
# TYPE jvm_memory_bytes_used gauge
jvm_memory_bytes_used{area="heap",} 1.0318492E8
jvm_memory_bytes_used{area="nonheap",} 1.52094712E8
# HELP jvm_memory_bytes_committed Bytes comprometidos de un área de memoria JVM dada.
# TYPE jvm_memory_bytes_committed gauge
jvm_memory_bytes_committed{area="heap",} 1.35266304E8
jvm_memory_bytes_committed{area="nonheap",} 1.71302912E8
# HELP jvm_memory_bytes_max Máximo de bytes de un área de memoria JVM dada.
# TYPE jvm_memory_bytes_max gauge
jvm_memory_bytes_max{area="heap",} 1.073741824E9
jvm_memory_bytes_max{area="nonheap",} -1.0
# HELP jvm_memory_bytes_init Bytes iniciales de un área de memoria JVM dada.
# TYPE jvm_memory_bytes_init gauge
jvm_memory_bytes_init{area="heap",} 1.34217728E8
jvm_memory_bytes_init{area="nonheap",} 2555904.0
# HELP jvm_memory_pool_bytes_used Bytes usados de un pool de memoria JVM dado.
# TYPE jvm_memory_pool_bytes_used gauge
jvm_memory_pool_bytes_used{pool="Code Cache",} 3.3337536E7
jvm_memory_pool_bytes_used{pool="Metaspace",} 1.04914136E8
jvm_memory_pool_bytes_used{pool="Compressed Class Space",} 1.384304E7
jvm_memory_pool_bytes_used{pool="G1 Eden Space",} 3.3554432E7
jvm_memory_pool_bytes_used{pool="G1 Survivor Space",} 1048576.0
jvm_memory_pool_bytes_used{pool="G1 Old Gen",} 6.8581912E7
# HELP jvm_memory_pool_bytes_committed Bytes comprometidos de un pool de memoria JVM dado.
# TYPE jvm_memory_pool_bytes_committed gauge
jvm_memory_pool_bytes_committed{pool="Code Cache",} 3.3619968E7
jvm_memory_pool_bytes_committed{pool="Metaspace",} 1.19697408E8
jvm_memory_pool_bytes_committed{pool="Compressed Class Space",} 1.7985536E7
jvm_memory_pool_bytes_committed{pool="G1 Eden Space",} 4.6137344E7
jvm_memory_pool_bytes_committed{pool="G1 Survivor Space",} 1048576.0
jvm_memory_pool_bytes_committed{pool="G1 Old Gen",} 8.8080384E7
# HELP jvm_memory_pool_bytes_max Máximo de bytes de un pool de memoria JVM dado.
# TYPE jvm_memory_pool_bytes_max gauge
jvm_memory_pool_bytes_max{pool="Code Cache",} 2.5165824E8
jvm_memory_pool_bytes_max{pool="Metaspace",} -1.0
jvm_memory_pool_bytes_max{pool="Compressed Class Space",} 1.073741824E9
jvm_memory_pool_bytes_max{pool="G1 Eden Space",} -1.0
jvm_memory_pool_bytes_max{pool="G1 Survivor Space",} -1.0
jvm_memory_pool_bytes_max{pool="G1 Old Gen",} 1.073741824E9
# HELP jvm_memory_pool_bytes_init Bytes iniciales de un pool de memoria JVM dado.
# TYPE jvm_memory_pool_bytes_init gauge
jvm_memory_pool_bytes_init{pool="Code Cache",} 2555904.0
jvm_memory_pool_bytes_init{pool="Metaspace",} 0.0
jvm_memory_pool_bytes_init{pool="Compressed Class Space",} 0.0
jvm_memory_pool_bytes_init{pool="G1 Eden Space",} 7340032.0
jvm_memory_pool_bytes_init{pool="G1 Survivor Space",} 0.0
jvm_memory_pool_bytes_init{pool="G1 Old Gen",} 1.26877696E8
# HELP jvm_buffer_pool_used_bytes Bytes usados de un pool de buffer JVM dado.
# TYPE jvm_buffer_pool_used_bytes gauge
jvm_buffer_pool_used_bytes{pool="direct",} 148590.0
jvm_buffer_pool_used_bytes{pool="mapped",} 0.0
# HELP jvm_buffer_pool_capacity_bytes Capacidad en bytes de un pool de buffer JVM dado.
# TYPE jvm_buffer_pool_capacity_bytes gauge
jvm_buffer_pool_capacity_bytes{pool="direct",} 148590.0
jvm_buffer_pool_capacity_bytes{pool="mapped",} 0.0
# HELP jvm_buffer_pool_used_buffers Buffers usados de un pool de buffer JVM dado.
# TYPE jvm_buffer_pool_used_buffers gauge
jvm_buffer_pool_used_buffers{pool="direct",} 19.0
jvm_buffer_pool_used_buffers{pool="mapped",} 0.0
# HELP jvm_classes_loaded El número de clases que están actualmente cargadas en la JVM
# TYPE jvm_classes_loaded gauge
jvm_classes_loaded 16993.0
# HELP jvm_classes_loaded_total El número total de clases que han sido cargadas desde que la JVM comenzó a ejecutarse
# TYPE jvm_classes_loaded_total counter
jvm_classes_loaded_total 17041.0
# HELP jvm_classes_unloaded_total El número total de clases que han sido descargadas desde que la JVM comenzó a ejecutarse
# TYPE jvm_classes_unloaded_total counter
jvm_classes_unloaded_total 48.0
# HELP bwce_activity_stats_list Lista de estadísticas de actividad BWCE
# TYPE bwce_activity_stats_list gauge
# HELP bwce_activity_counter_list Lista de contadores relacionados con la actividad BWCE
# TYPE bwce_activity_counter_list gauge
# HELP all_activity_events_count Conteo de todos los eventos de actividad BWCE por estado
# TYPE all_activity_events_count counter
all_activity_events_count{StateName="CANCELLED",} 0.0
all_activity_events_count{StateName="COMPLETED",} 0.0
all_activity_events_count{StateName="STARTED",} 0.0
all_activity_events_count{StateName="FAULTED",} 0.0
# HELP activity_events_count Conteo de todos los eventos de actividad BWCE por proceso, estado de actividad
# TYPE activity_events_count counter
# HELP activity_total_evaltime_count Tiempo total de evaluación de actividad BWCE por proceso y actividad
# TYPE activity_total_evaltime_count counter
# HELP activity_total_duration_count Tiempo total de duración de actividad BWCE por proceso y actividad
# TYPE activity_total_duration_count counter
# HELP bwpartner_instance:total_request Solicitud total para la invocación del socio que se mapeó desde las actividades
# TYPE bwpartner_instance:total_request counter
# HELP bwpartner_instance:total_duration_ms Duración total para la invocación del socio que se mapeó desde las actividades (ejecución o latencia)
# TYPE bwpartner_instance:total_duration_ms counter
# HELP bwce_process_stats Lista de estadísticas de proceso BWCE
# TYPE bwce_process_stats gauge
# HELP bwce_process_counter_list Lista de contadores relacionados con el proceso BWCE
# TYPE bwce_process_counter_list gauge
# HELP all_process_events_count Conteo de todos los eventos de proceso BWCE por estado
# TYPE all_process_events_count counter
all_process_events_count{StateName="CANCELLED",} 0.0
all_process_events_count{StateName="COMPLETED",} 0.0
all_process_events_count{StateName="STARTED",} 0.0
all_process_events_count{StateName="FAULTED",} 0.0
# HELP process_events_count Conteo de eventos de proceso BWCE por operación
# TYPE process_events_count counter
# HELP process_duration_seconds_total Duración de eventos de proceso BWCE por operación en segundos
# TYPE process_duration_seconds_total counter
# HELP process_duration_milliseconds_total Duración de eventos de proceso BWCE por operación en milisegundos
# TYPE process_duration_milliseconds_total counter
# HELP bwdefinitions:partner Conteo de eventos de proceso BWCE por operación
# TYPE bwdefinitions:partner counter
bwdefinitions:partner{ProcessName="t1.module.item.getTransactionData",ActivityName="FTLPublisher",ServiceName="GetCustomer360",OperationName="GetDataOperation",PartnerService="TransactionService",PartnerOperation="GetTransactionsOperation",Location="internal",PartnerMiddleware="MW",} 1.0
bwdefinitions:partner{ProcessName=" t1.module.item.auditProcess",ActivityName="KafkaSendMessage",ServiceName="GetCustomer360",OperationName="GetDataOperation",PartnerService="AuditService",PartnerOperation="AuditOperation",Location="internal",PartnerMiddleware="MW",} 1.0
bwdefinitions:partner{ProcessName="t1.module.item.getCustomerData",ActivityName="JMSRequestReply",ServiceName="GetCustomer360",OperationName="GetDataOperation",PartnerService="CustomerService",PartnerOperation="GetCustomerDetailsOperation",Location="internal",PartnerMiddleware="MW",} 1.0
# HELP bwdefinitions:binding Repositorio de tiempo de diseño BW - definición de enlace/transporte
# TYPE bwdefinitions:binding counter
bwdefinitions:binding{ServiceName="GetCustomer360",OperationName="GetDataOperation",ServiceInterface="GetCustomer360:GetDataOperation",Binding="/customer",Transport="HTTP",} 1.0
# HELP bwdefinitions:service Repositorio de tiempo de diseño BW - definición de servicio
# TYPE bwdefinitions:service counter
bwdefinitions:service{ProcessName="t1.module.sub.item.getCustomerData",ServiceName="GetCustomer360",OperationName="GetDataOperation",ServiceInstance="GetCustomer360:GetDataOperation",} 1.0
bwdefinitions:service{ProcessName="t1.module.sub.item.auditProcess",ServiceName="GetCustomer360",OperationName="GetDataOperation",ServiceInstance="GetCustomer360:GetDataOperation",} 1.0
bwdefinitions:service{ProcessName="t1.module.sub.orchestratorSubFlow",ServiceName="GetCustomer360",OperationName="GetDataOperation",ServiceInstance="GetCustomer360:GetDataOperation",} 1.0
bwdefinitions:service{ProcessName="t1.module.Process",ServiceName="GetCustomer360",OperationName="GetDataOperation",ServiceInstance="GetCustomer360:GetDataOperation",} 1.0
# HELP bwdefinitions:gateway Repositorio de tiempo de diseño BW - definición de puerta de enlace
# TYPE bwdefinitions:gateway counter
bwdefinitions:gateway{ServiceName="GetCustomer360",OperationName="GetDataOperation",ServiceInstance="GetCustomer360:GetDataOperation",Endpoint="bwce-demo-mon-orchestrator-bwce",InteractionType="ISTIO",} 1.0
# HELP process_cpu_seconds_total Tiempo total de usuario y sistema de CPU gastado en segundos.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 1956.86
# HELP process_start_time_seconds Hora de inicio del proceso desde la época de Unix en segundos.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.604712447107E9
# HELP process_open_fds Número de descriptores de archivo abiertos.
# TYPE process_open_fds gauge
process_open_fds 763.0
# HELP process_max_fds Número máximo de descriptores de archivo abiertos.
# TYPE process_max_fds gauge
process_max_fds 1048576.0
# HELP process_virtual_memory_bytes Tamaño de la memoria virtual en bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 3.046207488E9
# HELP process_resident_memory_bytes Tamaño de la memoria residente en bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 4.2151936E8
# HELP jvm_gc_collection_seconds Tiempo gastado en un recolector de basura JVM dado en segundos.
# TYPE jvm_gc_collection_seconds summary
jvm_gc_collection_seconds_count{gc="G1 Young Generation",} 540.0
jvm_gc_collection_seconds_sum{gc="G1 Young Generation",} 4.754
jvm_gc_collection_seconds_count{gc="G1 Old Generation",} 2.0
jvm_gc_collection_seconds_sum{gc="G1 Old Generation",} 0.563
# HELP jvm_threads_current Conteo actual de hilos de una JVM
# TYPE jvm_threads_current gauge
jvm_threads_current 98.0
# HELP jvm_threads_daemon Conteo de hilos daemon de una JVM
# TYPE jvm_threads_daemon gauge
jvm_threads_daemon 43.0
# HELP jvm_threads_peak Conteo máximo de hilos de una JVM
# TYPE jvm_threads_peak gauge
jvm_threads_peak 98.0
# HELP jvm_threads_started_total Conteo de hilos iniciados de una JVM
# TYPE jvm_threads_started_total counter
jvm_threads_started_total 109.0
# HELP jvm_threads_deadlocked Ciclos de hilos JVM que están en deadlock esperando adquirir monitores de objetos o sincronizadores propios
# TYPE jvm_threads_deadlocked gauge
jvm_threads_deadlocked 0.0
# HELP jvm_threads_deadlocked_monitor Ciclos de hilos JVM que están en deadlock esperando adquirir monitores de objetos
# TYPE jvm_threads_deadlocked_monitor gauge
jvm_threads_deadlocked_monitor 0.0

Como puedes ver, muchas métricas, pero tengo que ser honesto, no estoy usando la mayoría de ellas en mis paneles y para generar mis alertas. Puedo usar las métricas relacionadas con el rendimiento de la aplicación para cada uno de los procesos de BusinessWorks y sus actividades, también el rendimiento de la memoria JVM y el número de hilos, pero cosas como cómo está funcionando el GC de la JVM para cada una de las capas de la JVM (G1 Young Generation, G1 Old Generation) no las estoy usando en absoluto.

Entonces, si muestro el mismo punto de acceso de métricas destacando las cosas que no estoy usando, sería algo como esto:

# HELP jvm_info Información de la versión de JVM
# TYPE jvm_info gauge
jvm_info{version="1.8.0_221-b27",vendor="Oracle Corporation",runtime="Java(TM) SE Runtime Environment",} 1.0

# HELP jvm_memory_bytes_used Bytes usados de un área de memoria JVM dada.
# TYPE jvm_memory_bytes_used gauge
jvm_memory_bytes_used{area="heap",} 1.0318492E8
jvm_memory_bytes_used{area="nonheap",} 1.52094712E8
# HELP jvm_memory_bytes_committed Bytes comprometidos de un área de memoria JVM dada.
# TYPE jvm_memory_bytes_committed gauge
jvm_memory_bytes_committed{area="heap",} 1.35266304E8
jvm_memory_bytes_committed{area="nonheap",} 1.71302912E8
# HELP jvm_memory_bytes_max Máximo de bytes de un área de memoria JVM dada.
# TYPE jvm_memory_bytes_max gauge
jvm_memory_bytes_max{area="heap",} 1.073741824E9
jvm_memory_bytes_max{area="nonheap",} -1.0
# HELP jvm_memory_bytes_init Bytes iniciales de un área de memoria JVM dada.
# TYPE jvm_memory_bytes_init gauge
jvm_memory_bytes_init{area="heap",} 1.34217728E8
jvm_memory_bytes_init{area="nonheap",} 2555904.0

# HELP jvm_memory_pool_bytes_used Bytes usados de un pool de memoria JVM dado.
# TYPE jvm_memory_pool_bytes_used gauge
jvm_memory_pool_bytes_used{pool="Code Cache",} 3.3337536E7
jvm_memory_pool_bytes_used{pool="Metaspace",} 1.04914136E8
jvm_memory_pool_bytes_used{pool="Compressed Class Space",} 1.384304E7
jvm_memory_pool_bytes_used{pool="G1 Eden Space",} 3.3554432E7
jvm_memory_pool_bytes_used{pool="G1 Survivor Space",} 1048576.0
jvm_memory_pool_bytes_used{pool="G1 Old Gen",} 6.8581912E7
# HELP jvm_memory_pool_bytes_committed Bytes comprometidos de un pool de memoria JVM dado.
# TYPE jvm_memory_pool_bytes_committed gauge
jvm_memory_pool_bytes_committed{pool="Code Cache",} 3.3619968E7
jvm_memory_pool_bytes_committed{pool="Metaspace",} 1.19697408E8
jvm_memory_pool_bytes_committed{pool="Compressed Class Space",} 1.7985536E7
jvm_memory_pool_bytes_committed{pool="G1 Eden Space",} 4.6137344E7
jvm_memory_pool_bytes_committed{pool="G1 Survivor Space",} 1048576.0
jvm_memory_pool_bytes_committed{pool="G1 Old Gen",} 8.8080384E7
# HELP jvm_memory_pool_bytes_max Máximo de bytes de un pool de memoria JVM dado.
# TYPE jvm_memory_pool_bytes_max gauge
jvm_memory_pool_bytes_max{pool="Code Cache",} 2.5165824E8
jvm_memory_pool_bytes_max{pool="Metaspace",} -1.0
jvm_memory_pool_bytes_max{pool="Compressed Class Space",} 1.073741824E9
jvm_memory_pool_bytes_max{pool="G1 Eden Space",} -1.0
jvm_memory_pool_bytes_max{pool="G1 Survivor Space",} -1.0
jvm_memory_pool_bytes_max{pool="G1 Old Gen",} 1.073741824E9
# HELP jvm_memory_pool_bytes_init Bytes iniciales de un pool de memoria JVM dado.
# TYPE jvm_memory_pool_bytes_init gauge
jvm_memory_pool_bytes_init{pool="Code Cache",} 2555904.0
jvm_memory_pool_bytes_init{pool="Metaspace",} 0.0
jvm_memory_pool_bytes_init{pool="Compressed Class Space",} 0.0
jvm_memory_pool_bytes_init{pool="G1 Eden Space",} 7340032.0
jvm_memory_pool_bytes_init{pool="G1 Survivor Space",} 0.0
jvm_memory_pool_bytes_init{pool="G1 Old Gen",} 1.26877696E8
# HELP jvm_buffer_pool_used_bytes Bytes usados de un pool de buffer JVM dado.
# TYPE jvm_buffer_pool_used_bytes gauge
jvm_buffer_pool_used_bytes{pool="direct",} 148590.0
jvm_buffer_pool_used_bytes{pool="mapped",} 0.0
# HELP jvm_buffer_pool_capacity_bytes Capacidad en bytes de un pool de buffer JVM dado.
# TYPE jvm_buffer_pool_capacity_bytes gauge
jvm_buffer_pool_capacity_bytes{pool="direct",} 148590.0
jvm_buffer_pool_capacity_bytes{pool="mapped",} 0.0
# HELP jvm_buffer_pool_used_buffers Buffers usados de un pool de buffer JVM dado.
# TYPE jvm_buffer_pool_used_buffers gauge
jvm_buffer_pool_used_buffers{pool="direct",} 19.0
jvm_buffer_pool_used_buffers{pool="mapped",} 0.0
# HELP jvm_classes_loaded El número de clases que están actualmente cargadas en la JVM
# TYPE jvm_classes_loaded gauge
jvm_classes_loaded 16993.0
# HELP jvm_classes_loaded_total El número total de clases que han sido cargadas desde que la JVM comenzó a ejecutarse
# TYPE jvm_classes_loaded_total counter
jvm_classes_loaded_total 17041.0
# HELP jvm_classes_unloaded_total El número total de clases que han sido descargadas desde que la JVM comenzó a ejecutarse
# TYPE jvm_classes_unloaded_total counter
jvm_classes_unloaded_total 48.0

# HELP bwce_activity_stats_list Lista de estadísticas de actividad BWCE
# TYPE bwce_activity_stats_list gauge
# HELP bwce_activity_counter_list Lista de contadores relacionados con la actividad BWCE
# TYPE bwce_activity_counter_list gauge
# HELP all_activity_events_count Conteo de todos los eventos de actividad BWCE por estado
# TYPE all_activity_events_count counter
all_activity_events_count{StateName="CANCELLED",} 0.0
all_activity_events_count{StateName="COMPLETED",} 0.0
all_activity_events_count{StateName="STARTED",} 0.0
all_activity_events_count{StateName="FAULTED",} 0.0
# HELP activity_events_count Conteo de todos los eventos de actividad BWCE por proceso, estado de actividad
# TYPE activity_events_count counter
# HELP activity_total_evaltime_count Tiempo total de evaluación de actividad BWCE por proceso y actividad
# TYPE activity_total_evaltime_count counter
# HELP activity_total_duration_count Tiempo total de duración de actividad BWCE por proceso y actividad
# TYPE activity_total_duration_count counter
# HELP bwpartner_instance:total_request Solicitud total para la invocación del socio que se mapeó desde las actividades
# TYPE bwpartner_instance:total_request counter
# HELP bwpartner_instance:total_duration_ms Duración total para la invocación del socio que se mapeó desde las actividades (ejecución o latencia)
# TYPE bwpartner_instance:total_duration_ms counter
# HELP bwce_process_stats Lista de estadísticas de proceso BWCE
# TYPE bwce_process_stats gauge
# HELP bwce_process_counter_list Lista de contadores relacionados con el proceso BWCE
# TYPE bwce_process_counter_list gauge
# HELP all_process_events_count Conteo de todos los eventos de proceso BWCE por estado
# TYPE all_process_events_count counter
all_process_events_count{StateName="CANCELLED",} 0.0
all_process_events_count{StateName="COMPLETED",} 0.0
all_process_events_count{StateName="STARTED",} 0.0
all_process_events_count{StateName="FAULTED",} 0.0
# HELP process_events_count Conteo de eventos de proceso BWCE por operación
# TYPE process_events_count counter
# HELP process_duration_seconds_total Duración de eventos de proceso BWCE por operación en segundos
# TYPE process_duration_seconds_total counter
# HELP process_duration_milliseconds_total Duración de eventos de proceso BWCE por operación en milisegundos
# TYPE process_duration_milliseconds_total counter
# HELP bwdefinitions:partner Conteo de eventos de proceso BWCE por operación
# TYPE bwdefinitions:partner counter
bwdefinitions:partner{ProcessName="t1.module.item.getTransactionData",ActivityName="FTLPublisher",ServiceName="GetCustomer360",OperationName="GetDataOperation",PartnerService="TransactionService",PartnerOperation="GetTransactionsOperation",Location="internal",PartnerMiddleware="MW",} 1.0
bwdefinitions:partner{ProcessName=" t1.module.item.auditProcess",ActivityName="KafkaSendMessage",ServiceName="GetCustomer360",OperationName="GetDataOperation",PartnerService="AuditService",PartnerOperation="AuditOperation",Location="internal",PartnerMiddleware="MW",} 1.0
bwdefinitions:partner{ProcessName="t1.module.item.getCustomerData",ActivityName="JMSRequestReply",ServiceName="GetCustomer360",OperationName="GetDataOperation",PartnerService="CustomerService",PartnerOperation="GetCustomerDetailsOperation",Location="internal",PartnerMiddleware="MW",} 1.0
# HELP bwdefinitions:binding Repositorio de tiempo de diseño BW - definición de enlace/transporte
# TYPE bwdefinitions:binding counter
bwdefinitions:binding{ServiceName="GetCustomer360",OperationName="GetDataOperation",ServiceInterface="GetCustomer360:GetDataOperation",Binding="/customer",Transport="HTTP",} 1.0
# HELP bwdefinitions:service Repositorio de tiempo de diseño BW - definición de servicio
# TYPE bwdefinitions:service counter
bwdefinitions:service{ProcessName="t1.module.sub.item.getCustomerData",ServiceName="GetCustomer360",OperationName="GetDataOperation",ServiceInstance="GetCustomer360:GetDataOperation",} 1.0
bwdefinitions:service{ProcessName="t1.module.sub.item.auditProcess",ServiceName="GetCustomer360",OperationName="GetDataOperation",ServiceInstance="GetCustomer360:GetDataOperation",} 1.0
bwdefinitions:service{ProcessName="t1.module.sub.orchestratorSubFlow",ServiceName="GetCustomer360",OperationName="GetDataOperation",ServiceInstance="GetCustomer360:GetDataOperation",} 1.0
bwdefinitions:service{ProcessName="t1.module.Process",ServiceName="GetCustomer360",OperationName="GetDataOperation",ServiceInstance="GetCustomer360:GetDataOperation",} 1.0
# HELP bwdefinitions:gateway Repositorio de tiempo de diseño BW - definición de puerta de enlace
# TYPE bwdefinitions:gateway counter
bwdefinitions:gateway{ServiceName="GetCustomer360",OperationName="GetDataOperation",ServiceInstance="GetCustomer360:GetDataOperation",Endpoint="bwce-demo-mon-orchestrator-bwce",InteractionType="ISTIO",} 1.0
# HELP process_cpu_seconds_total Tiempo total de usuario y sistema de CPU gastado en segundos.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 1956.86
# HELP process_start_time_seconds Hora de inicio del proceso desde la época de Unix en segundos.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.604712447107E9
# HELP process_open_fds Número de descriptores de archivo abiertos.
# TYPE process_open_fds gauge
process_open_fds 763.0
# HELP process_max_fds Número máximo de descriptores de archivo abiertos.
# TYPE process_max_fds gauge
process_max_fds 1048576.0
# HELP process_virtual_memory_bytes Tamaño de la memoria virtual en bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 3.046207488E9
# HELP process_resident_memory_bytes Tamaño de la memoria residente en bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 4.2151936E8
# HELP jvm_gc_collection_seconds Tiempo gastado en un recolector de basura JVM dado en segundos.
# TYPE jvm_gc_collection_seconds summary
jvm_gc_collection_seconds_count{gc="G1 Young Generation",} 540.0
jvm_gc_collection_seconds_sum{gc="G1 Young Generation",} 4.754
jvm_gc_collection_seconds_count{gc="G1 Old Generation",} 2.0
jvm_gc_collection_seconds_sum{gc="G1 Old Generation",} 0.563

# HELP jvm_threads_current Conteo actual de hilos de una JVM
# TYPE jvm_threads_current gauge
jvm_threads_current 98.0
# HELP jvm_threads_daemon Conteo de hilos daemon de una JVM
# TYPE jvm_threads_daemon gauge
jvm_threads_daemon 43.0
# HELP jvm_threads_peak Conteo máximo de hilos de una JVM
# TYPE jvm_threads_peak gauge
jvm_threads_peak 98.0
# HELP jvm_threads_started_total Conteo de hilos iniciados de una JVM
# TYPE jvm_threads_started_total counter
jvm_threads_started_total 109.0
# HELP jvm_threads_deadlocked Ciclos de hilos JVM que están en deadlock esperando adquirir monitores de objetos o sincronizadores propios
# TYPE jvm_threads_deadlocked gauge
jvm_threads_deadlocked 0.0
# HELP jvm_threads_deadlocked_monitor Ciclos de hilos JVM que están en deadlock esperando adquirir monitores de objetos
# TYPE jvm_threads_deadlocked_monitor gauge
jvm_threads_deadlocked_monitor 0.0

Entonces, puede ser un 50% de la respuesta del punto de acceso de métricas la parte que no estoy usando, entonces, ¿por qué estoy usando espacio en disco que estoy pagando para almacenarlo? Y esto es solo para un «exportador crítico», uno que trato de usar tanta información como sea posible, pero piensa en cuántos exportadores tienes y cuánta información usas para cada uno de ellos.

Ok, entonces ahora el propósito y la motivación de esta publicación están claros, pero ¿qué podemos hacer al respecto?

Descubriendo la API REST

Prometheus tiene una increíble API REST para exponer toda la información que puedas desear. Si alguna vez has usado la Interfaz Gráfica para Prometheus (mostrada a continuación) estás usando la API REST porque esto es lo que está detrás de ella.

Prometheus Storage: ¿Cómo optimizar el uso del disco?
Vista de destino de la Interfaz Gráfica de Prometheus

Tenemos toda la documentación sobre la API REST en la documentación oficial de Prometheus:

https://prometheus.io/docs/prometheus/latest/querying/api/

Pero, ¿qué nos proporciona esta API en términos de la base de datos de series temporales TSDB que utiliza Prometheus?

APIs de Administración de TSDB

Tenemos una API específica para gestionar el rendimiento de la base de datos TSDB, pero para poder usarla, necesitamos habilitar la API de Administración. Y eso se hace proporcionando la siguiente bandera donde estamos lanzando el servidor Prometheus --web.enable-admin-api.

Si estamos usando el Prometheus Operator Helm Chart para desplegar esto, necesitamos usar el siguiente elemento en nuestro values.yaml

## EnableAdminAPI habilita la API HTTP administrativa de Prometheus, que incluye funcionalidades como eliminar series temporales.    
## Esto está deshabilitado por defecto.
## ref: https://prometheus.io/docs/prometheus/latest/querying/api/#tsdb-admin-apis
## enableAdminAPI: true

Tenemos muchas opciones habilitadas cuando habilitamos esta API administrativa, pero hoy nos vamos a centrar en una sola operación REST que es el «stats». Este es el único método relacionado con TSDB que no requiere habilitar la API de Administración. Esta operación, como podemos leer en la documentación de Prometheus, devuelve los siguientes elementos:

headStats: Esto proporciona los siguientes datos sobre el bloque principal de la TSDB:

  • numSeries: El número de series.
  • chunkCount: El número de fragmentos.
  • minTime: La marca de tiempo mínima actual en milisegundos.
  • maxTime: La marca de tiempo máxima actual en milisegundos.

seriesCountByMetricName: Esto proporcionará una lista de nombres de métricas y su conteo de series.

labelValueCountByLabelName: Esto proporcionará una lista de nombres de etiquetas y su conteo de valores.

memoryInBytesByLabelName Esto proporcionará una lista de nombres de etiquetas y la memoria utilizada en bytes. El uso de memoria se calcula sumando la longitud de todos los valores para un nombre de etiqueta dado.

seriesCountByLabelPair Esto proporcionará una lista de pares de valores de etiquetas y su conteo de series.

Para acceder a esa API, necesitamos acceder al siguiente punto de acceso:

GET /api/v1/status/tsdb

Entonces, cuando hago eso en mi implementación de Prometheus, obtengo algo similar a esto:

{
"status":"success",
"data":{
"seriesCountByMetricName":[
{
"name":"apiserver_request_duration_seconds_bucket",
"value":34884
},
{
"name":"apiserver_request_latencies_bucket",
"value":7344
},
{
"name":"etcd_request_duration_seconds_bucket",
"value":6000
},
{
"name":"apiserver_response_sizes_bucket",
"value":3888
},
{
"name":"apiserver_request_latencies_summary",
"value":2754
},
{
"name":"etcd_request_latencies_summary",
"value":1500
},
{
"name":"apiserver_request_count",
"value":1216
},
{
"name":"apiserver_request_total",
"value":1216
},
{
"name":"container_tasks_state",
"value":1140
},
{
"name":"apiserver_request_latencies_count",
"value":918
}
],
"labelValueCountByLabelName":[
{
"name":"__name__",
"value":2374
},
{
"name":"id",
"value":210
},
{
"name":"mountpoint",
"value":208
},
{
"name":"le",
"value":195
},
{
"name":"type",
"value":185
},
{
"name":"name",
"value":181
},
{
"name":"resource",
"value":170
},
{
"name":"secret",
"value":168
},
{
"name":"image",
"value":107
},
{
"name":"container_id",
"value":97
}
],
"memoryInBytesByLabelName":[
{
"name":"__name__",
"value":97729
},
"name":"id",
"value":21450
},
{
"name":"mountpoint",
"value":18123
},
{
"name":"name",
"value":13831
},
{
"name":"image",
"value":8005
},
{
"name":"container_id",
"value":7081
},
{
"name":"image_id",
"value":6872
},
{
"name":"secret",
"value":5054
},
{
"name":"type",
"value":4613
},
{
"name":"resource",
"value":3459
}
],
"seriesCountByLabelValuePair":[
{
"name":"namespace=default",
"value":72064
},
{
"name":"service=kubernetes",
"value":70921
},
{
"name":"endpoint=https",
"value":70917
},
{
"name":"job=apiserver",
"value":70917
},
{
"name":"component=apiserver",
"value":57992
},
{
"name":"instance=192.168.185.199:443",
"value":40343
},
{
"name":"__name__=apiserver_request_duration_seconds_bucket",
"value":34884
},
{
"name":"version=v1",
"value":31152
},
{
"name":"instance=192.168.112.31:443",
"value":30574
},
{
"name":"scope=cluster",
"value":29713
}
]
}
}

También podemos verificar la misma información si usamos la nueva y experimental Interfaz de Usuario React en el siguiente punto de acceso:

/new/tsdb-status
Prometheus Storage: ¿Cómo optimizar el uso del disco?
Visualización gráfica del conteo de las 10 series principales por nombre de métrica en la nueva interfaz de usuario de Prometheus

Entonces, con eso, obtendrás las 10 series y etiquetas principales que están dentro de tu base de datos de series temporales, por lo que en caso de que algunas de ellas no sean útiles, puedes simplemente deshacerte de ellas usando los enfoques normales para eliminar una serie o una etiqueta. Esto es genial, pero ¿qué pasa si todas las que se muestran aquí son relevantes, qué podemos hacer al respecto?

Mmmm, tal vez podamos usar PromQL para monitorear esto (enfoque de dogfooding). Así que si quisiéramos extraer la misma información pero usando PromQL, podemos hacerlo con la siguiente consulta:

topk(10, count by (__name__)({__name__=~".+"}))
Prometheus Storage: ¿Cómo optimizar el uso del disco?
Top 10 de series de métricas generadas y almacenadas en la base de datos de series temporales

Y ahora tenemos todo el poder en mis manos. Por ejemplo, echemos un vistazo no a las 10 más relevantes, sino a las 100 más relevantes o cualquier otro filtro que necesitemos aplicar. Por ejemplo, veamos las métricas relacionadas con la JVM que discutimos al principio. Y lo haremos con la siguiente consulta PromQL:

topk(100, count by (__name__)({__name__=~"jvm.+"}))
Prometheus Storage: ¿Cómo optimizar el uso del disco?
Top 100 de series de métricas relacionadas con métricas de JVM

Así que podemos ver que tenemos al menos 150 series relacionadas con métricas que no estoy usando en absoluto. Pero hagámoslo aún mejor, echemos un vistazo a lo mismo pero agrupado por nombres de trabajos:

topk(10, count by (job,__name__)({__name__=~".+"}))
Prometheus Storage: ¿Cómo optimizar el uso del disco?
Resultado de verificar el conteo de las 10 series de métricas principales con el trabajo que las está generando

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Almacenamiento Prometheus: ¿Cómo funciona y por qué es importante?

Almacenamiento Prometheus: ¿Cómo funciona y por qué es importante?

Aprende las bases que hacen de Prometheus una gran solución para monitorear tus cargas de trabajo y úsalo para tu propio beneficio.

Prometheus es uno de los sistemas clave en las arquitecturas de nube actuales. El segundo proyecto graduado de la Cloud Native Computing Foundation (CNCF) después de Kubernetes, y es la solución de monitoreo por excelencia en la mayoría de las cargas de trabajo que se ejecutan en Kubernetes.

Si ya has usado Prometheus por algún tiempo, sabes que se basa en una base de datos de series temporales, por lo que el almacenamiento de Prometheus es uno de los elementos clave. Basado en sus propias palabras de la página oficial de Prometheus:

Cada serie temporal se identifica de manera única por su nombre de métrica y pares clave-valor opcionales llamados etiquetas, y esa serie es similar a las tablas en un modelo relacional. Y dentro de cada una de esas series, tenemos muestras que son similares a las tuplas. Y cada una de las muestras contiene un valor flotante y una marca de tiempo con precisión de milisegundos.

Enfoque predeterminado en disco

Por defecto, Prometheus utiliza un enfoque de almacenamiento local guardando todas esas muestras en disco. Estos datos se distribuyen en diferentes archivos y carpetas para agrupar diferentes fragmentos de datos.

Así que, tenemos carpetas para crear esos grupos, y por defecto, son un bloque de dos horas y pueden contener uno o más archivos dependiendo de la cantidad de datos ingeridos en ese período de tiempo, ya que cada carpeta contiene todas las muestras para esa línea de tiempo específica.

Además, cada carpeta también tiene algún tipo de archivos de metadatos que ayudan a localizar las métricas de cada uno de los archivos de datos.

Un archivo es persistente de manera completa cuando el bloque ha terminado, y antes de eso, se mantiene en memoria y utiliza una técnica de registro de escritura anticipada para recuperar los datos en caso de un fallo del servidor de Prometheus.

Así que, a un nivel alto, la estructura de directorios del directorio de datos de un servidor de Prometheus se verá algo así:

Integración de Almacenamiento Remoto

El almacenamiento predeterminado en disco es bueno y tiene algunas limitaciones en términos de escalabilidad y durabilidad, incluso considerando la mejora de rendimiento de la última versión de TSDB. Así que, si queremos explorar otras opciones para almacenar estos datos, Prometheus proporciona una manera de integrarse con ubicaciones de almacenamiento remoto.

Proporciona una API que permite escribir muestras que se están ingiriendo en una URL remota y, al mismo tiempo, poder leer datos de muestra para esa URL remota como se muestra en la imagen a continuación:

Como siempre en cualquier cosa relacionada con Prometheus, el número de adaptadores creados usando este patrón es enorme, y se puede ver en el siguiente enlace en detalle:

Resumen

Saber cómo funciona el almacenamiento de Prometheus es crítico para entender cómo podemos optimizar su uso para mejorar el rendimiento de nuestra solución de monitoreo y proporcionar un despliegue rentable.

En las siguientes publicaciones, vamos a cubrir cómo podemos optimizar el uso de esta capa de almacenamiento, asegurándonos de que solo se almacenen las métricas y muestras que son importantes para usar, y también cómo analizar cuáles métricas son las más utilizadas de la base de datos de series temporales para poder tomar buenas decisiones sobre qué métricas deben ser eliminadas y cuáles deben mantenerse.

Así que, mantente atento a la próxima publicación sobre cómo podemos tener una mejor vida con Prometheus y no morir en el intento.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Métricas de Prometheus: ¿Cómo cambiar el nombre de la métrica?

Métricas de Prometheus: ¿Cómo cambiar el nombre de la métrica?

Encuentra una manera de redefinir y reorganizar el nombre de tus métricas de Prometheus para cumplir con tus requisitos

Prometheus se ha convertido en el nuevo estándar cuando hablamos de monitorear nuestra nueva arquitectura de aplicaciones modernas, y necesitamos asegurarnos de conocer todas sus opciones para asegurarnos de obtener lo mejor de él. Lo he estado usando durante algún tiempo hasta que me di cuenta de una característica que estaba desesperado por saber cómo hacer, pero no pude encontrar en ningún lugar claramente definido. Así que como no lo encontré fácilmente, pensé en escribir un pequeño artículo para mostrarte cómo hacerlo sin necesidad de gastar el mismo tiempo que yo.

Tenemos mucha información sobre cómo configurar Prometheus y usar algunos de los complementos de configuración habituales, como podemos ver en su página web oficial [1]. Incluso ya escribí sobre alguna configuración y usándolo para varios propósitos, como también puedes ver en otras publicaciones [2][3][4].

Uno de estos complementos de configuración es sobre el reetiquetado, y esto es algo genial. Tenemos que cada uno de los exportadores puede tener sus etiquetas y significado para ellas, y cuando intentas gestionar diferentes tecnologías o componentes hace complejo que todos ellos coincidan juntos incluso si todos ellos siguen la convención de nombres que tiene Prometheus [5].

Pero tuve esta situación, y estoy seguro de que tú también has pasado o pasarás por eso, que tengo métricas similares para diferentes tecnologías que para mí son las mismas, y necesito mantenerlas con el mismo nombre, pero como pertenecen a otras tecnologías no lo son. Así que necesito encontrar una manera de renombrar la métrica, y lo genial es que puedes hacer eso.

Para hacer eso, solo necesitas hacer una configuración de metric_relabel. Esta configuración se aplica para reetiquetar (como el nombre ya indica) etiquetas de tus métricas de prometheus en este caso antes de ser ingeridas, pero también nos permite usar algunos términos notables para hacer diferentes cosas, y uno de estos términos notables es __name__. __name__ es una etiqueta particular que te permitirá renombrar tus métricas de prometheus antes de ser ingeridas en la Base de Datos de Series Temporales de Prometheus. Y después de ese punto, esto será como si tuviera ese nombre desde el principio.

Cómo usar eso es relativamente fácil, es como cualquier otro proceso de reetiquetado, y me gustaría mostrarte un ejemplo sobre cómo hacerlo.

- source_labels: [__name__]
regex:  'jvm_threads_current'
target_label: __name__
replacement: 'process_thread_count'

Aquí hay un ejemplo simple para mostrar cómo podemos renombrar un nombre de métrica jvm_threads_current para contar los hilos dentro de la máquina JVM para hacerlo más genérico y poder incluir los hilos para el proceso en una métrica de prometheus process_thread_count que ahora podemos usar como si fuera el nombre original.


Referencias

[1] Prometheus: Configuración https://prometheus.io/docs/prometheus/latest/configuration/configuration/

[2] https://medium.com/@alexandrev/prometheus-monitoring-in-tibco-cloud-integration-96a6811416ce

[3] https://medium.com/@alexandrev/prometheus-monitoring-for-microservices-using-tibco-772018d093c4

[4] https://medium.com/@alexandrev/kubernetes-service-discovery-for-prometheus-fcab74237db6

[5] Prometheus: Nomenclatura de Métricas y Etiquetas https://prometheus.io/docs/practices/naming/

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Monitoreo de Prometheus en TIBCO Cloud Integration

Monitoreo de Prometheus en TIBCO Cloud Integration

En publicaciones anteriores, he explicado cómo integrar aplicaciones de TIBCO BusinessWorks 6.x / BusinessWorks Container Edition (BWCE) con Prometheus, uno de los sistemas de monitoreo más populares para capas en la nube. Prometheus es una de las soluciones más utilizadas para monitorear tus microservicios dentro de un clúster de Kubernetes. En esta publicación, explicaré los pasos para aprovechar Prometheus para integrarse con aplicaciones que se ejecutan en TIBCO Cloud Integration (TCI).

TCI es el iPaaS de TIBCO y principalmente oculta la complejidad de gestión de aplicaciones de una app para los usuarios. Necesitas tu aplicación empaquetada (también conocida como EAR) y manifest.json, ambos generados por el producto para simplemente desplegar la aplicación.

¿No es mágico? ¡Sí, lo es! Como expliqué en mi publicación anterior relacionada con la integración de Prometheus con BWCE, que te permite personalizar tus imágenes base, TCI permite la integración con Prometheus de una manera ligeramente diferente. Vamos a recorrer los pasos.

TCI tiene sus propias herramientas de monitoreo integradas (mostradas a continuación) para proporcionar información sobre la utilización de Memoria y CPU, además del rendimiento de la red, lo cual es muy útil.

Aunque las métricas de monitoreo proporcionadas de fábrica por TCI son suficientes para la mayoría de los escenarios, hay casos de uso de conectividad híbrida (aplicación ejecutándose en las instalaciones y microservicios ejecutándose en tu propio clúster que podría estar en una nube privada o pública) que podrían requerir una vista unificada de monitoreo.

Paso uno es importar el plugin de Prometheus desde la ubicación actual de GitHub a tu espacio de trabajo de BusinessStudio. Para hacer eso, solo necesitas clonar el Repositorio de GitHub disponible aquí: https://github.com/TIBCOSoftware/bw-tooling O https://github.com/alexandrev/bw-tooling

Importa el plugin de Prometheus eligiendo la opción Importar → Plug-ins y Fragmentos y especificando el directorio descargado de la ubicación de GitHub mencionada anteriormente. (mostrado abajo)

Monitoreo de Prometheus en TIBCO Cloud Integration
Monitoreo de Prometheus en TIBCO Cloud Integration

Paso dos implica agregar el módulo de Prometheus previamente importado a la aplicación específica como se muestra a continuación:

Monitoreo de Prometheus en TIBCO Cloud Integration

Paso tres es simplemente construir el archivo EAR junto con manifest.json.

NOTA: Si el EAR no se genera una vez que agregas el plugin de Prometheus, por favor sigue los pasos a continuación:

  • Exporta el proyecto con el módulo de Prometheus a un archivo zip.
  • Elimina el proyecto de Prometheus del espacio de trabajo.
  • Importa el proyecto desde el archivo zip generado antes.

Antes de desplegar la aplicación BW en TCI, necesitamos habilitar un puerto adicional en TCI para extraer las métricas de Prometheus.

Paso cuatro Actualización del archivo manifest.json.

Por defecto, una app de TCI que usa el archivo manifest.json solo expone un puerto para ser consumido desde afuera (relacionado con servicios funcionales) y otro para ser usado internamente para verificaciones de salud.

Monitoreo de Prometheus en TIBCO Cloud Integration

Para la integración de Prometheus con TCI, necesitamos un puerto adicional escuchando en 9095, para que el servidor de Prometheus pueda acceder a los endpoints de métricas para extraer las métricas requeridas para nuestra aplicación TCI.

Nota: Este documento no cubre los detalles sobre la configuración del servidor de Prometheus (NO es necesario para este PoC) pero puedes encontrar la información relevante en https://prometheus.io/docs/prometheus/latest/installation/

Necesitamos modificar ligeramente el archivo manifest.json generado (de la app BW) para exponer un puerto adicional, 9095 (mostrado abajo).

Monitoreo de Prometheus en TIBCO Cloud Integration

Además, para decirle a TCI que queremos habilitar el endpoint de Prometheus necesitamos establecer una propiedad en el archivo manifest.json. La propiedad es TCI_BW_CONFIG_OVERRIDES y proporciona el siguiente valor: BW_PROMETHEUS_ENABLE=true, como se muestra a continuación:

Monitoreo de Prometheus en TIBCO Cloud Integration

También necesitamos agregar una línea adicional (propertyPrefix) en el archivo manifest.json como se muestra a continuación.

Monitoreo de Prometheus en TIBCO Cloud Integration

Ahora, estamos listos para desplegar la aplicación BW en TCI y una vez que esté desplegada podemos ver que hay dos endpoints

Monitoreo de Prometheus en TIBCO Cloud Integration

Si expandimos las opciones de Endpoints a la derecha (mostrado arriba), puedes ver que uno de ellos se llama “prometheus” y ese es nuestro endpoint de métricas de Prometheus:

Simplemente copia la URL de prometheus y añádela con /metrics (URL en la captura de pantalla a continuación) — esto mostrará las métricas de Prometheus para la aplicación BW específica desplegada en TCI.

Nota: añadir /metrics no es obligatorio, la URL tal cual para el endpoint de Prometheus también funcionará.

Monitoreo de Prometheus en TIBCO Cloud Integration

En la lista encontrarás el siguiente tipo de métricas para poder crear los dashboards y análisis más increíbles basados en ese tipo de información:

  • Métricas JVM sobre memoria utilizada, rendimiento de GC y conteos de pools de hilos
  • Uso de CPU por la aplicación
  • Conteos de ejecución de Procesos y Actividades por Estado (Iniciado, Completado, Fallido, Programado..)
  • Duración por Actividad y Proceso.

Con toda esta información disponible puedes crear dashboards similares al que se muestra a continuación, en este caso usando Spotfire como la herramienta de Dashboard:

Monitoreo de Prometheus en TIBCO Cloud Integration

Pero también puedes integrar esas métricas con Grafana o cualquier otra herramienta que pueda leer datos de la base de datos de series temporales de Prometheus.

Monitoreo de Prometheus en TIBCO Cloud Integration

Descubrimiento de servicios de Kubernetes para Prometheus

Descubrimiento de servicios de Kubernetes para Prometheus
En publicaciones anteriores, describimos cómo configurar Prometheus para trabajar con tus aplicaciones de TIBCO BusinessWorks Container Edition, y puedes leer más al respecto aquí. En esa publicación, describimos que había varias formas de actualizar a Prometheus sobre los servicios que están listos para monitorear. Y elegimos la más simple en ese momento que era la configuración de static_config, lo que significa:
No te preocupes Prometheus, te haré saber la IP que necesitas monitorear y no necesitas preocuparte por nada más.
Y esto es útil para una prueba rápida en un entorno local cuando quieres probar rápidamente tu configuración de Prometheus o quieres trabajar en la parte de Grafana para diseñar el mejor tablero posible para manejar tus necesidades. Pero, esto no es muy útil para un entorno de producción real, aún más, cuando estamos hablando de un clúster de Kubernetes donde los servicios están subiendo y bajando continuamente con el tiempo. Entonces, para resolver esta situación, Prometheus nos permite definir diferentes tipos de formas para realizar este enfoque de «descubrimiento de servicios». En la documentación oficial de Prometheus, podemos leer mucho sobre las diferentes técnicas de descubrimiento de servicios, pero a un nivel alto, estas son las principales técnicas de descubrimiento de servicios disponibles:
  • azure_sd_configs: Descubrimiento de Servicios de Azure
  • consul_sd_configs: Descubrimiento de Servicios de Consul
  • dns_sd_configs: Descubrimiento de Servicios de DNS
  • ec2_sd_configs: Descubrimiento de Servicios de EC2
  • openstack_sd_configs: Descubrimiento de Servicios de OpenStack
  • file_sd_configs: Descubrimiento de Servicios de Archivo
  • gce_sd_configs: Descubrimiento de Servicios de GCE
  • kubernetes_sd_configs: Descubrimiento de Servicios de Kubernetes
  • marathon_sd_configs: Descubrimiento de Servicios de Marathon
  • nerve_sd_configs: Descubrimiento de Servicios de Nerve de AirBnB
  • serverset_sd_configs: Descubrimiento de Servicios de Serverset de Zookeeper
  • triton_sd_configs: Descubrimiento de Servicios de Triton
  • static_config: IP/DNS Estático para la configuración. Sin Descubrimiento de Servicios.
E incluso, si todas estas opciones no son suficientes para ti y necesitas algo más específico, tienes una API disponible para extender las capacidades de Prometheus y crear tu propia técnica de Descubrimiento de Servicios. Puedes encontrar más información al respecto aquí: Pero este no es nuestro caso, para nosotros, el Descubrimiento de Servicios de Kubernetes es la elección correcta para nuestro enfoque. Así que, vamos a cambiar la configuración estática que teníamos en la publicación anterior:
- job_name: 'bwdockermonitoring'
  honor_labels: true
  static_configs:
    - targets: ['phenix-test-project-svc.default.svc.cluster.local:9095']
      labels:
        group: 'prod'
Por esta configuración de Kubernetes
- job_name: 'bwce-metrics'
  scrape_interval: 5s
  metrics_path: /metrics/
  scheme: http
  kubernetes_sd_configs:
  - role: endpoints
    namespaces:
      names:
      - default
  relabel_configs:
  - source_labels: [__meta_kubernetes_service_label_app]
    separator: ;
    regex: (.*)
    replacement: $1
    action: keep
  - source_labels: [__meta_kubernetes_endpoint_port_name]
    separator: ;
    regex: prom
    replacement: $1
    action: keep
  - source_labels: [__meta_kubernetes_namespace]
    separator: ;
    regex: (.*)
    target_label: namespace
    replacement: $1
    action: replace
  - source_labels: [__meta_kubernetes_pod_name]
    separator: ;
    regex: (.*)
    target_label: pod
    replacement: $1
    action: replace
  - source_labels: [__meta_kubernetes_service_name]
    separator: ;
    regex: (.*)
    target_label: service
    replacement: $1
    action: replace
  - source_labels: [__meta_kubernetes_service_name]
    separator: ;
    regex: (.*)
    target_label: job
    replacement: 1
    action: replace
  - separator: ;
    regex: (.*)
    target_label: endpoint
    replacement: $1
    action: replace
Como puedes ver, esto es bastante más complejo que la configuración anterior, pero no es tan complejo como podrías pensar a primera vista, revisémoslo por diferentes partes.
- role: endpoints
    namespaces:
      names:
      - default
Dice que vamos a usar el rol para los endpoints que se crean bajo el namespace por defecto y vamos a especificar los cambios que necesitamos hacer para encontrar los endpoints de métricas para Prometheus.
scrape_interval: 5s
 metrics_path: /metrics/
 scheme: http
Esto dice que vamos a ejecutar el proceso de scrape en un intervalo de 5 segundos, usando http en la ruta /metrics/ Y luego, tenemos una sección de relabel_config:
- source_labels: [__meta_kubernetes_service_label_app]
    separator: ;
    regex: (.*)
    replacement: $1
    action: keep
  - source_labels: [__meta_kubernetes_endpoint_port_name]
    separator: ;
    regex: prom
    replacement: $1
    action: keep
Eso significa que nos gustaría mantener esa etiqueta para prometheus:
- source_labels: [__meta_kubernetes_namespace]
    separator: ;
    regex: (.*)
    target_label: namespace
    replacement: $1
    action: replace
  - source_labels: [__meta_kubernetes_pod_name]
    separator: ;
    regex: (.*)
    target_label: pod
    replacement: $1
    action: replace
  - source_labels: [__meta_kubernetes_service_name]
    separator: ;
    regex: (.*)
    target_label: service
    replacement: $1
    action: replace
  - source_labels: [__meta_kubernetes_service_name]
    separator: ;
    regex: (.*)
    target_label: job
    replacement: 1
    action: replace
  - separator: ;
    regex: (.*)
    target_label: endpoint
    replacement: $1
    action: replace
Eso significa que queremos hacer un reemplazo del valor de la etiqueta y podemos hacer varias cosas:
  • Renombrar el nombre de la etiqueta usando el target_label para establecer el nombre de la etiqueta final que vamos a crear basado en las source_labels.
  • Reemplazar el valor usando el parámetro regex para definir la expresión regular para el valor original y el parámetro replacement que va a expresar los cambios que queremos hacer a este valor.
Así que, ahora después de aplicar esta configuración cuando despleguemos una nueva aplicación en nuestro clúster de Kubernetes, como el proyecto que podemos ver aquí: Automáticamente vamos a ver un objetivo adicional en nuestra configuración de job-name “bwce-metrics”

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.