Un error en el software puede ser disruptivo, elusivo, enloquecedor e invasivo. De hecho, un desarrollador a menudo necesita la tenacidad de Edison para encontrar y solucionar un problema.

Pero la determinación no es el único activo que necesita un desarrollador. También se necesita información para depurar el código: ¿Cuáles son los síntomas y efectos del problema? ¿Cuál es su frecuencia? ¿Su generalización? ¿Su procedencia? La evidencia y los artefactos de un error (un volcado de memoria, un seguimiento de la pila, un registro o un caso de prueba) son invaluables.

Exploremos algunas técnicas y herramientas disponibles para los desarrolladores de Ruby y Rails para recopilar e investigar evidencia de un problema. Los datos no pueden reemplazar la tenacidad, pero pueden ayudar a facilitar sus esfuerzos (y ahorrarle sueño).

Utilice variables de entorno para optimizar sus herramientas en Rails

Rails ofrece algunas herramientas excelentes para examinar una aplicación en ejecución, incluido un registrador configurable para capturar diagnósticos propios y cualquier otro que desee agregar. Rails también ofrece un registro de consultas detallado para identificar el origen de las consultas de la base de datos y un registro de puesta en cola detallado para indicar dónde se ponen en cola los trabajos en segundo plano. Los dos últimos registros están habilitados de forma predeterminada en el entornodevelopment; puede habilitar ambos en otros entornos con dos instrucciones.

Una opción de registro menos conocida disponible desde Rails 7 anota cada consulta SQL con comentarios. Si agrega lo siguiente a config/application.rbcualquier archivo de entorno:

El registro de consultas se modifica automáticamente con el nombre de la aplicación, el nombre del controlador, el nombre de la acción o el nombre del trabajo en segundo plano. El siguiente ejemplo de salida proviene directamente de la guía de depuración de Rails :

Probablemente no desee habilitar todas estas funciones en producción. La generación de registros puede resultar costosa en términos de memoria y tiempo (recursos limitados para una aplicación bajo carga).

Sin embargo, existen excepciones. Es posible que desee habilitar brevemente una función a pedido, especialmente al depurar en los modos de desarrollo y prueba. En lugar de modificar el código (y quizás volver a implementarlo) para habilitar o deshabilitar un diagnóstico, use variables de entorno para controlar el estado. En algunos entornos, como Heroku, cambiar la configuración de una variable de entorno no obliga a una nueva implementación.

Por ejemplo, puede definir un conjunto de variables para controlar el registro y el nivel de detalle.

Nombre de la variable Objetivo Valores
COMMENTED_QUERY_LOG Habilitar comentarios en el registro de consultas El valor que no está en blanco habilita la función
LOG_ALL Habilitar todas las funciones de registro El valor que no está en blanco habilita la función
LOG_LEVEL Controlar el umbral para los mensajes de registro debuginfowarnerrorfatalunknown(del orden más verboso al menos verboso)
VERBOSE_ENQUEUE_LOG Mostrar dónde se ponen en cola los trabajos El valor que no está en blanco habilita la función
VERBOSE_QUERY_LOG Mostrar el origen de cada consulta de registro activo El valor que no está en blanco habilita la función

Para mayor comodidad, cree una clase pequeña para consultar la configuración.

Ahora use las variables y el código para configurar las funciones de registro en config/application.rb:

Utilice su shell, un archivo dotenv, su integración continua o su plataforma de alojamiento e implementación para configurar cada opción. También puede utilizar una función a pedido. Simplemente inicie la aplicación con la variable de entorno definida en la línea de comandos.

Pon a punto a Puma para el desarrollo

Basándonos en la sección anterior, veamos cómo usar variables de entorno para adaptar la configuración de Puma para la depuración en el entorno de desarrollo.

Por lo general, Puma está configurado para maximizar el rendimiento en producción, ejecutando varios trabajadores y muchos subprocesos por trabajador. En desarrollo, se desea lo opuesto: un trabajador, un subproceso y un tiempo de espera muy largo para permitir la depuración interactiva. Cada uno de ellos es un parámetro que se puede ajustar.

Modificar config/puma.rbpara reflejar el siguiente código.

Ahora puede configurar las tres variables de entorno para controlar Puma en cada entorno. En el desarrollo, configure los valores para optimizar la depuración interactiva.

Si desea validar la configuración de Puma, configure la variable de entorno PUMA_LOG_CONFIG=truee inicie la aplicación. Puma emite su configuración activa al iniciarse.

Casualmente, la configuración predeterminada de Puma en la versión más reciente de Rails es similar a la que se muestra aquí (gracias a Nate Matykiewicz por el dato).

Ejecutar trabajos en segundo plano en línea

