Escribir un post-mortem comprobable
Un post-mortem es un relato escrito y breve de un incidente: una cronología, una causa y una lista de acciones. Importa porque uno que nadie puede comprobar solo guarda una impresión.
El incidente de coste de la biblioteca ha terminado. El equipo lo redacta, y un script pequeño compara el borrador con el registro antes de que nadie lo firme.
Al final de esta lección
Nota
Puedo escribir qué pasó, por qué y qué cambia.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Post-mortem | un relato escrito de un incidente y lo que sigue | |
| Cronología | los eventos de un incidente, en orden de tiempo | |
| Causa | por qué ocurrió, en términos que el registro confirma | |
| Acción | un cambio con responsable y fecha límite | |
| Comprobación | una forma de ver que una acción funcionó | como máximo 2 intentos |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una cronología usa las horas del registro
Una cronología lista qué pasó y cuándo, en orden. Copia cada hora de un registro. No la escribas de memoria.
Una buena cronología incluye también los tiempos lentos: cuándo empezó la causa, cuándo la notó alguien y cuándo terminó. Los huecos entre esas horas son las lecciones.
Ejemplo: los eventos de la biblioteca
| Hora | Evento |
|---|---|
| 10:55 | Sale una hoja más larga |
| 12:02 | Salta la alerta horaria de coste |
| 12:20 | Se encuentra la causa en la traza |
| 12:35 | Se limitan los intentos |
| 13:00 | El coste vuelve a estar bajo el límite |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una causa que el registro pueda confirmar
Escribe la causa como una frase que el registro pueda probar o refutar. Dice qué pasó, a qué peticiones y por qué.
«Cada pregunta de tarifas se intentaba cinco veces porque la comprobación de 40 palabras no podía aprobar» se puede comprobar. «El sistema estaba sobrecargado» no: ningún registro lo confirma.
Una acción tiene responsable y comprobación
Una acción es un cambio que arregla la causa o acorta los huecos. Cada una tiene un responsable, una fecha límite y una comprobación: una cifra que el registro mostrará cuando la acción haya funcionado.
«Tener más cuidado» no tiene nada de eso. «Como máximo 2 intentos por petición, visto en el registro en 2 días» tiene las tres cosas.
Un error frecuente
Advertencia
Mucha gente cree que un post-mortem debe decir quién tuvo la culpa. Debe decir qué del sistema permitió el fallo. Pon un nombre junto a una acción, como responsable, y en ningún otro sitio.
Escribe el borrador y el registro, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fs = require(\"fs\");' 'const EVENTS = [' ' { time: \"10:55\", code: \"sheet_published\" },' ' { time: \"12:02\", code: \"alert_fired\" },' ' { time: \"12:20\", code: \"cause_found\" },' ' { time: \"12:35\", code: \"attempts_capped\" },' ' { time: \"13:00\", code: \"cost_normal\" },' '];' 'const DRAFT = {' ' timeline: [' ' { time: \"10:55\", code: \"sheet_published\" },' ' { time: \"12:02\", code: \"alert_fired\" },' ' { time: \"12:10\", code: \"cause_found\" },' ' { time: \"13:00\", code: \"cost_normal\" },' ' ],' > pm.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el borrador y el registro, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' cause: \"Cada pregunta de tarifas se intentaba cinco veces porque la comprobación de 40 palabras no podía aprobar\",' ' actions: [' ' { what: \"Limitar los intentos a 2\", owner: \"Marta\", check: \"El registro muestra como máximo 2 intentos por petición\", days: 2 },' ' { what: \"Tener más cuidado con la hoja\", owner: \"Marta\", check: \"\", days: 5 },' ' { what: \"Alertar cada 10 minutos\", owner: \"\", check: \"Una alerta salta en menos de 10 minutos desde un pico\", days: 60 },' ' ],' '};' 'fs.writeFileSync(\"events.json\", JSON.stringify(EVENTS, null, 1));' 'fs.writeFileSync(\"postmortem.json\", JSON.stringify(DRAFT, null, 1));' >> pm.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Crea los archivos del borrador
docker exec -w /home/node/project agent node pm.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el comprobador, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fs = require(\"fs\");' 'const MAX_DAYS = 30;' 'function hasDigit(text) { return /[0-9]/.test(text); }' 'function run() {' ' const events = JSON.parse(fs.readFileSync(\"events.json\", \"utf8\"));' ' const pm = JSON.parse(fs.readFileSync(\"postmortem.json\", \"utf8\"));' ' const timeline = [];' ' const actions = [];' ' let last = \"\";' ' pm.timeline.forEach(function (entry, i) {' ' const found = events.find(function (e) { return e.code === entry.code; });' ' if (found === undefined) timeline.push(i + \":unknown_event\");' ' else if ((found.time === entry.time) === false) timeline.push(i + \":wrong_time\");' ' if (entry.time < last) timeline.push(i + \":out_of_order\");' ' last = entry.time;' ' });' > check-pm.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el comprobador, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' events.forEach(function (e) {' ' if (pm.timeline.some(function (t) { return t.code === e.code; }) === false) timeline.push(\"missing:\" + e.code);' ' });' ' pm.actions.forEach(function (a, i) {' ' if (a.owner.trim() === \"\") actions.push(i + \":no_owner\");' ' if (a.check.trim() === \"\") actions.push(i + \":no_check\");' ' else if (hasDigit(a.check) === false) actions.push(i + \":no_number\");' ' if (a.days > MAX_DAYS) actions.push(i + \":too_late\");' ' });' ' console.log(\"Cronología:\", timeline.join(\" \"));' ' console.log(\"Acciones:\", actions.join(\" \"));' ' const total = timeline.length + actions.length;' ' console.log(\"Problemas:\", total);' ' console.log(total === 0 ? \"El post-mortem está listo.\" : \"El post-mortem no está listo.\");' '}' 'module.exports = { run };' 'if (require.main === module) run();' >> check-pm.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Comprueba el borrador
docker exec -w /home/node/project agent node check-pm.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Lo que imprime el comprobador
| Línea | Qué dice |
|---|---|
| Cronología | 2:wrong_time missing:attempts_capped |
| Acciones | 1:no_check 2:no_owner 2:too_late |
| Problemas | 5 |
| Última línea | El post-mortem no está listo. |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Escribe la corrección
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fs = require(\"fs\");' 'const pm = JSON.parse(fs.readFileSync(\"postmortem.json\", \"utf8\"));' 'pm.timeline[2].time = \"12:20\"; // el registro dice 12:20' 'pm.timeline.splice(3, 0, { time: \"12:35\", code: \"attempts_capped\" });' 'pm.actions[1].what = \"Probar cada hoja con la comprobación de 40 palabras antes de publicarla\";' 'pm.actions[1].check = \"Cada caso de la evaluación pasa la comprobación de 40 palabras antes de publicar una hoja\";' 'pm.actions[2].owner = \"Luis\";' 'pm.actions[2].days = 14;' 'fs.writeFileSync(\"postmortem.json\", JSON.stringify(pm, null, 1));' 'require(\"./check-pm\").run();' > fix-pm.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Arregla el borrador y comprueba de nuevo
docker exec -w /home/node/project agent node fix-pm.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.