usa unidos toronto quebec mapa ilegal fronterizos fronteras frontera estados eeuu cruces cruce con canada abiertas logging haskell metrics

logging - unidos - ¿Cuáles son las mejores bibliotecas de Haskell para operacionalizar un programa?



frontera eeuu y canada (3)

¡Esta es una gran pregunta! Aquí hay un primer corte.

Ser capaz de iniciar sesión en múltiples niveles (por ejemplo: depuración, advertencia, etc.).

hslogger es fácilmente el marco de registro más popular.

Ser capaz de recopilar y compartir métricas / estadísticas sobre los tipos de trabajo que está haciendo el programa y cuánto tiempo lleva ese trabajo. Idealmente, las métricas recopiladas están disponibles en un formato que es compatible con las herramientas de monitoreo comúnmente utilizadas, como Ganglia, o que pueden ser tan difíciles de usar.

No conozco ninguna herramienta de informes estandarizada, sin embargo, la extracción de informes de las transmisiones +RTS -s (o de las marcas de salida de los perfiles) ha sido algo que he hecho en el pasado.

$ ./A +RTS -s 64,952 bytes allocated in the heap 1 MB total memory in use %GC time 0.0% (6.1% elapsed) Productivity 100.0% of total user, 0.0% of total elapsed

Puede obtener esto también en formato legible por máquina:

$ ./A +RTS -t --machine-readable [("bytes allocated", "64952") ,("num_GCs", "1") ,("average_bytes_used", "43784") ,("max_bytes_used", "43784") ,("num_byte_usage_samples", "1") ,("peak_megabytes_allocated", "1") ,("init_cpu_seconds", "0.00") ,("init_wall_seconds", "0.00") ,("mutator_cpu_seconds", "0.00") ,("mutator_wall_seconds", "0.00") ,("GC_cpu_seconds", "0.00") ,("GC_wall_seconds", "0.00") ]

Idealmente, podría conectarse a un tiempo de ejecución de GHC en ejecución sobre un socket y observar estas estadísticas de GC de forma interactiva, pero actualmente eso no es súper fácil (necesita un enlace FFI a la interfaz "rts / Stats.h"). Puede conectarlo a un proceso utilizando ThreadScope y controlar el comportamiento de GC y de subprocesamiento.

Banderas similares están disponibles para la creación de perfiles incrementales de time y space , que se pueden utilizar para la supervisión (por ejemplo, estos graphs se pueden construir de forma incremental).

hpc recopila muchas estadísticas sobre la ejecución del programa, a través de su tipo Tix , y las personas tienen herramientas escritas para registrar por segmento de tiempo qué código se está ejecutando.

Ser configurable, idealmente a través de un sistema que permita que las propiedades configuradas en los programas en ejecución se actualicen sin reiniciar dichos programas.

Varias herramientas están disponibles para esto, puede hacer la recarga de estado xmonad-style; o pasar al código hotswapping a través de plugins * paquetes o hint . Algunos de estos son más experimentales que otros.

Implementaciones reproducibles

Recientemente, Galois lanzó cabal-dev , que es una herramienta para hacer compilaciones reproducibles (es decir, las dependencias tienen un ámbito y están controladas).

Si voy a poner en producción un programa, hay varias cosas que necesito que haga ese programa para considerarlo "operacionalizado", es decir, ejecutable y mantenible de manera medible y verificable tanto por los ingenieros como por el personal de operaciones. Para mis propósitos, un programa operacional debe:

  • Ser capaz de iniciar sesión en múltiples niveles (por ejemplo: depuración, advertencia, etc.).
  • Ser capaz de recopilar y compartir métricas / estadísticas sobre los tipos de trabajo que está haciendo el programa y cuánto tiempo lleva ese trabajo. Idealmente, las métricas recopiladas están disponibles en un formato que es compatible con las herramientas de monitoreo comúnmente utilizadas, como Ganglia , o que pueden ser tan difíciles de usar.
  • Ser configurable, idealmente a través de un sistema que permita que las propiedades configuradas en los programas en ejecución se actualicen sin reiniciar dichos programas.
  • Ser implementable en servidores remotos de forma repetible.

En el mundo de Scala, hay buenas bibliotecas para tratar al menos con los tres primeros requisitos. Ejemplos:

En cuanto al despliegue, un enfoque adoptado en el mundo de Scala es agrupar el bytecode y las bibliotecas que componen el programa con algo como assembly-sbt , y luego enviar el paquete resultante (un "JAR") a servidores remotos con una herramienta como Capistrano que ejecuta comandos en paralelo sobre SSH. Este no es un problema que requiera herramientas específicas del lenguaje, pero tengo curiosidad de saber si existe tal herramienta en la comunidad Haskell.

Probablemente haya bibliotecas Haskell que proporcionan los rasgos que he descrito anteriormente. Me gustaría saber cuáles de las bibliotecas disponibles se consideran "mejores"; es decir, que son las más maduras, bien mantenidas, comúnmente utilizadas en la comunidad de Haskell, y ejemplares de las mejores prácticas de Haskell.

Si hay otras bibliotecas, herramientas o prácticas para hacer que el código de Haskell esté "listo para la producción", también me gustaría saber sobre ellos.


Me gustaría repetir todo lo que dijo Don y agregar algunos consejos generales.

Por ejemplo, dos herramientas y bibliotecas adicionales que quizás desee considerar:

  • QuickCheck para pruebas basadas en propiedades
  • hlint como una versión extendida de -Wall

Esos están dirigidos a la calidad del código.

Como práctica de codificación, evita Lazy IO. Si necesita la transmisión de E / S, entonces vaya con una de las bibliotecas de iteración, como el enumerator . Si observa Hackage , verá bibliotecas como http-enumerator que usan un estilo de enumerador para solicitudes http.

En cuanto a elegir bibliotecas en hackage, a veces puede ayudar a ver cuántos paquetes dependen de algo. Vea fácilmente las dependencias inversas de un paquete que puede usar este sitio web, que refleja el hackage:

Si su aplicación termina realizando bucles ajustados, como un servidor web que maneja muchas solicitudes, la pereza puede ser un problema en forma de pérdidas de espacio. A menudo, se trata de agregar anotaciones de rigor en los lugares correctos. Profiling, experience y reading core son las principales técnicas que conozco para combatir este tipo de cosas. La mejor referencia de perfiles que conozco es el Capítulo 25 de Real-World Haskell .


  • En cuanto a la configuración, he encontrado que ConfigFile es útil para mis proyectos. Lo uso para todos mis daemons en producción. No se actualiza automáticamente.
  • Uso cabal-dev para crear compilaciones reproducibles en entornos (local, desarrollador, colega local). Really cabal-dev es indispensable, especialmente por su capacidad para soportar versiones locales y parcheadas de bibliotecas dentro del directorio del proyecto.
  • Por lo que vale, iría con la recarga de estado xmonad-style. La pureza de Haskell hace que esto sea trivial; la migración es un problema, pero es de todos modos. Experimenté con hsplugins e insinué mi IRCd y, en el primer caso, había un problema de tiempo de ejecución de GHC, y en el último, un error de segmentación. Dejé las ramas en Github para postmortem posterior: https://github.com/chrisdone/hulk

Ejemplo de ConfigFile:

# Default options [DEFAULT] hostname: localhost # Options for the first file [file1] location: /usr/local user: Fred