Encontrar código no utilizado en una aplicación Rails


¿Cómo encuentro qué código se está ejecutando y qué no en producción ?

La aplicación está bien probada, pero hay muchas pruebas que prueban el código no utilizado. Por lo tanto, obtienen cobertura cuando se ejecutan pruebas... Me gustaría refactorizar y limpiar este desastre, me sigue haciendo perder el tiempo. Tengo muchos trabajos de fondo, es por eso que me gustaría que el env de producción me guiara. Al correr en heroku, puedo activar dynos para compensar cualquier impacto en el rendimiento del generador de perfiles.

Relacionados pregunta ¿Cómo puedo encontrar métodos no utilizados en una aplicación Ruby? no es útil.

Bonus: métricas para mostrar la frecuencia con la que se ejecuta una línea de código. ¡No sé por qué lo quiero, pero lo quiero! :)

Author: Community, 2012-03-16

11 answers

En circunstancias normales, el enfoque sería usar los datos de prueba para la cobertura del código, pero como dice que tiene partes de su código que se prueban pero no se usan en la aplicación de producción, podría hacer algo ligeramente diferente.

Solo para mayor claridad: No confíes en las herramientas automáticas. Solo te mostrarán los resultados de las cosas que pruebes activamente, nada más.

Con el descargo de responsabilidad detrás de nosotros, propongo que use una herramienta de cobertura de código (como rcov o simplecov para Ruby 1.9) en su aplicación de producción y mida las rutas de código que realmente usan sus usuarios. Si bien estas herramientas se diseñaron originalmente para medir la cobertura de las pruebas, también puede usarlas para la cobertura de producción

Bajo el supuesto de que durante el período de prueba se visitan todas las rutas de código relevantes, puede eliminar el resto. Desafortunadamente, esta suposición probablemente no se mantendrá completamente. Así que todavía tendrá que aplicar su conocimiento de la aplicación y su funcionamiento interno al retirar piezas. Esto es aún más importante cuando se eliminan partes declarativas (como referencias de modelos), ya que a menudo no se ejecutan directamente, sino que solo se utilizan para configurar otras partes del sistema.

Otro enfoque que podría combinarse con lo anterior es tratar de refactorizar su aplicación en características distinguidas que puede activar y desactivar. A continuación, puede desactivar las características que se sospecha que no se utilizan y comprobar si nadie se queja :)

Y como final nota: usted no encontrará una herramienta mágica para hacer su análisis completo. Esto se debe a que ninguna herramienta puede saber si cierta pieza de código es utilizada por usuarios reales o no. Lo único que las herramientas pueden hacer es crear (más o menos) gráficos estáticos de accesibilidad, diciéndole si su código se llama de alguna manera desde un cierto punto. Con un lenguaje dinámico como Ruby, incluso esto es bastante difícil de lograr, ya que el análisis estático no aporta mucha información frente a la metaprogramación o las llamadas dinámicas que se usan mucho en un contexto rails. Así que algunas herramientas realmente ejecutan su código o intentan obtener información de la cobertura de prueba. Pero definitivamente no hay hechizo mágico.

Así que dada la alta complejidad interna (en su mayoría oculta) de una aplicación rails, no podrá realizar la mayor parte del análisis a mano. El mejor consejo probablemente sería tratar de modularizar su aplicación y desactivar ciertos módulos para probar si no se utilizan. Esto puede ser soportado por pruebas de integración adecuadas.

 32
Author: Holger Just,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-20 14:14:06

Tal vez pueda intentar usar rails_best_practices para verificar métodos y clases no utilizados.

Aquí está en el github: https://github.com/railsbp/rails_best_practices .

Ponga ' gem "rails_best_practices "' en su Gemfile y luego ejecute rails_best_practices . para generar el archivo de configuración

 21
Author: big-circle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-11 03:15:45

Tuve el mismo problema y después de explorar algunas alternativas me di cuenta de que tengo toda la información disponible fuera de la caja - archivos de registro. Nuestro formato de registro es el siguiente

