📑 Índice del documento
- Trabajo Práctico Nº 2 — Parte 4
Trabajo Práctico Nº 2 — Parte 4
Cierre: comparativa empírica, decisiones arquitectónicas y ADR magisterial
Fecha de Entrega: 09/05/2026
🧭 Esto es la Parte 4 de 4 sobre observabilidad.
Esta parte es reflexiva y de escritura técnica, no operativa. Tienen 3 stacks corriendo en su cluster con métricas reales medidas por ustedes. La consigna acá es convertir esa experiencia en una decisión arquitectónica defendible, plasmada en un ADR magisterial que la cátedra pueda usar como ejemplo de buena toma de decisiones técnicas.
🤝 Partes 3 y 4 se entregan el mismo día (09/05) en un solo push final. Trabajalas en paralelo: a medida que la Parte 3 te muestra que OTel funciona, andá tomando las mediciones del Hit #1 de esta Parte 4. Cuando termina la Parte 3, el Hit #3 (ADR magisterial) ya está respaldado por datos reales de tu cluster.
Pre-requisitos: Parte 3 funcionando con OTel haciendo fan-out + Loki y EFK siguen vivos. Necesitan los 3 stacks corriendo para tomar las mediciones empíricas (Hit #1).
Pre-requisitos
- Parte 1 aprobada (mínimo 60/100): Loki +
Promtail/Alloy + Grafana operativos en el namespace
observability. - Parte 2 aprobada (mínimo 60/100): Elasticsearch +
Fluentd/Fluent Bit + Kibana operativos en el namespace
efk. - Parte 3 aprobada (mínimo 60/100): OpenTelemetry Collector haciendo fan-out hacia Loki y Elasticsearch (y traces a un backend de su elección). El SDK de Python instrumentando el scraper.
- ADRs previos escritos:
0007-stack-de-logging.md(Parte 1),0009-stack-efk.md(Parte 2), y el ADR de OpenTelemetry de la Parte 3. Esta Parte 4 los revisita, no los reemplaza. - Cluster con los 3 stacks vivos al momento de
evaluar: la cátedra va a
kubectl get pods -Adurante la defensa para confirmar que los 3 namespaces siguen Running. Si alguno está caído al momento de la defensa, no se puede tomar Hit #1 → -15 % directo. - 24 h de runtime mínimo antes de medir: los CronJobs del scraper deben haber corrido al menos un ciclo completo en cada stack para que los números del Hit #1 sean representativos. No midan el cluster recién levantado.
Requisitos generales y formato de entrega
A diferencia de las Partes 1, 2 y 3, acá no se entrega código nuevo. Se entrega escritura técnica y mediciones. Eso no la hace más fácil — la hace distinta.
ADR magisterial obligatorio
- Archivo:
docs/adr/0012-stack-de-observabilidad-final.md. - Formato Michael Nygard (Contexto · Decisión · Consecuencias) extendido — ver plantilla del Hit #3.
- Longitud mínima: 1500 palabras, recomendado 1500-2000. Esto no es relleno: es lo que hace falta para integrar las 3 experiencias de Partes 1-3 y fundamentar la decisión final.
- Tiene que referenciar la tabla de mediciones del Hit #1 explícitamente — al menos 3 veces a lo largo del documento, citando números concretos.
Checklist de mediciones reales
- Las cifras del Hit #1 son medidas por ustedes en su propio cluster, no copiadas de blogs ni del paper de Grafana Labs. Si la cátedra pide reproducción durante la defensa y los números no se replican (con tolerancia ±20 %), se descuenta el Hit #1 entero.
- Cada medición incluye: comando exacto que la generó, timestamp de cuándo se tomó, estado del cluster en ese momento (uptime, qué CronJobs habían corrido, volumen de logs acumulado).
- Si una medición es imposible de tomar en su entorno (ej: no llegan a 24 h de logs por límite de tiempo), declárenlo explícitamente — vale más una limitación honesta documentada que un número inventado.
Otros requisitos
Repo público (mismo del TP 0/1/2) con todos los entregables nuevos en
docs/observability-final/:docs/ ├── adr/ │ └── 0012-stack-de-observabilidad-final.md ← ADR magisterial (Hit #3) └── observability-final/ ├── README.md ← índice + cómo se generaron las mediciones ├── measurements.md ← tabla del Hit #1 + comandos exactos ├── decision-matrix.md ← tabla del Hit #2 ├── vendor-lockin-essay.md ← reflexión del Hit #4 └── screenshots/ ├── kubectl-top-loki.png ├── kubectl-top-efk.png ├── kubectl-top-otel.png ├── pvc-disk-usage.png └── query-latency-comparison.pngSin código del scraper modificado en esta Parte 4. Si tocaron el scraper para reparar algo de Partes 1-3 está bien, pero documenten el cambio en el README y mencionen por qué — no es el foco de esta entrega.
Defensa oral de 5 minutos durante la corrección. Cada equipo presenta su ADR magisterial, justifica su recomendación final y responde preguntas del jurado. Vale 5 % de la nota.
Contenidos del programa relacionados
- Toma de decisiones arquitectónicas: ADR como artefacto vivo (no se “termina”, se “supera”), trade-offs explícitos, criterios de revisión.
- Análisis comparativo: medición empírica vs benchmarks de marketing, sesgos del evaluador (familiaridad, estética, hype).
- Vendor lock-in: capas de abstracción, costo de migración, riesgo de plataforma.
- Total Cost of Ownership: licencia + infra + operación + capacitación + costo de salida.
- Comunicación técnica escrita: estructura del razonamiento, evidencia citable, separación contexto/decisión/consecuencias.
Práctica
Después de tres semanas levantando stacks de logging, ya tienen algo que casi nadie tiene en la industria: experiencia operativa directa con los 3 ecosistemas dominantes, corriendo simultáneamente sobre la misma carga de trabajo. Esa es la materia prima de esta Parte 4.
Lo que sigue no es operar más infra — es reflexionar con disciplina sobre lo que ya operaron. La diferencia entre un ingeniero senior y uno junior no es que el senior sepa más comandos: es que sabe por qué eligió lo que eligió y bajo qué condiciones cambiaría de opinión. Esa habilidad se entrena escribiendo decisiones, no solo ejecutándolas.
⚠️ Esta parte se evalúa por calidad de pensamiento, no por entregables operativos. Un repo con muchísimos archivos pero un ADR débil saca menos nota que un repo con un solo ADR sólido. La cátedra lee con detalle: prosa floja, contradicciones internas, números sin fuente, recomendaciones sin contexto — todo eso baja la nota.
Hit #1 — Mediciones empíricas en SU cluster
Construyan una tabla con números reales medidos por el
equipo sobre los 3 stacks, en el mismo cluster, durante la
misma ventana de 24 h. La tabla va a
docs/observability-final/measurements.md y se referencia
desde el ADR del Hit #3.
Métricas obligatorias
- Footprint RAM/CPU por stack (medido con
kubectl top pods). - Disk usage del PVC tras 24 h de logs del scraper
(medido con
kubectl exec ... -- du -sh). - Query latency p50 / p95 sobre la misma pregunta de negocio en LogQL, KQL, y la query equivalente de OTel + backend (idealmente la misma query Q1 del Hit #4 de Parte 1: “errores del scraper en la última hora por producto”).
- Tiempo de deployment desde cero: clean cluster → primer log visible en el visualizador. Cronómetro en mano, una sola corrida (no promedio de varias).
- Tamaño de la imagen del agente: Promtail (o Alloy)
vs Fluent Bit (o Fluentd) vs OTel Collector.
docker image inspectsobre la imagen pinneada en sus Helm charts.
Comandos exactos para cada métrica
Métrica 1 — Footprint RAM / CPU
# Pre-requisito: metrics-server instalado en k3s (suele venir por default).
# Si no está: kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# Loki + Promtail + Grafana
kubectl top pods -n observability --no-headers | awk '{cpu+=$2; mem+=$3} END {print "Loki stack:", cpu"m CPU,", mem"Mi RAM"}'
# EFK
kubectl top pods -n efk --no-headers | awk '{cpu+=$2; mem+=$3} END {print "EFK stack:", cpu"m CPU,", mem"Mi RAM"}'
# OTel Collector (sin contar el backend al que exporta — eso ya está en los 2 anteriores)
kubectl top pods -n otel --no-headers | awk '{cpu+=$2; mem+=$3} END {print "OTel stack:", cpu"m CPU,", mem"Mi RAM"}'💡 Tomen 3 muestras espaciadas por 1 hora y reporten la media + desviación. Una sola medición puntual puede caer en un GC pause de Elasticsearch y mentirles feo.
Métrica 2 — Disk usage del PVC tras 24 h
# Loki — chunks store en filesystem
kubectl -n observability exec loki-0 -- du -sh /var/loki/chunks /var/loki/index 2>/dev/null
# Elasticsearch — data dir
kubectl -n efk exec elasticsearch-master-0 -- du -sh /usr/share/elasticsearch/data 2>/dev/null
# Si OTel exporta a archivos (caso poco común, solo si configuraron file exporter):
kubectl -n otel exec <otel-pod> -- du -sh /var/lib/otel 2>/dev/null
# Si OTel solo hace fan-out a Loki/ES (caso típico), el disco se cuenta en los 2 anteriores
# y se reporta "0 (es passthrough)" en la fila de OTel.⚠️ El stack que persiste es el que cuenta. Si OTel solo hace
pipeliney exporta a Loki + ES sin retener nada, su footprint en disco es 0 y eso es una ventaja real, no una trampa estadística. Anótenlo así en la tabla.
Métrica 3 — Query latency p50 / p95
Usen la misma pregunta de negocio traducida a las 3 queries — sino comparan peras con manzanas.
Pregunta canónica: “errores del scraper en la última hora, agrupados por producto”.
# Loki / LogQL — via API
time curl -sG http://localhost:3100/loki/api/v1/query_range \
--data-urlencode 'query=sum by (producto) (count_over_time({namespace="ml-scraper", app="scraper"} | json | level="ERROR" [1h]))' \
--data-urlencode 'start='$(date -u -d '1 hour ago' +%s)000000000 \
--data-urlencode 'end='$(date -u +%s)000000000 \
-o /dev/null
# Elasticsearch / KQL — via _search
time curl -sX POST "http://localhost:9200/scraper-*/_search" -H 'Content-Type: application/json' -d '{
"size": 0,
"query": {"bool": {"must": [
{"range": {"@timestamp": {"gte": "now-1h"}}},
{"term": {"level": "ERROR"}}
]}},
"aggs": {"by_producto": {"terms": {"field": "producto.keyword"}}}
}' -o /dev/nullCorran 10 veces cada query con time y
reporten p50 (mediana) y p95. Para cálculo rápido del p95 de 10
muestras: ordenen y tomen la 10ª (vale como aproximación pedagógica — no
es estadísticamente robusto pero ese no es el punto).
Métrica 4 — Tiempo de deployment desde cero
# Borren todo y midan con cronómetro:
kubectl delete namespace observability efk otel --wait=true
# Loki stack
START=$(date +%s); cd observability && ./install.sh; END=$(date +%s)
echo "Loki stack deploy: $((END-START))s"
# Repetir el patrón para EFK y OTelTiempo “desde clean cluster hasta primer log visible en el
visualizador” — incluye el primer Job del scraper que dispara y aparece
en la UI. No es solo helm install.
Métrica 5 — Tamaño de imagen del agente
docker image inspect grafana/promtail:3.5.6 --format='{{.Size}}' | numfmt --to=iec
docker image inspect fluent/fluent-bit:3.2.0 --format='{{.Size}}' | numfmt --to=iec
docker image inspect otel/opentelemetry-collector-contrib:0.116.0 --format='{{.Size}}' | numfmt --to=iec💡 Las versiones exactas las eligen ustedes — son las que efectivamente desplegaron. El punto es comparar lo que ustedes corrieron, no lo último de cada proyecto.
Tabla resumen (formato obligatorio)
| Métrica | Loki + Promtail + Grafana | EFK (ES + Fluentd + Kibana) | OTel Collector |
|---|---|---|---|
| RAM total (MiB) | <medido> | <medido> | <medido> |
| CPU total (mCPU) | <medido> | <medido> | <medido> |
| Disco PVC tras 24 h (MiB) | <medido> | <medido> | <medido (o "passthrough")> |
| Query latency p50 (ms) | <medido> | <medido> | <medido> |
| Query latency p95 (ms) | <medido> | <medido> | <medido> |
| Deploy clean → first log (s) | <medido> | <medido> | <medido> |
| Tamaño imagen agente (MiB) | <medido> | <medido> | <medido> |Bajo cada celda, citen el comando que generó el número y el timestamp. Sin esa traza, la cátedra asume que el número está inventado.
Hit #2 — Decision matrix por contexto
No existe “el mejor stack” en abstracto. Existe “el mejor stack para X equipo, X presupuesto, X regulación, X madurez operativa”. Construyan una matriz cruzada que defienda esa idea.
Archivo:
docs/observability-final/decision-matrix.md.
Contextos obligatorios (filas)
- Startup OSS-only: 3-5 devs, presupuesto cloud < USD 200/mes, sin equipo de plataforma dedicado.
- Mid enterprise: 50-200 devs, presupuesto OK pero finito, equipo de plataforma de 2-4 personas, ya tienen Grafana en producción para métricas.
- Regulated (banca / salud): requiere retención ≥ 7 años, audit trail, encriptación en reposo y tránsito, cumplimiento (BCRA / HIPAA / ISO 27001), cualquier vendor SaaS necesita DPA firmado.
- Edge / IoT: agente corre en dispositivos con 256 MB RAM y conectividad intermitente, batched ingestion, no hay cluster local — solo collector embebido.
- Cloud-native multi-region: aplicación en 3+ regiones de AWS/GCP, latencia inter-región importa, federation de queries necesaria, equipo de SRE de 5+ personas.
Stacks obligatorios (columnas)
- Loki + Promtail/Alloy + Grafana
- EFK (Elasticsearch + Fluentd/Fluent Bit + Kibana)
- OpenTelemetry Collector (como capa de abstracción, no como backend final)
- Datadog (managed SaaS — aunque no lo desplegaron, lo conocen del Hit #4 de Parte 1)
- Splunk (enterprise on-prem o Splunk Cloud)
Formato de cada celda
Cada celda tiene 3 cosas:
- Veredicto: ✅ recomendado · ⚠️ aceptable · ❌ desaconsejado.
- Razón principal (1 línea, máximo 25 palabras).
- Caveat (1 línea, máximo 20 palabras) — el “pero ojo con esto” que cambiaría el veredicto.
Ejemplo de celda bien hecha (startup × Loki):
✅ Recomendado. Costo $0, opera 1 persona part-time, escala fácil hasta cientos de GB/día. Caveat: si crecen a full-text search heavy, migrar a OTel-frontend ya para evitar re-instrumentar.
Ejemplo de celda mal hecha (la cátedra la marca como insuficiente):
✅ Es bueno. Caveat: tiene cosas malas.
Tamaño esperado
5 contextos × 5 stacks = 25 celdas. No salten ninguna. Si una combinación es obvia (ej: regulated × Datadog SaaS sin DPA → ❌), igual escriban la razón explícita.
Hit #3 — ADR magisterial
Este es el núcleo de la entrega. Vale 50 % de la nota. Todo lo otro existe para alimentarlo: las mediciones del Hit #1 son evidencia, la matriz del Hit #2 es contexto, la reflexión del Hit #4 es complemento. Acá se integra todo.
Archivo:
docs/adr/0012-stack-de-observabilidad-final.md.
Plantilla extendida (secciones obligatorias)
# 0010 — Stack de observabilidad final para <escenario elegido>
- Date: 2026-06-XX
- Status: Accepted
- Deciders: <equipo>
- Supersedes: 0007, 0009 (parcialmente — ver "Relación con ADRs previos")
## 1. Contexto
[300-400 palabras]
Definan el escenario imaginario que el equipo eligió defender. No "una empresa
genérica" — un escenario concreto, con números:
- Tipo de aplicación (ej: "scraper de e-commerce que crece a 100 usuarios/mes
via API pública").
- Tamaño del equipo (ej: "4 devs full-stack, 0 SRE, 0 platform engineer").
- Presupuesto cloud mensual (ej: "USD 300/mes en AWS, todo en una región").
- Restricciones regulatorias (ej: "ninguna — startup pre-seed, no manejamos
PII").
- Volumen esperado de logs (ej: "~500 MB/día hoy, proyección a 5 GB/día en
12 meses").
- Madurez operativa actual (ej: "tenemos kubectl + GitHub Actions, nada más").
Justifiquen por qué este escenario es **representativo** de algo real que
ustedes podrían encontrarse en su primer trabajo. No inventen una mega-empresa
de Wall Street que no van a operar nunca.
## 2. Alternativas consideradas
[400-500 palabras]
Las 3 que probaron empíricamente + 2 mencionadas en partes anteriores. Para
cada una, **2-3 oraciones**:
### 2.1. Loki + Promtail/Alloy + Grafana
- Qué es, cómo se compara con las otras.
- Cita a Hit #1: "RAM total medida = <X> MiB; query latency p95 = <Y> ms".
- Pro principal y contra principal en SU contexto.
### 2.2. EFK (Elasticsearch + Fluentd/Fluent Bit + Kibana)
- Idem. Cita Hit #1.
### 2.3. OpenTelemetry Collector + backend
- Idem. Cita Hit #1.
### 2.4. Datadog Logs (managed SaaS)
- No lo probaron, pero conocen el modelo. Costo, lock-in, ergonomía.
- Por qué quedó descartado / por qué quedó en finalista.
### 2.5. Splunk Cloud
- Idem. Diferenciar de Datadog.
## 3. Decisión
[150-250 palabras]
**La frase del veredicto va al principio, en negrita, en una línea.**
Ejemplo: "Adoptamos OpenTelemetry Collector como capa de instrumentación +
Loki como backend de logs + Grafana como visualizador, con plan de evolución
hacia Tempo (traces) en 6 meses."
Después, 2-3 párrafos:
- Por qué esa combinación gana en el contexto definido en §1.
- Qué hace mejor que cada alternativa de §2 (referenciando explícitamente).
- Qué cambia la decisión si alguno de los supuestos del §1 cambia (umbrales).
## 4. Trade-offs aceptados explícitos
[200-300 palabras]
Lista de **3-5 trade-offs reales que aceptan**. No "hay un trade-off pequeño",
sino "renunciamos a X y aceptamos las consecuencias Y". Ejemplo:
- **Renunciamos a full-text search rápido**. Loki es label-first; si en 12 meses
necesitamos buscar substrings de 100 chars en GBs de logs, vamos a sufrir.
Mitigación: si llegamos a ese caso, Loki acepta filtros de línea (`|=`) que
son lentos pero existen — y siempre podemos agregar ES más adelante porque
ya estamos hablando OTel.
- **Aceptamos un single-binary Loki**. No tenemos HA. Si el pod muere y el PVC
se corrompe, perdemos los logs no-replicados. Mitigación: snapshots semanales
del PVC + el código sigue emitiendo a stdout (kubectl logs como fallback).
- ...
## 5. Evidencia empírica (Hit #1)
[100-200 palabras]
Tabla del Hit #1 reproducida o linkeada. **Tres referencias mínimas en el
cuerpo del ADR**:
- "El footprint de RAM de EFK (<X> MiB medido) duplica al de Loki (<Y> MiB)
en nuestro cluster. Para un equipo sin SRE dedicado, eso son <Z> USD/mes
extra de instancias EC2."
- "La query latency p95 de Loki (<X> ms) está dentro del rango aceptable
para nuestro dashboard de incidentes (target < 2 s)."
- "El tiempo de deploy clean de OTel (<X> s) versus EFK (<Y> s) reduce el
MTTR de un 'borrón total y reinstalo' por un factor 3×."
## 6. Plan de evolución
[200-300 palabras]
Qué cambiarían en 3 horizontes. Sean **específicos**, no "vamos a evaluar
de nuevo".
### 6 meses
- Trigger: <evento que dispararía el cambio>.
- Acción concreta: <qué se hace>.
- Riesgo si no se hace: <consecuencia>.
Ejemplo: "Trigger: si el volumen de logs supera 5 GB/día. Acción: agregar
Tempo para traces (ya estamos OTel-instrumented). Riesgo: si el equipo
crece sin traces, debugging distribuido se vuelve adivinanza."
### 12 meses
[Idem]
### 24 meses
[Idem]
## 7. Relación con ADRs previos
[100-150 palabras]
- 0007 (Loki+Promtail) — qué de ese ADR sigue válido y qué se actualiza acá.
- 0009 (EFK) — idem.
- ADR de OTel de Parte 3 — idem.
Si este ADR **supersede** completamente alguno, declárenlo. Si solo
**actualiza parcialmente**, expliquen qué partes.
## 8. Referencias
- Mediciones empíricas: `docs/observability-final/measurements.md`.
- Decision matrix: `docs/observability-final/decision-matrix.md`.
- Reflexión vendor lock-in: `docs/observability-final/vendor-lockin-essay.md`.
- CNCF Observability Whitepaper.
- Charity Majors et al, *Observability Engineering* (O'Reilly, 2022).
- Cindy Sridharan, *Distributed Systems Observability* (O'Reilly, 2018).
- Otros que hayan citado.Criterios de un ADR magisterial bien hecho
- Específico: el escenario del §1 tiene números, no adjetivos.
- Honesto: el §4 admite renuncias, no las maquilla.
- Basado en evidencia: el §5 cita la tabla del Hit #1 con números, no impresiones.
- Defendible: el equipo, en la defensa oral, puede sostener cada decisión sin recurrir a “lo elegimos porque nos gustó”.
- Versátil: el §6 anticipa que el contexto va a cambiar y describe los disparadores del próximo ADR (0011).
📚 Lectura recomendada antes de escribirlo: el capítulo 7 (“Documenting Architecture Decisions”) del libro Software Architecture: The Hard Parts (Ford, Richards, Sadalage, Dehghani — O’Reilly, 2021). 30 páginas, ejemplos reales, cambia cómo se piensa un ADR.
Hit #4 — Reflexión sobre vendor lock-in
Escriban un essay corto (~500 palabras, no más de 700) sobre por qué OpenTelemetry como capa de abstracción cambia la conversación de vendor lock-in en observabilidad.
Archivo:
docs/observability-final/vendor-lockin-essay.md.
Estructura sugerida
Apertura: el problema histórico (~100 palabras). Antes de OTel, instrumentar la aplicación significaba elegir un SDK de un vendor (Datadog APM, New Relic agent, AppDynamics, Dynatrace). Cambiar de vendor era un proyecto de 6-12 meses de re-instrumentación. El SDK era el lock-in real, no el backend.
Qué cambia con OTel (~150 palabras). El SDK es estándar de CNCF. La aplicación habla OTLP (protocolo abierto), el Collector hace fan-out a cualquier backend. Cambiar de Datadog a Honeycomb a Grafana Cloud pasa de ser un proyecto de 6 meses a un cambio de YAML del Collector. El backend deja de ser estratégico — pasa a ser un proveedor reemplazable.
Por qué CNCF graduated importa (~100 palabras). OTel está graduated en CNCF desde 2024. Eso no es un sello bonito: significa neutralidad de gobernanza, multi-vendor steering committee (Microsoft, Google, AWS, Splunk, Datadog, todos contribuyen), ciclo de release predecible, y compromiso de no-fork. Comparen con Logstash (Elastic, single-vendor, cambio de licencia en 2021 partió la comunidad → Fluentd/Fluent Bit ganaron porque eran neutrales).
Casos reales (~150 palabras, mínimo 2 empresas). Ejemplos verificables:
- Discord publicó en 2023 que migró buena parte de su pipeline de logging hacia ELK pero mantiene un agente OTel-compatible para no quedarse encerrados (blog post de Discord engineering — buscar “scaling logs”).
- GitHub opera con Splunk + DataDog para logs y APM respectivamente — pero en sus charlas públicas (ej: KubeCon 2023) declaran que están instrumentando todo con OTel para tener opcionalidad.
- Shopify migró de un stack propio a OTel + multi-backend (Datadog + Tempo) y lo documentó en su engineering blog.
- Grafana Labs, obviamente, usa Loki y promueve OTel como ingestion path canónico para Loki 3.x.
- Uber publicó cómo construyeron M3 (su sistema de métricas) y por qué después incorporaron OTel para no re-inventar la rueda en cada equipo.
Citen al menos 2 con link verificable. No inventen.
Cierre honesto (~100 palabras). OTel no elimina el lock-in: lo redistribuye. El nuevo lock-in es a OTel mismo (si OTel se fragmenta, todos sufrimos) y al backend de almacenamiento (los datos siguen viviendo en Loki / ES / Datadog / lo que sea). Pero es un lock-in más barato de cambiar y distribuido entre más actores. Eso es progreso, no nirvana.
Tono del essay
Sobrio, técnico, sin hype. No “OTel es el futuro mágico”, sí “OTel cambia el cálculo de TCO de migración de un orden de magnitud”. La cátedra busca razonamiento, no entusiasmo.
Auto-verificación previa a la entrega
5 ítems. Si falta alguno, la entrega no se acepta.
1) Mediciones tomadas en el cluster propio del equipo
# La tabla de measurements.md tiene los 7 valores numéricos para los 3 stacks (mín. 21 celdas con números reales).
# Cada celda cita el comando y el timestamp.
grep -c "^|" docs/observability-final/measurements.md # > 30 lineas tipo tabla2) ADR ≥ 1500 palabras
wc -w docs/adr/0012-stack-de-observabilidad-final.md
# Esperado: ≥ 1500. Si es < 1500, está incompleto.3) Decision matrix completa (5 × 5 = 25 celdas)
Abrir docs/observability-final/decision-matrix.md y
contar celdas. Cada una con veredicto + razón + caveat. Ninguna
celda vacía o con “TBD”.
4) Reflexión vendor lock-in presente y con citas
wc -w docs/observability-final/vendor-lockin-essay.md
# Esperado: 400-700 palabras.
grep -c "https://" docs/observability-final/vendor-lockin-essay.md
# Esperado: ≥ 2 referencias verificables a casos reales.5) Los 3 stacks de Partes 1-3 siguen corriendo
kubectl get pods -n observability -n efk -n otel | grep -v Running | grep -v NAME
# Esperado: vacío. Cualquier pod en CrashLoopBackOff o Pending == falla.Esto se chequea el día de la defensa, no antes. Si entre el push y la defensa los stacks se cayeron, no se aceptan excusas — son su responsabilidad.
Criterios de evaluación
Requisitos bloqueantes
- Partes 1, 2 y 3 entregadas y aprobadas (≥ 60/100 cada una).
- Los 3 stacks corriendo el día de la defensa (verificado en auto-verificación #5).
- ADR
0010existe y tiene ≥ 1500 palabras.
Tabla de puntaje (100 %)
| Criterio | Peso |
|---|---|
| Hit #1 — Mediciones empíricas en el cluster propio (tabla completa, comandos citados, timestamps) | 15 % |
| Hit #2 — Decision matrix por contexto (5 × 5 celdas, cada una con veredicto + razón + caveat) | 15 % |
| Hit #3 — ADR magisterial (≥ 1500 palabras, las 8 secciones de la plantilla, evidencia citada del Hit #1) | 50 % |
| Hit #4 — Reflexión vendor lock-in (~500 palabras, ≥ 2 casos reales con cita verificable) | 15 % |
| Defensa oral — 5 min explicación al jurado, respuestas a preguntas | 5 % |
🎯 El Hit #3 vale la mitad de la nota. Es la parte que la cátedra lee dos veces. Inviertan ahí el 60 % de su tiempo, no en pulir screenshots.
Material de apoyo
Plantilla extendida del ADR magisterial
La plantilla completa con las 8 secciones está descrita en Hit #3 — se desarrolla en línea, no se duplica acá. Apunten a esa estructura literalmente: las secciones tienen números (1, 2, 3…) y rangos de palabras esperados. Respeten ambos.
Tamaño esperado por sección
| Sección | Rango de palabras | Foco |
|---|---|---|
| §1 Contexto | 300-400 | Escenario concreto con números |
| §2 Alternativas | 400-500 | 5 opciones, 2-3 oraciones cada una, evidencia citada |
| §3 Decisión | 150-250 | Veredicto + por qué gana en SU contexto |
| §4 Trade-offs | 200-300 | 3-5 renuncias explícitas + mitigación |
| §5 Evidencia | 100-200 | Tabla del Hit #1 + 3 referencias mínimo |
| §6 Plan evolución | 200-300 | 3 horizontes con triggers concretos |
| §7 Relación ADRs previos | 100-150 | Qué supersede / actualiza |
| §8 Referencias | n/a | Links + libros |
| Total | 1500-2000 |
Cómo medir cada métrica del Hit #1 — comandos exactos
Los comandos están en Hit #1 y se reproducen acá como cheatsheet rápido:
# 1. RAM/CPU
kubectl top pods -n <namespace>
# 2. Disk PVC
kubectl exec -n <ns> <pod> -- du -sh <data-dir>
# 3. Query latency
time curl -sG <api>/query --data-urlencode 'query=...'
# 4. Deploy time
START=$(date +%s); ./install.sh; echo "$(($(date +%s)-START))s"
# 5. Imagen agente
docker image inspect <image>:<tag> --format='{{.Size}}' | numfmt --to=iecEmpresas reales que migraron stacks (referencias verificables)
Para el Hit #4. Verifiquen el link antes de citarlo — la web cambia y los blog posts a veces se mueven o desaparecen.
| Empresa | Stack actual (público) | Movimiento documentado | Fuente |
|---|---|---|---|
| Discord | ELK (logs) + interno (search) | Escaló de Mongo a ELK; OTel-compatible para evitar re-lock-in | https://discord.com/blog/how-discord-stores-trillions-of-messages |
| GitHub | Splunk + Datadog APM | Instrumentando todo con OTel para opcionalidad multi-backend | KubeCon NA 2023 — “OpenTelemetry at GitHub” talk |
| Shopify | Datadog + Tempo (multi-backend via OTel) | Migración documentada en engineering blog | https://shopify.engineering/ (buscar “OpenTelemetry”) |
| Grafana Labs | Loki + Tempo + Mimir (todo casa propia) | Adoptaron OTLP como ingestion path canónico desde Loki 3.x | https://grafana.com/blog/2024/09/24/grafana-loki-3.0-release/ |
| Uber | M3 (métricas custom) + Jaeger (traces) | Incorporaron OTel para que cada equipo no re-instrumente | https://www.uber.com/blog/m3/ |
| Cloudflare | Internal log pipeline + Splunk | Documentaron por qué Splunk no escaló y armaron alternativa propia | https://blog.cloudflare.com/log-analytics-using-clickhouse/ |
| Slack | Splunk → ES propio | Migración por costo de licencias Splunk | Citado en KubeCon 2022 |
| Netflix | Atlas (métricas) + interno (logs) + Mantis (events) | Casi todo casa propia — caso opuesto a la abstracción OTel | https://netflixtechblog.com/ |
💡 No copien la tabla. Elijan 2 que les interesen, lean el blog post original, y citen con sus propias palabras. La cátedra detecta copy-paste de ChatGPT en 30 segundos.
Anti-patterns comunes en decision matrices
Cinco trampas que la cátedra ve recurrentemente. Eviten estas — bajan la nota incluso si el resto está bien.
“Lo elegí porque lo conozco” sin justificarlo en el contexto. Conocer el stack es un factor legítimo (TCO de capacitación), pero explicítelo: “Costo de capacitar al equipo en una herramienta nueva = ~80 horas/persona × 4 personas × USD 30/h = USD 9.600, equivale a 6 meses de Datadog SaaS para nuestro volumen, por lo tanto la familiaridad con Grafana es relevante en este contexto”. Eso es análisis. “Lo elegí porque es lo que sé” no es.
“Es lo más popular” sin contexto. La popularidad correlaciona con disponibilidad de talento, ecosistema de plugins, y madurez de docs — pero no es el criterio en sí. Argumenten desde la causa, no desde el síntoma.
“Lo OSS siempre gana”. OSS no es gratis (TCO operativo). Para un equipo sin SRE, Datadog SaaS puede ser más barato que operar EFK on-prem si miden todas las horas de tuning.
“Lo SaaS siempre lock-in”. SaaS es un grado de lock-in, pero EFK self-hosted con dashboards Kibana custom también es lock-in (migrar Kibana a Grafana es no-trivial). Lock-in es un espectro, no un binario.
“Es lo que recomendó la cátedra” sin defenderlo. La cátedra tiene una recomendación, pero no es la única respuesta correcta. Un ADR que defiende EFK con buenos argumentos saca mejor nota que uno que recomienda Loki+OTel y no lo justifica.
Recomendación honesta de la cátedra
Para no dejarlos sin guía, esto es lo que la cátedra recomienda en cada uno de los tres arquetipos típicos del mercado argentino 2026:
Empresa mediana argentina con presupuesto limitado y preferencia por OSS (la mayoría de los lectores de este TP en su primer trabajo): OTel Collector + Loki + Grafana. Footprint razonable, costo $0 de licencia, opcionalidad gracias a OTel, ecosistema Grafana ya conocido en muchos equipos, escala suficiente hasta varios GB/día. Es la combinación recomendada.
Empresa que ya tiene Elastic en otra parte del stack (búsqueda de productos, tienda online con Elastic, etc.): EFK con OTel-frontend. Reusan la inversión en Elastic, mantienen full-text search potente, y OTel les deja la puerta abierta para migrar parcialmente sin re-instrumentar. La integración entre teams (search team + observability team) suele simplificarse.
Empresa con presupuesto y aversión total a operar infra de observabilidad: Datadog o Splunk Cloud (o New Relic en su tier gratuito si están bajo 100 GB/mes). Pagar por no operar es una decisión legítima — el costo de oportunidad del tiempo del equipo de plataforma puede superar fácilmente el costo de licencia. Pero asegúrense de instrumentar con OTel SDK, no con el SDK propietario del vendor — eso preserva la opcionalidad para el día que cambie el contexto.
Esta recomendación no es prescripción. Si su escenario del Hit #3 lleva a otro lado y lo defienden con evidencia, sacan nota perfecta. Si copian esto sin justificarlo, sacan nota mediocre.
Cómo entregar
- Push final al repo público (mismo repo del TP 0/1/2) antes del 09/05/2026 23:59 ART.
- README raíz actualizado con sección “TP 2 · Parte 4
— Cierre y ADR magisterial”:
- Link al ADR
0010. - Link a la carpeta
docs/observability-final/. - Una línea con el veredicto final (“Recomendamos X para el escenario Y”) — en el README, no solo en el ADR.
- Link al ADR
- Carpeta
docs/observability-final/completa según estructura obligatoria. docs/adr/0012-stack-de-observabilidad-final.md≥ 1500 palabras.- Defensa oral agendada — la cátedra coordina horarios por Discord la semana del 03/06.
- Mensaje en el canal Discord con link al repo y al
ADR
0010.
📡 Canal Discord (consultas + entregas): https://discord.com/channels/1482135908508500148/1482135909456679139
Referencias y Bibliografía
Solo lo directamente relevante para esta Parte 4. Las referencias técnicas operativas viven en Partes 1, 2 y 3.
Toma de decisiones arquitectónicas
- Michael Nygard — “Documenting Architecture Decisions” (2011) — el blog post fundacional del formato ADR que usamos en todos los TPs. https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions
- Ford, Richards, Sadalage, Dehghani — Software Architecture: The Hard Parts (O’Reilly, 2021). Capítulo 7 sobre ADRs es lectura obligada para esta Parte 4. ISBN 978-1492086895.
- ThoughtWorks Tech Radar — entry “Lightweight Architecture Decision Records” — Adopt desde 2018, sigue vigente. https://www.thoughtworks.com/radar/techniques/lightweight-architecture-decision-records
Observabilidad — fundamentos
- CNCF Observability Whitepaper (2023) — overview oficial de logs / metrics / traces / events / profiles desde la fundación que mantiene Loki, Prometheus y OpenTelemetry. https://github.com/cncf/tag-observability/blob/main/whitepaper.md
- Charity Majors, Liz Fong-Jones, George Miranda — Observability Engineering (O’Reilly, 2022) — el libro que diferencia “monitoring” de “observability” y por qué importa. Lectura esencial para defender el ADR. ISBN 978-1492076445. https://www.oreilly.com/library/view/observability-engineering/9781492076438/
- Cindy Sridharan — Distributed Systems Observability (O’Reilly, 2018, ~80 páginas) — el reporte corto que define los 3 pilares y por qué cada parte de este TP cubre uno. Free download. https://www.oreilly.com/library/view/distributed-systems-observability/9781492033431/
Comparativa Loki / EFK / OTel
- Bryan Boreham (Grafana Labs) — KubeCon talks 2022-2024 — charlas técnicas honestas sobre cuándo Loki gana y cuándo no. Lo importante: las 5 últimas slides de cada talk son honestas sobre los límites del modelo label-first. https://www.youtube.com/c/cloudnativefdn (buscar “Boreham Loki”)
- Elastic — Logging at Scale with Elasticsearch (whitepaper) — el lado contrario, sesgado pero honesto sobre por qué full-text search importa cuando importa. https://www.elastic.co/resources
- OpenTelemetry — Why OpenTelemetry? — documentación oficial sobre el problema que resuelve. Corto y directo. https://opentelemetry.io/docs/what-is-opentelemetry/
- CNCF — State of Observability 2024 Report — encuesta anual a ~1500 ingenieros sobre qué stacks usan, qué migraciones están planeando, y por qué. https://www.cncf.io/reports/
Vendor lock-in en observabilidad
- Charity Majors — “What’s the Difference Between Monitoring and Observability?” (Honeycomb blog, 2018) — argumenta por qué los APMs propietarios pre-OTel son lock-in pesado. https://www.honeycomb.io/blog/observability-a-manifesto
- Joe Beda (ex-Heptio, ex-Google) — sobre CNCF graduation y por qué importa — varios posts en su blog. https://blog.heptio.com/ (archivado).
- Logstash → Fluentd transition (2021-2023) — caso de estudio sobre cambio de licencia y fragmentación de comunidad. https://www.elastic.co/blog/license-change-clarification
Empresas reales que migraron stacks
Ver tabla en material de apoyo — los links de cada caso están ahí, no se duplican acá.
El paper Borg-Omega-Kubernetes
- Burns, Grant, Oppenheimer, Brewer, Wilkes (2016). “Borg, Omega, and Kubernetes: Lessons learned from three container-management systems over a decade”. Communications of the ACM, 59(5). Ya está en TP 0 — repaso recomendado para entender el contexto de “decisiones arquitectónicas en sistemas de larga vida”. https://research.google/pubs/pub44843/