Quelles sont les meilleures bibliothèques Haskell pour opérationnaliser un programme? [fermé]

115

Si je veux mettre un programme en production, il y a plusieurs choses que je dois faire pour que ce programme le considère comme "opérationnalisé" - c'est-à-dire qu'il est opérationnel et maintenable de manière mesurable et vérifiable par les ingénieurs et le personnel d'exploitation. À mes fins, un programme opérationnel doit:

  • Être capable de se connecter à plusieurs niveaux (ex: débogage, avertissement, etc.).
  • Être en mesure de collecter et de partager des mesures / statistiques sur les types de travail effectué par le programme et la durée de ce travail. Idéalement, les métriques collectées sont disponibles dans un format compatible avec les outils de surveillance couramment utilisés tels que Ganglia , ou peuvent être ainsi intégrées.
  • Être configurable, idéalement via un système qui permet de mettre à jour les propriétés configurées dans les programmes en cours d'exécution sans redémarrer lesdits programmes.
  • Être déployable sur des serveurs distants de manière répétable.

Dans le monde Scala, il existe de bonnes bibliothèques pour traiter au moins les trois premières exigences. Exemples:

En ce qui concerne le déploiement, une approche adoptée dans le monde Scala est de regrouper le bytecode et les bibliothèques qui composent son programme avec quelque chose comme assembly-sbt , puis de pousser le bundle résultant (un "fat JAR") vers des serveurs distants avec un outil comme Capistrano qui exécute des commandes en parallèle sur SSH. Ce n'est pas un problème qui nécessite des outils spécifiques au langage, mais je suis curieux de savoir si un tel outil existe dans la communauté Haskell.

Il existe probablement des bibliothèques Haskell qui fournissent les caractéristiques que j'ai décrites ci-dessus. J'aimerais savoir lesquelles des bibliothèques disponibles sont considérées comme «les meilleures»; c'est-à-dire qui sont les plus matures, bien entretenues, couramment utilisées dans la communauté Haskell et exemplaires des meilleures pratiques Haskell.

S'il y a d'autres bibliothèques, outils ou pratiques pour rendre le code Haskell "prêt pour la production", j'aimerais aussi les connaître.

Alex Payne
la source
1
La quatrième puce peut causer des problèmes, car Haskell est compilé en natif. Vous pouvez essayer de compiler de manière statique, ce qui pourrait ou non fonctionner, mais de manière optimale, vous auriez un environnement similaire sur le serveur de production que sur le serveur de développement. Cabal-dev est un environnement sandbox, qui peut convenir au transfert vers d'autres machines. Même dans ce cas, il faudrait au moins que les bibliothèques de base soient installées sur la machine cible.
Masse le
1
Concernant les autres outils et techniques, cette question SO a un aperçu: stackoverflow.com/questions/3077866/...
Don Stewart
1
Une autre chose - vous pouvez accéder sur les systèmes * nix à une énorme quantité de statistiques de processus et de métadonnées directement via le système de fichiers / proc. Donc, si vous écrivez quelques routines pour introspecter cela, cela aide à remplacer le manque de hooks directs dans le runtime.
sclv
1
le déploiement d'un binaire est facile tant que vous construisez sur le même environnement (vous devriez avoir un serveur intermédiaire si votre ordinateur est d'une architecture différente). Ensuite, vous pouvez rsync le binaire et tous les fichiers externes. Il n'y a pas de bibliothèque ssh pour haskell pour exécuter automatiquement les commandes de redémarrage, mais vous pouvez utiliser capistrano.
Greg Weber
1
@tchrist Il passe le reste du premier paragraphe et la liste à puces immédiatement après le mot opérationnalisé à expliquer sa signification en anglais simple.
Will McCutchen

Réponses:

54

C'est une excellente question! Voici une première coupe.

Être capable de se connecter à plusieurs niveaux (ex: débogage, avertissement, etc.).

hslogger est de loin le cadre de journalisation le plus populaire.

Être en mesure de collecter et de partager des mesures / statistiques sur les types de travail effectué par le programme et la durée de ce travail. Idéalement, les métriques collectées sont disponibles dans un format compatible avec les outils de surveillance couramment utilisés tels que Ganglia, ou peuvent être ainsi intégrées.

Je ne connais aucun outil de reporting standardisé, cependant, l'extraction de rapports à partir de +RTS -sflux (ou via le profilage des indicateurs de sortie) a été quelque chose que j'ai fait dans le passé.

$ ./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

Vous pouvez également l'obtenir dans un format lisible par machine:

$ ./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")
 ]

