Was sind die besten Haskell-Bibliotheken, um ein Programm zu operationalisieren? [geschlossen]

115

Wenn ich ein Programm in Produktion nehmen will, muss dieses Programm einige Dinge tun, um es als "operationalisiert" zu betrachten - das heißt, es kann sowohl von Ingenieuren als auch von Betriebspersonal messbar und überprüfbar ausgeführt und gewartet werden. Für meine Zwecke muss ein operationalisiertes Programm:

  • Sie können auf mehreren Ebenen protokollieren (z. B. Debugging, Warnung usw.).
  • Sie können Metriken / Statistiken über die Art der Arbeit des Programms und die Dauer dieser Arbeit sammeln und austauschen. Im Idealfall sind die gesammelten Metriken in einem Format verfügbar, das mit häufig verwendeten Überwachungstools wie Ganglia kompatibel ist oder so munged werden kann.
  • Konfigurierbar sein, idealerweise über ein System, mit dem konfigurierte Eigenschaften in laufenden Programmen aktualisiert werden können, ohne die Programme neu zu starten.
  • Bereitstellbar auf Remote-Servern auf wiederholbare Weise.

In der Scala-Welt gibt es gute Bibliotheken, um mindestens die ersten drei Anforderungen zu erfüllen. Beispiele:

Bei der Bereitstellung besteht ein Ansatz in der Scala-Welt darin, den Bytecode und die Bibliotheken, aus denen das Programm besteht, mit Assembly-sbt zu bündeln und das resultierende Bundle (eine "fette JAR") mit einem Tool wie Capistrano auf Remote-Server zu übertragen das führt Befehle parallel über SSH aus. Dies ist kein Problem, das sprachspezifische Tools erfordert, aber ich bin gespannt, ob es ein solches Tool in der Haskell-Community gibt.

Es gibt wahrscheinlich Haskell-Bibliotheken, die die oben beschriebenen Merkmale aufweisen. Ich würde gerne wissen, welche der verfügbaren Bibliotheken als "am besten" gelten. Das heißt, diese sind am ausgereiftesten, am besten gepflegt, werden häufig in der Haskell-Community verwendet und sind beispielhaft für die Best Practices von Haskell.

Wenn es andere Bibliotheken, Tools oder Methoden gibt, mit denen Haskell-Code "produktionsbereit" gemacht werden kann, würde ich gerne auch davon erfahren.

Alex Payne
quelle
1
Die vierte Kugel kann Probleme verursachen, da Haskell auf native kompiliert ist. Sie könnten versuchen, statisch zu kompilieren, was möglicherweise funktioniert oder nicht, aber optimalerweise haben Sie auf dem Produktionsserver eine ähnliche Umgebung wie auf dem Entwicklungsserver. Cabal-dev ist eine Sandbox-Umgebung, die möglicherweise für die Übertragung auf andere Maschinen geeignet ist. Selbst dann müssten mindestens die Basisbibliotheken auf dem Zielcomputer installiert sein.
Masse
1
In Bezug auf andere Tools und Techniken hat diese SO-Frage einen Überblick: stackoverflow.com/questions/3077866/…
Don Stewart
1
Eine andere Sache - Sie können auf * nix-Systemen direkt über das Dateisystem / proc auf eine Vielzahl von Prozessstatistiken und Metadaten zugreifen. Wenn Sie also ein paar Routinen schreiben, um dies zu überprüfen, ist es hilfreich, das Fehlen direkter Hooks in die Laufzeit zu ersetzen.
sclv
1
Das Bereitstellen einer Binärdatei ist einfach, solange Sie auf derselben Umgebung aufbauen (Sie sollten einen Staging-Server haben, wenn Ihr Computer eine andere Architektur hat). Dann können Sie die Binärdatei und alle externen Dateien synchronisieren. Es gibt keine ssh-Bibliothek für haskell zum automatischen Ausführen von Neustartbefehlen, aber Sie können capistrano verwenden.
Greg Weber
1
@tchrist Er verbringt den Rest des ersten Absatzes und die Liste mit Aufzählungszeichen unmittelbar nach dem Wort operationalisiert , um seine Bedeutung im Klartext zu erklären.
Will McCutchen

Antworten:

54

Das ist eine gute Frage! Hier ist ein erster Schnitt.

Sie können auf mehreren Ebenen protokollieren (z. B. Debugging, Warnung usw.).

hslogger ist mit Abstand das beliebteste Protokollierungsframework.

Sie können Metriken / Statistiken über die Art der Arbeit, die das Programm ausführt, und wie lange diese Arbeit dauert, sammeln und teilen. Im Idealfall sind die gesammelten Metriken in einem Format verfügbar, das mit häufig verwendeten Überwachungstools wie Ganglia kompatibel ist oder so munged werden kann.

Mir sind keine standardisierten Berichterstellungstools bekannt, aber das Extrahieren von Berichten aus +RTS -sStreams (oder über Profiling-Ausgabeflags) war etwas, was ich in der Vergangenheit getan habe.

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

Sie können dies auch in maschinenlesbarem Format erhalten:

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

Idealerweise können Sie über einen Socket eine Verbindung zu einer laufenden GHC-Laufzeit herstellen und diese GC-Statistiken interaktiv anzeigen. Derzeit ist dies jedoch nicht ganz einfach (erfordert eine FFI-Bindung an die Schnittstelle "rts / Stats.h"). Sie können mithilfe von ThreadScopeGC- und Threading-Verhalten eine Verbindung zu einem Prozess herstellen .