Dec 18 03:10:41 ip-xx-xx-xx-xx appname-p[7776]:   Processing by MyController#show as HTML

Así que creé un script simple para analizar esta información

zfgrep Processing production.log*.gz |awk '{print $8}' > ~/tmp/action

sort  ~/tmp/action | uniq -c |sort -g -r > ~/tmp/histogram

Que produjo resultados de la frecuencia con la que se accedió a una acción#de controlador dada.

4394886 MyController#index
3237203 MyController#show
1644765 MyController#edit

El siguiente paso es compararlo con la lista de todos los pares de acciones del controlador#en la aplicación (usando rake routes output o puede hacer el mismo script para probar suite)

 12
Author: katzmopolitan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-04 17:23:56

Checkout la gema coverband, hace exactamente lo que estás buscando.

 11
Author: Dmitry Polushkin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-04 17:38:16

No estoy muy familiarizado con Ruby y RoR, pero lo que sugeriría una suposición loca:

  • add :after_filter method wich logs name of previous called method (grab it from call stack) to file
  • desplegar esto en producción
  • espere un rato
  • elimine todos los métodos que no están en el registro.

P. s. probablemente la solución con Alt + F7 en NetBeans o RubyMine es mucho mejor:)

 4
Author: alex.b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-16 11:24:03

Ya tienes la idea de marcar métodos sospechosos como privados (lo que tal vez romperá su aplicación).

Una pequeña variación que hice en el pasado: Agregar un código pequeño a todos los métodos sospechosos para registrarlo. En mi caso se trataba de una ventana emergente de usuario "Usted llamó a una función obsoleta - si realmente necesita por favor póngase en contacto con el IT". Después de un año tuvimos una buena visión general de lo que realmente se usaba (era una aplicación de negocios y allí donde las funciones solo necesitaban una vez al año).

En su caso usted solo debe registrar el uso. Todo lo que no se registra después de un período razonable no se utiliza.

 4
Author: knut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-24 08:57:22

Metaprogramación

Objeto # method_missing

Invalida Object#method_missing. En el interior, registre la clase que llama y el método , de forma asíncrona, en un almacén de datos. Luego llame manualmente al método original con los argumentos adecuados, basados en los argumentos pasados a method_missing.

Árbol de objetos

Luego compare los datos en el almacén de datos con el contenido del árbol de objetos de la aplicación.

descargo de responsabilidad: Esto seguramente requerirá un rendimiento significativo y consideración de los recursos. Además, tomará un poco de retoques para que funcione, pero teóricamente debería funcionar. Lo dejaré como un ejercicio para que el póster original lo implemente. ;)

 2
Author: Patrick Klingemann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-27 06:23:00

¿Ha intentado crear un conjunto de pruebas usando algo como sahi entonces podría grabar todos sus viajes de usuario usando esto y vincular esas pruebas a rcov o algo similar.

Tienes que asegurarte de tener todos los journies de usuario, pero después de eso puedes ver lo que rcov escupe y al menos comenzar a podar cosas que obviamente nunca están cubiertas.

 1
Author: krystan honour,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-22 16:15:59

Este no es un enfoque muy proactivo, pero a menudo he utilizado los resultados recopilados de New Relic para ver si algo que sospechaba que no se había utilizado se había llamado a la producción en cualquier momento en el último mes más o menos. Sin embargo, las aplicaciones en las que he usado esto han sido bastante pequeñas, y son decentemente caras para aplicaciones más grandes.

Nunca lo he usado, pero este post sobre la gema láser parece hablar de resolver su problema exacto.

 1
Author: Chris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-23 14:39:40

No es la solución perfecta, pero por ejemplo en NetBeans puede encontrar usos de los métodos haciendo clic derecho sobre ellos (o presione Alt+F7).
Así que si el método no se usa, lo verás.

 0
Author: beornborn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-16 11:04:36

Marque los métodos sospechosos como privados. Si eso no rompe el código, compruebe si los métodos se utilizan dentro de la clase. a continuación, puede eliminar cosas

 0
Author: Dirk de Kok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-21 02:59:21