Skip to content

Logs — Loki + accesos

Last updated: 2026-07-12

Documento canónico de cómo y dónde ver los logs del homelab.

Resumen

  • Backend: Loki (single-node) en VM 208 container, port host 3101 (internal docker 3100).
  • UI principal: Grafana → Explore → datasource Loki (http://192.168.0.208:3030/explore).
  • Live tail UI por container: Dozzle en http://192.168.0.208:9999 (solo VM 208).
  • Cron pings: Healthchecks self-hosted en http://192.168.0.208:8073.
  • Retention: 30 días (limits_config.retention_period: 720h).

Hosts shipping logs (8)

Host Cómo
proxmox-50, proxmox2-51 promtail systemd binary /usr/local/bin/promtail v3.6.10
ubuntu-media-server promtail container, scrape Docker socket + /var/log
lxc-123, 155, 200 proxmox2 lee journal/ de cada LXC desde /zfs-ha/subvol-<ID>-disk-0/var/log/journal
ha-171 systemd service ha-log-pusher en proxmox-50 — websocket subscribe a HA events, push a Loki

DECOMISADOS (2026-07-12): lxc-249 (beszel) y lxc-253 (clawdbot → migrado a CT100) ya no existen; se han retirado de la tabla de hosts que envían logs.

Labels disponibles en Loki

Label Valor Source
host proxmox-50, proxmox2-51, ubuntu-media-server, lxc-NNN, ha-171 promtail relabel
container_name nombre del container Docker docker_sd auto
job systemd-journal, varlogs, lxc, homeassistant, pveproxy promtail config
stream stdout / stderr docker logs

2026-04-25: añadido label host=ubuntu-media-server también al docker scrape (antes solo en varlogs). Ahora {host="ubuntu-media-server"} cubre ALL containers + syslog.

LogQL — queries típicas

Por container

{container_name="jellyfin"}
{container_name="caddy"} |= "error"
{container_name=~"sablier|caddy"} | json

Por host

{host="ubuntu-media-server"} | json | level=~"err|warn"
{host="proxmox-50"} |~ "(?i)oom|panic"
{host=~"lxc-.+"} != "INFO"

Por job (system logs)

{job="varlogs"} |= "sshd"
{job="systemd-journal", host="proxmox2-51"}
{job="homeassistant"} |= "automation_triggered"

Patterns útiles

# Errors en últimos 5min, agrupados por container
sum by (container_name) (count_over_time({container_name=~".+"} |~ "(?i)error" [5m]))

# Caddy 5xx
{container_name="caddy"} | json | status >= 500

# Failed SSH (auth.log)
{job="varlogs"} |= "Failed password"

Acceso por CLI

Via curl

# List labels
curl -s http://192.168.0.208:3101/loki/api/v1/labels | jq .

# Values of a label
curl -s http://192.168.0.208:3101/loki/api/v1/label/container_name/values | jq -r '.data[]'

# Query range (último 1h)
curl -G -s "http://192.168.0.208:3101/loki/api/v1/query_range" \
  --data-urlencode 'query={container_name="caddy"}' \
  --data-urlencode 'limit=20' \
  --data-urlencode "start=$(date -u -d '1 hour ago' +%s)000000000" \
  --data-urlencode "end=$(date -u +%s)000000000" | jq .

Via logcli (opcional, herramienta oficial Grafana)

curl -fsSL https://github.com/grafana/loki/releases/download/v3.6.3/logcli-linux-amd64.zip -o /tmp/logcli.zip
unzip /tmp/logcli.zip -d /tmp && sudo mv /tmp/logcli-linux-amd64 /usr/local/bin/logcli
logcli query --addr=http://192.168.0.208:3101 '{container_name="jellyfin"}'

Promtail config

  • VM 208: /home/monxas/appdata/promtail/config.yml (container promtail)
  • proxmox-50, proxmox2-51: systemd unit + /etc/promtail.yaml

Log rotation

Configurada en /etc/systemd/journald.conf y /etc/docker/daemon.json para que el disco no se llene. Detalles en log-rotation.md.

Loki 3.7.1 — bug count_over_time + regex (workaround aplicado 2026-04-26)

count_over_time({...} |~ "regex"[24h]) puede devolver counts inflados ~3-4x con auto stream sharding (__stream_shard__). Streams reales pueden tener 0 matches mientras la metrica reporta 100k+.

Workaround: limits_config.shard_streams.enabled: false en /home/monxas/appdata/loki-config/loki-config.yaml. Solo afecta ingesta nueva — los chunks ya sharded inflaran hasta que rolen del 24h window.

Verificacion rapida si una metrica Loki parece descabellada: query directo a la API de Loki con limit=1 y mirar totalPostFilterLines en .data.stats.summary. Si es ~0 pero la metrica de count reporta miles → es phantom.

Self-loop: Grafana queries que contienen "ERROR" se loguean en container loki/grafana, y promtail los reenvia a Loki, donde matchean su propia query. Cualquier alerta sobre logs de error debe excluir container_name!~"loki|grafana" y filtrar != "query=" != "caller=metrics".

Promtail varlogs — pipeline_stages para syslog_identifier (2026-04-26)

Antes el job varlogs en /etc/promtail/config.yml (pmx-50 + pmx2-51) no asignaba syslog_identifier a las lineas de /var/log/{syslog,kern.log,auth.log,...}. Ahora extrae el nombre del programa con regex pipeline_stage en la configuracion del job. Solo aplica a ingesta nueva; streams antiguas siguen sin label hasta que sus chunks rolen.

Troubleshooting

Síntoma Solución
Falta un host en host label Verifica promtail está running en ese host. En proxmox: systemctl status promtail. En LXC: el journal se lee desde proxmox2, así que ls /zfs-ha/subvol-<ID>-disk-0/var/log/journal debería tener data.
Container existe pero no aparece en Loki Verifica docker logs <container> no está vacío Y promtail está running. docker logs promtail \| tail -10 para ver actividad.
ingestion rate limit exceeded Promtail está mandando demasiado en burst. Usually se autoresuelve. Si persiste, ajustar limits_config.ingestion_rate_mb en Loki.
entries too far behind Loki rechaza logs más viejos de 7 días. Pasa al inicio cuando promtail catch-up. Se autoresuelve.

Reference

  • LogQL docs: https://grafana.com/docs/loki/latest/query/
  • Promtail: https://grafana.com/docs/loki/latest/send-data/promtail/
  • Estado canónico de hosts/jobs: ../architecture/homelab-architecture.md sección "Logs — Loki"