Idéalement, vous pourriez vous connecter à un runtime GHC en cours d'exécution sur une socket et regarder ces statistiques GC de manière interactive, mais actuellement ce n'est pas super facile (nécessite une liaison FFI à l'interface "rts / Stats.h"). Vous pouvez vous attacher à un processus en utilisant ThreadScopeet surveiller le GC et le comportement des threads.

Des indicateurs similaires sont disponibles pour le profilage incrémentiel, de temps et d' espace consigné , qui peuvent être utilisés pour la surveillance (par exemple, ces graphiques peuvent être construits de manière incrémentielle).

hpcrecueille beaucoup de statistiques sur l'exécution du programme, via son Tixtype, et les gens ont écrit des outils pour enregistrer par tranche de temps le code en cours d'exécution.

Être configurable, idéalement via un système qui permet de mettre à jour les propriétés configurées dans les programmes en cours d'exécution sans redémarrer lesdits programmes.

Plusieurs outils sont disponibles pour cela, vous pouvez effectuer un rechargement d'état de style xmonad; ou passez au code hotswapping via plugins* packages ou hint. Certains d'entre eux sont plus expérimentaux que d'autres.

Déploiements reproductibles

Galois a récemment publié cabal-dev, qui est un outil pour faire des constructions reproductibles (c'est-à-dire que les dépendances sont étendues et contrôlées).

Don Stewart
la source
6
Le paquet dyre est censé faire abstraction du rechargement d'état de style xmonad, il faut donc le mentionner en particulier, je pense. Cependant, cela lie la recompilation et le redéploiement, il s'agit donc vraiment de changements sur une machine avec l'ensemble de la chaîne d'outils. Pour les redéploiements à distance, vous voulez quelque chose de plus comme l'état acide, bien que ce soit un peu lourd à mon goût. J'ai cette abstraction persistante de mvar qui a des garanties plus faibles, mais que vous pouvez simplement traiter comme un MVar simple qui est rempli par magie à chaque lancement d'un binaire avec les dernières données qu'il détenait.
sclv
2
En outre, le nouveau EventLogcadre de journalisation de GHC (utilisé +RTS -lau moment de l'exécution) diffuse la sortie dans un fichier, qui peut être visualisé avec n'importe quel outil lisant le format du journal des événements.
Don Stewart
2
Un programme émettra des journaux de ses événements, comme ceci: galois.com/~dons/tmp/A.event.log - qui peut être visualisé comme - i.imgur.com/QAe6r.png . Je pourrais imaginer construire d'autres outils de surveillance en plus de ce format.
Don Stewart
2
Notez également que de nombreux outils de profilage sont parfaits pour les tests, mais pas tant pour le code de production. Laissant de côté les frais généraux, -prof par exemple ne peut être utilisé qu'avec un seul processeur.
sclv
9
  • En ce qui concerne la configuration, j'ai trouvé que ConfigFile était utile pour mes projets. Je l'utilise pour tous mes démons en production. Il ne se met pas à jour automatiquement.
  • J'utilise cabal-dev pour créer des builds reproductibles dans des environnements (local, dev, collègue-local). Vraiment cabal-dev est indispensable, en particulier pour sa capacité à prendre en charge les versions locales et corrigées des bibliothèques dans le répertoire du projet.
  • Pour ce que ça vaut, j'irais avec le rechargement d'état de style xmonad. La pureté de Haskell rend cela trivial; la migration est un problème, mais c'est de toute façon. J'ai expérimenté des hsplugins et des astuces pour mon IRCd et dans le premier cas, il y avait un problème d'exécution GHC, et dans le second une erreur de segmentation. J'ai laissé les branches sur Github pour un post-mortem plus tard: https://github.com/chrisdone/hulk

Exemple de ConfigFile:

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

Je ferais écho à tout ce que Don a dit et ajouterais quelques conseils d'ordre général.

Par exemple, deux outils et bibliothèques supplémentaires que vous voudrez peut-être envisager:

  • QuickCheck pour les tests basés sur les propriétés
  • hlint en tant que version étendue de-Wall

Ceux-ci visent tous deux la qualité du code.

Comme pratique de codage, évitez Lazy IO. Si vous avez besoin d'E / S en streaming, utilisez l'une des bibliothèques iteratee telles que l' énumérateur . Si vous regardez sur Hackage, vous verrez des bibliothèques comme http-enumerator qui utilisent un style énumérateur pour les requêtes http.

En ce qui concerne la sélection de bibliothèques sur le piratage, il peut parfois être utile de voir combien de paquets dépendent de quelque chose. Visualisez facilement les dépendances inverses d'un package que vous pouvez utiliser ce site Web, qui reflète le piratage:

Si votre application finit par faire des boucles serrées, comme un serveur Web traitant de nombreuses demandes, la paresse peut être un problème sous la forme de fuites d'espace. Il s'agit souvent d'ajouter des annotations de rigueur aux bons endroits. Le profilage, l'expérience et le noyau de lecture sont les principales techniques que je connais pour lutter contre ce genre de choses. La meilleure référence de profilage que je connaisse est le chapitre 25 de Real-World Haskell .

Jason Dagit
la source