Ähnliche Flags sind für inkrementelle, protokollierte Zeit und Raum verfügbar Profilerstellung , die für die Überwachung verwendet werden können (zB diese Diagramme können schrittweise aufgebaut werden).

hpcsammelt eine Menge Statistiken über die Programmausführung, über ihren TixTyp und die Leute haben Tools geschrieben , um nach Zeitscheiben zu protokollieren, welcher Code ausgeführt wird.

Konfigurierbar sein, idealerweise über ein System, mit dem konfigurierte Eigenschaften in laufenden Programmen aktualisiert werden können, ohne die Programme neu zu starten.

Hierfür stehen verschiedene Tools zur Verfügung. Sie können das Status-Reload im Xmonad-Stil durchführen. oder wechseln Sie zum Code-Hotswapping über plugins* Pakete oderhint . Einige davon sind experimenteller als andere.

Reproduzierbare Bereitstellungen

Galois wurde kürzlich veröffentlicht cabal-dev, ein Tool zum Erstellen reproduzierbarer Builds (dh Abhängigkeiten werden festgelegt und kontrolliert).

Don Stewart
quelle
6
Das Dyre-Paket soll das Nachladen von Zuständen im Xmonad-Stil abstrahieren, daher sollte dies meiner Meinung nach besonders erwähnt werden. Es verbindet jedoch Neukompilierung und erneute Bereitstellung, sodass es wirklich um Änderungen auf einem Computer mit der gesamten Toolchain geht. Für Remote-Umbauten möchten Sie eher einen Säurezustand, obwohl er für meinen Geschmack etwas schwer ist. Ich habe diese beständige mvar-Abstraktion, die schwächere Garantien hat, die Sie aber wie eine einfache MVar behandeln können, die bei jedem Start einer Binärdatei mit den letzten darin enthaltenen Daten auf magische Weise gefüllt wird.
sclv
2
Das neue EventLogProtokollierungsframework von GHC ( +RTS -lzur Laufzeit) überträgt die Ausgabe in eine Datei, die mit jedem Tool visualisiert werden kann, das das Ereignisprotokollformat liest.
Don Stewart
2
Ein Programm sendet Protokolle seiner Ereignisse wie folgt aus : galois.com/~dons/tmp/A.event.log - das als - i.imgur.com/QAe6r.png visualisiert werden kann . Ich könnte mir vorstellen, andere Überwachungstools auf diesem Format aufzubauen.
Don Stewart
2
Beachten Sie auch, dass sich viele der Profiling-Tools hervorragend zum Testen eignen, aber nicht so sehr für Produktionscode. Abgesehen vom Overhead kann -prof beispielsweise nur mit einem einzigen Prozessor verwendet werden.
sclv
9
  • In Bezug auf die Konfiguration habe ich festgestellt, dass ConfigFile für meine Projekte nützlich ist. Ich benutze es für alle meine Dämonen in der Produktion. Es wird nicht automatisch aktualisiert.
  • Ich verwende cabal-dev zum Erstellen reproduzierbarer Builds in verschiedenen Umgebungen (lokal, dev, kollegenlokal). Wirklich cabal-dev ist unverzichtbar, insbesondere für die Fähigkeit, lokale, gepatchte Versionen von Bibliotheken im Projektverzeichnis zu unterstützen.
  • Für das, was es wert ist, würde ich mit Xmonad-Stil State Reloading gehen. Die Reinheit von Haskell macht dies trivial; Migration ist ein Problem, aber es ist trotzdem. Ich habe mit hsplugins und Hinweisen für meine IRCd experimentiert und im ersten Fall gab es ein GHC-Laufzeitproblem und im zweiten Fall einen Segmentierungsfehler. Ich habe die Filialen auf Github für ein späteres Postmortem verlassen: https://github.com/chrisdone/hulk

Beispiel für ConfigFile:

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

Ich würde alles wiederholen, was Don gesagt hat, und ein paar allgemeine Ratschläge hinzufügen.

Zum Beispiel zwei zusätzliche Tools und Bibliotheken, die Sie möglicherweise in Betracht ziehen sollten:

Beide zielen auf die Codequalität ab.

Vermeiden Sie als Codierungspraxis Lazy IO. Wenn Sie Streaming-E / A benötigen, verwenden Sie eine der iterierten Bibliotheken wie Enumerator . Wenn Sie sich Hackage ansehen, sehen Sie Bibliotheken wie http-enumerator, die einen Enumerator-Stil für http-Anforderungen verwenden.

Bei der Auswahl von Bibliotheken bei Hackage kann es manchmal hilfreich sein, zu prüfen, wie viele Pakete von etwas abhängen. Sehen Sie leicht die umgekehrten Abhängigkeiten eines Pakets, das Sie auf dieser Website verwenden können, die Hackage widerspiegelt:

Wenn Ihre Anwendung enge Schleifen aufweist, wie ein Webserver, der viele Anforderungen verarbeitet, kann Faulheit ein Problem in Form von Speicherplatzlecks sein. Oft geht es darum, an den richtigen Stellen strenge Anmerkungen hinzuzufügen. Profiling, Erfahrung und Lesekern sind die wichtigsten Techniken, die ich kenne, um solche Dinge zu bekämpfen. Die beste mir bekannte Profilreferenz ist Kapitel 25 von Real-World Haskell .

Jason Dagit
quelle