Una aplicación Rails de cualquier complejidad normalmente aprovecha los trabajos en segundo plano para ejecutar tareas que requieren un uso intensivo de recursos informáticos y que requieren una ejecución (relativamente) prolongada. Los trabajos en segundo plano se ejecutan de forma asincrónica, desconectados del ciclo de solicitud/respuesta. Los candidatos ideales para el procesamiento «fuera de banda» incluyen la generación de informes, el envío de correos electrónicos y la interacción con API de terceros. Pero la naturaleza asincrónica de los trabajos también complica la depuración.

Para simplificar la resolución de problemas, ejecute los trabajos inmediatamente en sus entornos de desarrollo y prueba locales. En el modo inmediato, los trabajos no se ponen en cola, sino que se ejecutan instantáneamente. Al ejecutarlos en «primer plano», puede establecer puntos de interrupción e inspeccionar el estado de forma interactiva.

Veamos un ejemplo en el que se utiliza Delayed Job , un backend de cola popular y fácil de administrar para Active Job . Delayed Job proporciona una configuración para habilitar la cola. De manera predeterminada, la configuración es truey los trabajos se ponen en cola como de costumbre. Sin embargo, si se configura en false, los trabajos se ejecutan inmediatamente.

Agregue el siguiente código a su aplicación en config/initializers/delayed_job.rb:

Si DELAYED_JOBS_DISABLE_JOB_QUEUESse establece en cualquier valor, se deshabilita la cola. Si la variable de entorno está en blanco o no está definida, se habilita la cola.

A continuación, en su shell, en la línea de comandos o en sus archivos dot, configúrelo
DELAYED_JOBS_DISABLE_JOB_QUEUESsegún sea necesario.


Establezca la variable de entorno en nada o elimine la variable de entorno para restaurar la puesta en cola.


No existen reglas para nombrar las variables de entorno. Elija nombres que le resulten significativos. Una convención útil para categorizar las variables es agregar un nombre de paquete como prefijo, como PUMA_DELAYED_JOB_. El primero indica variables que afectan a Puma; el segundo connota variables utilizadas por Delayed Job.

Interactuar con llamadas de red

Al igual que los trabajos en segundo plano, las aplicaciones Rails también pueden consumir
interfaces de programación de aplicaciones (API). Las API brindan acceso a servicios externos, como bases de datos GraphQL, transacciones de comercio electrónico y fuentes de datos públicos.

A continuación se muestra otro ejemplo para emitir solicitudes y respuestas HTTP de forma condicional desde la Net::HTTPbiblioteca. Si la variable de entorno DEBUG_HTTPse establece en cualquier valor que no esté en blanco, la solicitud saliente y las respuestas entrantes se imprimen en STDOUT.

Para ver la actividad de la red, simplemente inicie la aplicación con
la variable de entorno definida en la línea de comando.

El métododebug? proporciona cierta abstracción de la implementación real del indicador. Este método, junto con el resto de este código, puede formar una clase base para todas las solicitudes de red, como se muestra en este resumen tomado del código de producción .

Añade Ruby Gems a tu caja de herramientas

El universo de las gemas de Ruby es vasto: es imposible abarcar todas las excelentes gemas disponibles para la depuración. En su lugar, veamos algunas herramientas que puede agregar hoy para obtener un impulso instantáneo. Es probable que agregue cada una de estas a todos sus proyectos.

  • awesome_printtable_printcrean inspecciones completas y legibles de estructuras de datos de Ruby, incluidos los modelos de Active Record. Puede usar cualquiera de las gemas en el código o desde la consola.

A continuación se muestra un ejemplo de un modelo emitido por awesome_printen la consola:

En lugar de p, utilice appara mostrar la salida mejorada. awesome_print enumera los atributos en orden alfabético, un atributo por línea, entre otras ventajas.

  • better_errorsreemplaza la página de error estándar de Rails con un seguimiento de pila mejorado, una lista de parámetros y una consola interactiva donde puede sondear el marco de pila y las variables en el lugar de la excepción. También puede vincular vínculos de código fuente a su editor favorito. Aquí se incluye el código para vincular better_errorsa Visual Studio Code:

Ejecúta export BETTER_ERRORS_EDITOR=vscodeen su shell y reinicie el servidor Rails. Ahora los vínculos a archivos se abren automáticamente en Visual Studio.

  • Mantén las gemas fakerfactory_bot(o sus alternativas) tanto en los grupos de prueba como de desarrollo en Gemfile . Ambas son invaluables si necesitas generar datos rápidamente en la consola.

Una idea más: si utiliza AppSignal como herramienta de monitorización de aplicaciones, esta tiene funciones para interpretar los registros y detectar el origen de los errores.

La depuración es una habilidad

Depurar código es algo así como un arte y, como en cualquier esfuerzo creativo, cuanto más practiques, mejor te volverás.

Depure mientras trabaja en equipo con otro desarrollador, especialmente con uno experimentado. Si su compañero está dispuesto, piensen en voz alta juntos e intercambien ideas y puntos de vista.

 174 total views,  4 views today