{"id":429,"date":"2025-03-20T18:07:49","date_gmt":"2025-03-20T17:07:49","guid":{"rendered":"https:\/\/www.pythonparatodo.com\/?p=429"},"modified":"2025-03-21T06:51:43","modified_gmt":"2025-03-21T05:51:43","slug":"consumir-metricas-de-windows_exporter","status":"publish","type":"post","link":"https:\/\/www.pythonparatodo.com\/?p=429","title":{"rendered":"Consumir m\u00e9tricas con Windows_exporter"},"content":{"rendered":"\n<p><a href=\"https:\/\/github.com\/prometheus-community\/windows_exporter\">Windows_exporter<\/a> es una herramienta de Prometheus que sirve para extraer m\u00e9tricas de sistemas Windows. <a href=\"https:\/\/prometheus.io\" target=\"_blank\" rel=\"noreferrer noopener\">Prometheus<\/a> es el software encargado de tratar estas m\u00e9tricas y con <a href=\"https:\/\/grafana.com\" target=\"_blank\" rel=\"noreferrer noopener\">Grafana<\/a> podemos usar Dashboard para verlas. En este art\u00edculo veremos c\u00f3mo, desde Python 3, podemos consumir y analizar estas m\u00e9tricas para integrarlas en nuestros propios scripts o aplicaciones.<\/p>\n\n\n\n<p><strong>\u00bfQu\u00e9 es Windows_exporter?<\/strong><\/p>\n\n\n\n<p>Windows_exporter es un agente que se instala en sistemas Windows y recopila informaci\u00f3n sobre el sistema (como uso de CPU, RAM, disco, red y otros) estos datos son expuestos en formato HTTP por lo que cuando el agente entre en funcionamiento los encontraremos en http:\/\/localhost:9182\/metrics.<\/p>\n\n\n\n<p><strong>\u00bfPor qu\u00e9 leer m\u00e9tricas con Python?<\/strong><\/p>\n\n\n\n<p>Si usamos Python para leer estas m\u00e9tricas tendremos ciertas ventajas. <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>No necesitamos un servidor central con Prometheus y Grafana instalado.<\/li>\n\n\n\n<li>Integramos la monitorizaci\u00f3n en nuestras aplicaciones.<\/li>\n\n\n\n<li>Procesamos y transformamos los datos para hacer reportes personalizados.<\/li>\n\n\n\n<li>Nuestras aplicaciones pueden realizar acciones basadas en ciertos umbrales o condiciones de los datos.<\/li>\n<\/ul>\n\n\n\n<p><strong>\u00bfQu\u00e9 necesitaremos para hacer nuestros scripts o aplicaciones?<\/strong><\/p>\n\n\n\n<p>Descargar la \u00faltima versi\u00f3n de Windows_exporter que podremos encontrar aqu\u00ed: <a href=\"https:\/\/github.com\/prometheus-community\/windows_exporter\/releases\/latest\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">https:\/\/github.com\/prometheus-community\/windows_exporter\/<\/a><a href=\"https:\/\/github.com\/prometheus-community\/windows_exporter\/releases\/latest\" target=\"_blank\" rel=\"noreferrer noopener\">releases<\/a><a href=\"https:\/\/github.com\/prometheus-community\/windows_exporter\/releases\/latest\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">\/latest<\/a>. Existen dos versiones una .exe que se ejecuta directamente y que aconsejo para pruebas y otra .msi que funcionar\u00e1 como un servicio de Windows.<\/p>\n\n\n\n<p><strong>Seguridad<\/strong><\/p>\n\n\n\n<p>En cuanto iniciemos Windows_exporter dispondremos de todas las m\u00e9tricas en http:\/\/localhost:9182\/metrics, dado que no dispone de ninguna opci\u00f3n nativa para limitar el acceso a estas m\u00e9tricas, podemos usar nuestro firewall para limitar el acceso externo al puerto 9182 o incluso limitar las direcciones IP de los equipos que tendr\u00e1n acceso a estas m\u00e9tricas. <\/p>\n\n\n\n<p><strong>Requisitos previos<\/strong><\/p>\n\n\n\n<p>Para leer las m\u00e9tricas debemos tener instalada la biblioteca requests. Podemos hacerlo con:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">pip install requests --upgrade<\/code><\/pre>\n\n\n\n<p><strong>Ejemplo<\/strong><\/p>\n\n\n\n<p>El siguiente ejemplo obtiene todas las m\u00e9tricas, de hecho obtiene tanto m\u00e9tricas como comentarios, para su posterior procesado. Es muy importante <strong>ejecutar el programa windows_exporter<\/strong> previamente para obtener los resultados.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">import requests\n\ndef obtener_metricas(url):\n    try:\n        respuesta = requests.get(url)\n        respuesta.raise_for_status()\n        return respuesta.text\n    except requests.exceptions.RequestException as e:\n        print(f'Error al obtener las m\u00e9tricas: {e}')\n        return None\n\nurl_metricas = 'http:\/\/localhost:9182\/metrics'\ndatos_metricas = obtener_metricas(url_metricas)\n\nif datos_metricas:\n    print('M\u00e9tricas obtenidas correctamente.')\n    print(f'Las m\u00e9tricas son: {datos_metricas}')\nelse:\n    print('No se pudieron obtener las m\u00e9tricas.')<\/code><\/pre>\n\n\n\n<p>La funci\u00f3n<strong> obtener_metricas(url)<\/strong> recibe el par\u00e1metro <strong>url <\/strong>que se corresponde con la <strong>url <\/strong>donde est\u00e1 ejecutandose <strong>windows_exporter<\/strong>, en el caso de ser nuestro propio equipo ser\u00e1 http:\/\/localhost:9182\/metrics y en el caso de ser un equipo en la red cuya direcci\u00f3n ip sea la 192.168.0.10 ser\u00e1 http:\/\/192.268.0.10:9182\/metrics.  La variable <strong>respuesta <\/strong>se convierte en una instancia de la clase <strong>requests.models.Response<\/strong> al usar <strong>requests.get(url)<\/strong> de la clase requests y contendr\u00e1 todos los m\u00e9todos y atributos de esta en referencia a la url proporcionada. Por ejemplo, si la operaci\u00f3n es incorrecta, el m\u00e9todo <strong>raise_for_status()<\/strong> mostrar\u00e1 un mensaje parecido a este: <em>404 Client Error: Not Found for url: http:\/\/localhost:9182\/metrics<\/em>. Si llamamos al atributo <strong>reason <\/strong>podremos ver <em>&#8216;Not Found&#8217;<\/em>, sin embargo si todo es correcto, <strong>raise_for_status() <\/strong>no mostrar\u00e1 nada y en <strong>reason <\/strong>veremos <strong>&#8216;OK&#8217;<\/strong>.<\/p>\n\n\n\n<p>El atributo text contiene el cuerpo del mensaje es decir todo el conjunto de m\u00e9tricas en el formato que usa Prometheus por lo que para poder usarlo deberemos convertirlos en algo diferente.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">def analizar_metricas(datos):\n    metricas = {}\n    for linea in datos.splitlines():\n        if linea.startswith('#') or not linea.strip():\n            continue\n        partes = linea.split()\n        if len(partes) == 2:\n            nombre, valor = partes\n            try:\n                metricas[nombre] = float(valor)\n            except ValueError:\n                continue\n    return metricas<\/code><\/pre>\n\n\n\n<p>Esta funci\u00f3n analiza las m\u00e9tricas, para ello va recorriendo los datos obtenidos anteriormente l\u00ednea a l\u00ednea, descartando las que comienzan con # ya que se trata de comentarios y diviendo el valor de la l\u00ednea en dos, uno es el nombre de la m\u00e9trica y el otro es el valor de la misma, convirtiendo el valor en float si se trata de un valor num\u00e9rico con el bloque try que producir\u00e1 una excepci\u00f3n y continuar\u00e1 si no es un n\u00famero o lo asignar\u00e1 al nombre si lo es. Finalmente devolver\u00e1 un diccionario con las m\u00e9tricas.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">if metricas:\n    print(f'RAM total: {metricas[\"windows_cs_physical_memory_bytes\"]\/(1024**3):.2f} GB')\n    print(f'RAM libre: {metricas[\"windows_os_physical_memory_free_bytes\"]\/(1024**3):.2f} GB')       \nelse:\n    print(\"No se encontraron m\u00e9tricas.\")<\/code><\/pre>\n\n\n\n<p>Finalmente, como ejemplo, si hay m\u00e9tricas buscamos las que contienen <strong>windows_cs_physical_memory_bytes<\/strong> que contiene el valor de la memoria f\u00edsica total y <strong>windows_os_physical_memory_free_bytes<\/strong> que contiene la cantidad de memoria libre.<\/p>\n\n\n\n<p>El c\u00f3digo del ejemplo completo es este:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">import requests\n\ndef obtener_metricas(url):\n    try:\n        respuesta = requests.get(url)\n        respuesta.raise_for_status()\n        return respuesta.text\n    except requests.exceptions.RequestException as e:\n        print(f'Error al obtener las m\u00e9tricas: {e}')\n        return None\n\ndef analizar_metricas(datos):\n    metricas = {}\n    for linea in datos.splitlines():\n        if linea.startswith('#') or not linea.strip():\n            continue\n        partes = linea.split()\n        if len(partes) == 2:\n            nombre, valor = partes\n            try:\n                metricas[nombre] = float(valor)\n            except ValueError:\n                continue\n    return metricas\n\nurl_metricas = 'http:\/\/localhost:9182\/metrics'\ndatos_metricas = obtener_metricas(url_metricas)\n\nmetricas = analizar_metricas(datos_metricas)\n\nif metricas:\n    print(f'RAM total: {metricas[\"windows_cs_physical_memory_bytes\"]\/(1024**3):.2f} GB')\n    print(f'RAM libre: {metricas[\"windows_os_physical_memory_free_bytes\"]\/(1024**3):.2f} GB')       \nelse:\n    print(\"No se encontraron m\u00e9tricas.\")<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Windows_exporter es una herramienta de Prometheus que sirve para extraer m\u00e9tricas de sistemas Windows. Prometheus es el software encargado de &hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[162,159,161,160],"class_list":["post-429","post","type-post","status-publish","format-standard","hentry","category-python","tag-metricas","tag-prometheus","tag-requests","tag-windows_exporter"],"_links":{"self":[{"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=\/wp\/v2\/posts\/429","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=429"}],"version-history":[{"count":13,"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=\/wp\/v2\/posts\/429\/revisions"}],"predecessor-version":[{"id":447,"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=\/wp\/v2\/posts\/429\/revisions\/447"}],"wp:attachment":[{"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=429"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=429"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pythonparatodo.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=429"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}