Taller fundamental 2 — Grafana: una fuente, un panel, un tablero de control

Práctica guiada17 min
Duración
20 min
Módulo
1/7
Requisitos previos
el labo lleva corriendo al menos dos minutos (etat muestra 8/8 cibles up), Grafana abierto en http://localhost:3000 con admin / aiopsatlas2026, el taller 1 hecho (sabes lo que devuelve count(up))
Vas a construir
un tablero de control de un solo panel, creado a mano en la interfaz, guardado, releído en JSON y después eliminado
Entregable
el bloque JSON del panel tal como Grafana lo guardó (paso 9), con tres palabras rodeadas: el tipo de visualización, la consulta, la fuente de datos

Cómo leer esta página. Diez pasos, un gesto a la vez. Para cada uno: dónde hacer clic, lo que Grafana muestra palabra por palabra, y lo que hay que mirar. Los rótulos de la interfaz están en inglés en Grafana 13.2.2 (el del kit); se citan tal cual, en negrita. Las cifras serán distintas en tu máquina; las formas (número de series, valor del panel, mensajes) deben ser las mismas. Los bloques «Para entender mejor» son opcionales. Si el labo no está iniciado, vuelve a la práctica guiada: la sección En resumen da los comandos, kit incluido (https://github.com/hrhouma2/aiopsatlas-observabilite-labo-fr). Todo lo que creas aquí se destruye en el paso 10: los tres tableros de control entregados con el kit no se tocan.

Objetivo

En la práctica guiada, escribiste ocho consultas en Explore y miraste tres tableros de control ya hechos. Así que sabes leer Grafana. Pero si te piden agregar una cifra en un tablero, ¿sabes por dónde empezar? Aquí, partes de cero y ensamblas tú mismo los tres objetos de Grafana, del más pequeño al más grande: una fuente de datos (Grafana no almacena nada, consulta a Prometheus), un panel (una consulta más una manera de dibujarla), un tablero de control (paneles ordenados en una cuadrícula, con un nombre y una dirección). Un paso es una trampa deliberada: rompes una consulta para ver cómo el error de Prometheus atraviesa Grafana. Al final, lees el JSON que Grafana escribió por ti, encuentras en él los tres objetos, y después lo eliminas todo.

El vocabulario en una imagen

Grafana es un marco de fotos digital. No toma ninguna foto: va a buscarlas a un fotógrafo (la fuente de datos: Prometheus, Loki) y las muestra. Cada foto es un panel: una pregunta hecha al fotógrafo (la consulta) y un formato de visualización (una cifra, una curva, un medidor). El marco en sí, con sus fotos dispuestas en una cuadrícula, es el tablero de control: tiene un nombre, una dirección, y se guarda en la base de Grafana en forma de documento JSON.

GrafanaBase SQL clásicaEn este taller
fuente de datos (data source)la conexión a la basePrometheus (http://prometheus:9090)
consulta (query)SELECT …count(up)
panel (panel)una vista guardadaCibles surveillées
visualizaciónla manera de mostrar el resultadoStat (una cifra grande)
tablero de control (dashboard)un informe que reúne varias vistasAtelier M1 - Cibles Prometheus
uidclave primariaadc947c (el tuyo será distinto)
JSON del tableroel esquema exportado del informepaso 9
carpeta (folder)esquema de la baseDashboards (la raíz); Labo observabilite para los tres del kit

Dónde hacer clic, y cómo leer una respuesta

Abre http://localhost:3000. El menú principal es el icono de tres líneas arriba a la izquierda: da acceso a Dashboards, Explore y Connections. La ruta de navegación arriba (por ejemplo Dashboards › New dashboard) dice siempre dónde estás. Cuando una acción tiene éxito, Grafana muestra durante unos segundos un aviso abajo a la derecha (un toast): Dashboard saved, Dashboard deleted. Cuando una consulta falla, muestra un cuadro rojo bajo el campo de consulta, con el mensaje de Prometheus copiado tal cual.

Una vez guardado el tablero, lo releerás en JSON por la API de Grafana. En PowerShell o en una terminal Linux, el mismo comando:

bash
curl -s -u admin:aiopsatlas2026 http://localhost:3000/api/dashboards/uid/<uid>

<uid> es el identificador que Grafana dio a tu tablero; lo leerás en la dirección de la página en el paso 8.

Paso 1 — Verificar la fuente de datos

Menú principal → ConnectionsData sources. Se listan tres fuentes: Alertmanager, Loki y Prometheus (marcada default). Haz clic en Prometheus. Se abre la página Settings, con Prometheus server URL rellenado: http://prometheus:9090. No cambies nada. Baja hasta el final y haz clic en Save & test.

text
Successfully queried the Prometheus API.
Next, you can start to visualize data by building a dashboard from scratch or by querying data in the Explore view.

Qué mirar: el aviso verde. Grafana acaba de enviar una consulta a Prometheus y Prometheus respondió. Es el primer objeto: una fuente de datos es una dirección y un tipo. La dirección es http://prometheus:9090 y no http://localhost:9090: Grafana corre en un contenedor, y desde ese contenedor, Prometheus se llama prometheus. Tu navegador, en cambio, lo alcanza por localhost:9090. Dos nombres para la misma máquina, según quién habla.

Para entender mejor: ¿quién creó estas tres fuentes?

Tú no. El kit las describe en grafana/provisioning/datasources/sources.yml y Grafana las lee al arrancar: es el provisioning. El archivo es corto, ábrelo: name: Prometheus, uid: prometheus, type: prometheus, url: http://prometheus:9090, isDefault: true. Sin ese archivo, lo primero que habría que hacer en un Grafana nuevo sería Add new data source, y escribirías esas cuatro líneas a mano. El uid: prometheus te servirá de nuevo en el paso 9: es por él que tu panel designará su fuente.

Paso 2 — Consultar la fuente en Explore

Menú principal → Explore. Arriba, el selector de fuente muestra Prometheus. A la derecha del campo, pasa a Code (y no Builder). Escribe:

promql
up

y después Run query (o Mayús+Enter).

text
up{instance="alertmanager:9093", job="alertmanager"}
up{instance="alloy:12345", job="alloy"}
up{instance="api:8000", job="api", service="api"}
up{instance="cadvisor:8080", job="cadvisor"}
up{instance="grafana:3000", job="grafana"}
up{instance="localhost:9090", job="prometheus"}
up{instance="loki:3100", job="loki"}
up{instance="node-exporter:9100", job="node-exporter"}

Qué mirar: ocho líneas en la leyenda bajo el gráfico, las ocho series del paso 2 del taller 1, en orden alfabético de instance. La consulta es exactamente la que escribiste en Prometheus; Grafana la transmitió y dibujó la respuesta. Explore es un borrador: nada se guarda ahí, es donde se pone a punto una consulta antes de colocarla en un panel.

Paso 3 — La trampa: un paréntesis de menos

Todavía en Explore, reemplaza la consulta por una versión incorrecta, a propósito:

promql
count(up

Run query:

text
bad_data: invalid parameter "query": 1:9: parse error: unclosed left parenthesis

Qué mirar: un cuadro rojo bajo el campo, y No data en el gráfico. El mensaje no es de Grafana: parse error y la posición 1:9 son de Prometheus, que aprendiste a leer en el taller 1. Grafana solo antepone bad_data:, la categoría de error devuelta por la API de Prometheus. Regla: cuando un panel de Grafana muestra un error PromQL, corregirlo primero en Prometheus (http://localhost:9090), después copiarlo en Grafana. Cierra el paréntesis, Run query: una sola línea en la leyenda, que Grafana nombra count(up) a falta de etiquetas (Prometheus, por su parte, escribía {}), en 8. Es la consulta que vas a colocar en tu panel.

Paso 4 — Crear un tablero de control vacío

Menú principal → Dashboards. La página lista una sola carpeta, Labo observabilite, que contiene los tres tableros del kit. Arriba a la derecha, NewNew dashboard.

text
New dashboard
Add a panel to visualize your data

Qué mirar: la ruta de navegación dice Dashboards › New dashboard, la página está vacía, y el botón Save ya está ahí arriba a la derecha. Nada está guardado todavía: si cierras la pestaña ahora, no queda nada. Un tablero de control solo existe a partir del momento en que se guarda (paso 8). A la derecha, un panel lateral Add propone Panel («Drag or click to add a panel»).

Paso 5 — Agregar un panel sin consulta

En el panel lateral Add, haz clic en Panel. Aparece un marco en la cuadrícula, titulado New panel, con el texto No visualization configured. A la derecha, el campo Title contiene New panel: reemplázalo por:

text
Cibles surveillées

Qué mirar: el título del marco cambia en directo. Tienes un panel, pero está vacío: ni consulta, ni visualización. Es el segundo objeto, reducido a su mínimo: una ubicación en la cuadrícula y un nombre. Haz clic en Edit visualization en el panel lateral: se abre la página Edit panel, con abajo la pestaña Queries 1 y, a la derecha, Suggestions / All visualizations.

Paso 6 — Colocar la consulta

En Queries, la línea A ya está ligada a Data source : Prometheus (la fuente por defecto). Pasa a Code, escribe en el campo Enter a PromQL query…:

promql
count(up)

y después Run queries (o Mayús+Enter).

text
Suggestions
Time series · Stat · Gauge · Bar gauge · Table · State timeline · Heatmap · Histogram

Qué mirar: el panel de la derecha cambia: bajo Suggestions, Grafana propone una decena de visualizaciones, y cada miniatura ya muestra tu dato: count(up) y 8. El panel de arriba, en cambio, dice todavía «Run a query to visualize it here or go to all visualizations»: tiene la consulta, todavía no eligió cómo dibujarla. Consulta y visualización son dos ajustes separados de un mismo panel.

Para entender mejor: ¿Builder o Code?

Builder construye la consulta con menús (elegir la métrica, agregar una etiqueta, apilar una función). Code te deja escribirla. Los dos producen la misma cadena PromQL, y puedes pasar de uno al otro. En este curso, nos quedamos en Code: la consulta que escribes aquí es palabra por palabra la de Prometheus, y la encontrarás tal cual en el JSON del paso 9 ("editorMode": "code").

Paso 7 — Elegir la visualización

En Suggestions, haz clic en la miniatura Stat.

text
Stat
Value options
  Calculate | All values
  Calculation: Last *
Thresholds
  80  (rouge)
  Base  (vert)

Qué mirar: el panel de arriba muestra ahora un gran 8 verde, con la pequeña curva de fondo. El panel de la derecha lista las opciones de Stat, de las que hay dos que conocer: bajo Value options, Calculate está marcado y Calculation vale Last * (el panel muestra el último valor de la serie, no un promedio); bajo Thresholds, dos umbrales, Base en verde y 80 en rojo: el valor pasaría a rojo a partir de 80. Estos umbrales son los que Grafana pone por defecto en todo panel nuevo; no tienen ningún sentido para un conteo de destinos (verías rojo con 80 destinos), los leerías y los cambiarías en un tablero real. Aquí, déjalos: lo que importa es reconocerlos en el JSON.

Paso 8 — Guardar: un nombre, una dirección

Arriba a la derecha, Save. Se abre el diálogo Save dashboard, con dos pestañas, Details y Changes 3, y tres campos: Title (New dashboard), Description, Folder (Dashboards).

Qué mirar primero: borra el título y haz clic en Save: la palabra Required aparece en rojo bajo Title y el botón Save se desactiva. Un tablero de control tiene obligatoriamente un nombre. Escribe:

text
Atelier M1 - Cibles Prometheus

El botón se reactiva. Haz clic en Save.

text
Dashboard saved

Qué mirar después: el aviso Dashboard saved, y luego la dirección de la página:

text
http://localhost:3000/d/adc947c/atelier-m1-cibles-prometheus?orgId=1&from=now-6h&to=now&timezone=browser

Tres cosas en esta dirección. adc947c es el uid, generado al azar por Grafana: es la identidad del tablero, anótalo. atelier-m1-cibles-prometheus es el título en forma de dirección; solo sirve para la legibilidad. from=now-6h&to=now es el período mostrado, Last 6 hours por defecto para un tablero nuevo. El lápiz arriba a la derecha (Edit) reemplazó a Save: estás en lectura. Menú principal → Dashboards: tu tablero está en la lista, en la raíz, junto a la carpeta Labo observabilite.

Para entender mejor: la pestaña Changes 3

Antes de hacer clic en Save, abre Changes 3: Grafana muestra, en JSON, la diferencia entre un tablero nuevo y el que estás guardando. La cifra es el número de modificaciones que contó; en un tablero vacío recién abierto, la pestaña dice Changes 1. Es la primera vez que ves el JSON que se escribirá; el paso 9 te lo hace releer completo.

Paso 9 — Releer el JSON: los tres objetos están dentro

En una terminal, con tu uid en lugar de adc947c:

bash
curl -s -u admin:aiopsatlas2026 http://localhost:3000/api/dashboards/uid/adc947c

La respuesta es un documento JSON. Su parte meta:

json
"meta": {
  "slug": "atelier-m1-cibles-prometheus",
  "url": "/d/adc947c/atelier-m1-cibles-prometheus",
  "created": "2026-09-15T21:21:02Z",
  "version": 1,
  "folderTitle": "General"
}

Y en dashboard, el arreglo panels contiene un solo elemento, tu panel (recortado a los campos que importan):

json
{
  "type": "stat",
  "title": "Cibles surveillées",
  "datasource": { "type": "prometheus", "uid": "prometheus" },
  "targets": [
    {
      "datasource": { "type": "prometheus", "uid": "prometheus" },
      "editorMode": "code",
      "expr": "count(up)",
      "legendFormat": "__auto",
      "range": true,
      "refId": "A"
    }
  ],
  "fieldConfig": {
    "defaults": {
      "color": { "mode": "thresholds" },
      "thresholds": {
        "mode": "absolute",
        "steps": [
          { "color": "green", "value": 0 },
          { "color": "red", "value": 80 }
        ]
      }
    }
  },
  "options": {
    "colorMode": "value",
    "graphMode": "area",
    "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false }
  },
  "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 },
  "id": 1,
  "pluginVersion": "13.2.2"
}

Qué mirar: los tres objetos del taller, escritos con todas las letras. La fuente: "datasource": { "type": "prometheus", "uid": "prometheus" }, el uid del archivo de provisioning del paso 1. La consulta: "expr": "count(up)", en targets, con "refId": "A" (la letra de la línea en Queries) y "editorMode": "code". La visualización: "type": "stat", y sus ajustes del paso 7: "calcs": ["lastNotNull"] es el Last * de la pantalla, steps son los dos Thresholds, green en la base y red en 80. gridPos dice dónde está el marco en la cuadrícula: arriba a la izquierda, 12 columnas de ancho sobre 24, 8 líneas de alto. Un tablero de control de Grafana no es más que eso: este documento, guardado bajo un uid. Es tu entregable: este bloque, con stat, count(up) y prometheus rodeados.

Para entender mejor: el mismo JSON en la interfaz

En la página del tablero, Edit (el lápiz) → en la barra lateral derecha, Options (la rueda) → View all settings → pestaña JSON Model. Es el mismo documento, sin la parte meta, y puedes modificarlo ahí y después Save. Es también este documento el que el kit entrega para sus tres tableros, en grafana/provisioning/dashboards/*.json: abre api-catalogue.json y busca "expr": leerás ahí consultas de la práctica guiada, exactamente en el formato de arriba. Un tablero de control se comparte enviando ese archivo.

Paso 10 — Eliminar todo, y probarlo

En la página del tablero, EditOptionsView all settings. Se abre la página Settings (pestañas General, Annotations, Variables, Links, Versions, Permissions, JSON Model). Al final de todo, el botón rojo Delete dashboard.

text
Delete
Do you want to delete this dashboard?
Atelier M1 - Cibles Prometheus
Type "Delete" to confirm

Qué mirar: el botón Delete del diálogo está desactivado mientras no hayas escrito la palabra Delete en el campo. Escríbela, haz clic en Delete.

text
Dashboard deleted
View deleted dashboards

Grafana te lleva de vuelta a la página de inicio. Prueba por la API, con tu uid:

bash
curl -s -u admin:aiopsatlas2026 http://localhost:3000/api/dashboards/uid/adc947c
json
{"message":"Dashboard not found"}

Y la lista completa de tableros de control:

bash
curl -s -u admin:aiopsatlas2026 "http://localhost:3000/api/search?type=dash-db"

Tres entradas, las tres del kit, todas en la carpeta Labo observabilite: api-catalogue («API catalogue — signaux dorés», API catálogo — señales de oro), hote-conteneurs («Hôte et conteneurs», Host y contenedores), journaux-api («Journaux de l'API», Logs de la API). El tuyo ya no está. El diálogo de eliminación lo decía: Grafana conserva los tableros eliminados en un historial hasta doce meses (Recently deleted en la página Dashboards), desde donde pueden restaurarse; para lo que haces en este curso, eliminado quiere decir eliminado.

Verificación final

Retoma los diez gestos de memoria, en orden, y marca:

  • Connections → Data sources → Prometheus → Save & test devuelve Successfully queried the Prometheus API.
  • En Explore, up en modo Code devuelve 8 series.
  • count(up devuelve un cuadro rojo bad_data: … parse error: unclosed left parenthesis; count(up) devuelve {} y 8.
  • Dashboards → New → New dashboard abre una página New dashboard vacía, con Save ya visible.
  • Add → Panel crea New panel; el campo Title renombra el marco en directo.
  • count(up) y después Run queries rellena Suggestions con el valor 8 en cada miniatura.
  • La miniatura Stat muestra un gran 8; Calculation vale Last *; Thresholds: Base verde, 80 rojo.
  • Título vacío: Required y Save desactivado; título Atelier M1 - Cibles Prometheus: aviso Dashboard saved y un uid en la dirección.
  • curl … /api/dashboards/uid/<uid> contiene "type": "stat", "expr": "count(up)", "uid": "prometheus".
  • Después de Delete dashboard, el mismo curl devuelve {"message":"Dashboard not found"} y /api/search?type=dash-db lista exactamente tres tableros.

Del lado del labo, nada se movió: etat sigue mostrando 10/10 services, 8/8 cibles up, 0 alertes actives. Grafana escribió y después borró una línea en su propia base; Prometheus no vio pasar nada.

Si algo falla

Mostrar los casos en que algo falla

Aparece la página de inicio de sesión y admin / admin es rechazado. La contraseña del kit es aiopsatlas2026 (fijada en docker-compose.yml, variable GF_SECURITY_ADMIN_PASSWORD). En línea de comandos, el mismo par: -u admin:aiopsatlas2026; con una contraseña incorrecta, la API devuelve {"message":"Invalid username or password", …, "statusCode":401}.

Save & test devuelve un error en lugar del aviso verde. Prometheus está detenido o reiniciándose: etat, luego espera a que labo-prometheus esté healthy y vuelve a intentar. Si cambiaste la URL por error, vuelve a poner http://prometheus:9090 (no localhost: desde el contenedor Grafana, localhost es Grafana mismo).

Explore devuelve No data en up sin cuadro rojo. Mira el selector de fuente arriba: quizá estás en Loki (la práctica guiada te dejó ahí). Vuelve a Prometheus. Verifica también el período arriba a la derecha: debe terminar en now.

El campo de consulta rechaza lo que escribo, o el texto aparece dos veces. Estás en Builder: el campo libre solo existe en Code. Cambia, borra, vuelve a escribir.

El panel se queda en «Run a query to visualize it here». La consulta está escrita pero no fue lanzada: Run queries o Mayús+Enter. Si el panel Suggestions sigue vacío después de eso, la consulta tiene un error: el cuadro rojo está bajo el campo, baja.

El Save del diálogo sigue desactivado, con Required bajo el título. El título está vacío. Escribe uno. Si ya guardaste un tablero con el mismo nombre en un intento anterior, Grafana lo acepta igual: dos tableros pueden llevar el mismo título, tienen uid distintos. Tendrás entonces dos entradas en la lista; elimina la que sobra (paso 10).

No encuentro el uid. Está en la dirección, justo después de /d/: http://localhost:3000/d/adc947c/…. Si no, curl -s -u admin:aiopsatlas2026 "http://localhost:3000/api/search?query=Atelier" devuelve el campo "uid" de cada tablero cuyo título contenga Atelier.

curl devuelve {"message":"Dashboard not found"} en el paso 9 aunque el tablero está en pantalla. El uid está mal copiado (mayúsculas, un carácter de más). Cópialo de nuevo desde la dirección.

Eliminé un tablero del kit por error. Está en Dashboards → Recently deleted: restáuralo. Si no, docker compose restart grafana: el provisioning relee grafana/provisioning/dashboards/ al arrancar y recrea los tres tableros desde sus archivos JSON (tableaux-de-bord.yml, updateIntervalSeconds: 30).

Modifiqué un tablero del kit y Save lo rechaza. Normal: allowUiUpdates: false en tableaux-de-bord.yml. Los tres tableros del kit se leen, no se sobrescriben; guarda tu versión con otro nombre.