プログラムを運用するのに最適なHaskellライブラリは何ですか?[閉まっている]


115

プログラムを運用環境に導入する場合、そのプログラムが "運用可能"であると見なすためには、そのプログラムを実行する必要があるいくつかのこと、つまり、エンジニアと運用スタッフの両方が測定可能で検証可能な方法で実行および保守できるようにします。私の目的では、運用可能なプログラムは次の要件を満たしている必要があります。

  • 複数のレベルでログを記録できる(例:デバッグ、警告など)。
  • プログラムが実行している作業の種類とその作業にかかっている時間に関するメトリック/統計を収集して共有できるようにします。理想的には、収集された指標は、Gangliaなどの一般的に使用されている監視ツールと互換性のある形式で使用できるか、またはそのように変更することができます。
  • プログラムを再起動せずに、実行中のプログラムで構成されたプロパティを更新できるシステムを介して、理想的には構成可能にする。
  • 繰り返し可能な方法でリモートサーバーに展開できる。

Scalaの世界には、少なくとも最初の3つの要件に対処するための優れたライブラリーがあります。例:

デプロイに関しては、Scalaの世界で採用されている1つのアプローチは、プログラムを構成するバイトコードとライブラリをassembly-sbtのようなものでバンドルし、結果のバンドル(「ファットJAR」)をCapistranoのようなツールでリモートサーバーにプッシュすることです。SSH経由でコマンドを並列実行します。これは言語固有のツールを必要とする問題ではありませんが、Haskellコミュニティにそのようなツールが存在するかどうか知りたいです。

おそらく、上記で説明した特性を提供するHaskellライブラリがあるでしょう。利用可能なライブラリのうち、「最良」と見なされているものを知りたいのですが。つまり、Haskellコミュニティで一般的に使用されている、最も成熟し、よく管理されている、Haskellのベストプラクティスの例です。

Haskellのコードを「本番対応」にするためのライブラリ、ツール、またはプラクティスが他にある場合は、それらについても知りたいと思います。


1
Haskellはネイティブにコンパイルされているため、4番目の弾丸は問題を引き起こす可能性があります。静的にコンパイルすることもできますが、これは機能する場合と機能しない場合がありますが、開発サーバーよりも本番サーバーで同様の環境が最適です。Cabal-devはサンドボックス環境であり、他のマシンへの転送に適している可能性があります。それでも、少なくとも基本ライブラリをターゲットマシンにインストールする必要があります。
Masse、

1
他のツールと手法に関しては、このSOの質問に概要があります。stackoverflow.com
Don Stewart

1
もう1つ、* nixシステムでは、/ procファイルシステムを介して大量のプロセス統計とメタデータに直接アクセスできます。したがって、それを内省するためにいくつかのルーチンを作成する場合、ランタイムへの直接フ​​ックの欠如を置き換えるのに役立ちます。
sclv

1
同じ環境でビルドする限り、バイナリの展開は簡単です(コンピューターが異なるアーキテクチャの場合はステージングサーバーが必要です)。次に、バイナリと任意の外部ファイルをrsyncできます。再起動コマンドを自動的に実行するためのhaskell用のsshライブラリはありませんが、capistranoを使用できます。
グレッグウェーバー

1
@tchrist彼は最初の段落の残りと箇条書きのリストを、操作可能な単語の直後に費やして、わかりやすい英語でその意味を説明しています。
McCutchen氏、

回答:


54

これは素晴らしい質問です!これが最初のカットです。

複数のレベルでログを記録できる(例:デバッグ、警告など)。

hsloggerは、最も人気のあるロギングフレームワークです。

プログラムが実行している作業の種類とその作業にかかっている時間に関するメトリック/統計を収集して共有できるようにします。理想的には、収集されたメトリックスは、Gangliaなどの一般的に使用されている監視ツールと互換性のある形式で使用できるか、またはそのように変更することができます。

標準化されたレポートツールについては知りませんが、+RTS -sストリームから(またはプロファイリング出力フラグを介して)レポートを抽出することは、これまでに行ってきました。

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

これも機械可読形式で取得できます。

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

理想的には、ソケットを介して実行中のGHCランタイムに接続し、これらのGC統計をインタラクティブに見ることができますが、現在のところそれは非常に簡単ではありません(「rts / Stats.h」インターフェースへのFFIバインディングが必要です)。ThreadScopeGCとスレッドの動作を使用してプロセスに接続し、監視できます。

同様のフラグは、ログに記録された時間スペースのプロファイリングに利用でき、監視に使用できます(これらのグラフはインクリメンタルに構築できます)。

hpcそのTixタイプを介して、プログラムの実行に関する多くの統計を収集し、人々はコードが実行しているものをタイムスライスでログに記録するツール書いています。

プログラムを再起動せずに、実行中のプログラムで構成されたプロパティを更新できるシステムを介して、理想的には構成可能にする。

これにはいくつかのツールが利用できます。xmonadスタイルの状態の再読み込みを行うことができます。または、plugins*パッケージまたはhint。これらのいくつかは他のものより実験的です。

再現可能な展開

Galoisは最近リリースされましたcabal-dev。これは再現可能なビルドを行うためのツールです(つまり、依存関係のスコープと制御は異なります)。


6
dyreパッケージは、xmonadスタイルの状態のリロードを抽象化することになっているので、特に言及する必要があると思います。ただし、これは再コンパイルと再デプロイメントを結び付けるものであり、実際にはツールチェーン全体を使用するマシンの変更に関するものです。リモートの再デプロイでは、酸味のようなものが必要ですが、私の好みでは少し重いです。保証が弱いこの永続的なmvar抽象化がありますが、バイナリの起動ごとに、保持されている最後のデータが魔法のように入力されるプレーンなMVarのように扱うことができます。
sclv

2
また、GHCの新しいEventLogロギングフレームワーク(+RTS -l実行時に使用)は、出力をファイルにストリーミングします。これは、イベントログ形式を読み取る任意のツールで視覚化できます。
Don Stewart

2
プログラムは、次のようにそのイベントのログを出力します:galois.com/~dons/tmp/A.event.log- これは、-i.imgur.com/QAe6r.pngとして視覚化できます。このフォーマットの上に他の監視ツールを構築することを想像できます。
Don Stewart、

2
また、プロファイリングツールの多くはテストには適していますが、量産コードにはそれほど多くありません。たとえば、オーバーヘッドを除いて、-profは単一のプロセッサでのみ使用できます。
sclv

9
  • 構成に関しては、ConfigFileが私のプロジェクトに役立つことがわかりました。本番環境のすべてのデーモンに使用します。自動的には更新されません。
  • 私は環境全体(ローカル、開発、同僚ローカル)で再現可能なビルドを作成するためにcabal-devを使用します。本当にcabal-devは、特にプロジェクトディレクトリ内のパッチを当てたローカルバージョンのライブラリをサポートする機能にとって不可欠です。
  • 価値のあるものについては、xmonadスタイルの状態の再読み込みを使用します。Haskellの純度はこれを簡単にします。移行は問題ですが、とにかく問題です。IRCdのhspluginsとヒントを試してみましたが、前者の場合はGHCランタイムの問題があり、後者の場合はセグメンテーション違反がありました。私は後の検死のためにブランチをGithubに残しました:https : //github.com/chrisdone/hulk

ConfigFileの例:

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

9

私はドンが言ったすべてをエコーし​​、いくつかの一般的なアドバイスを追加します。

たとえば、次の2つの追加のツールとライブラリを検討する必要があります。

  • プロパティベースのテスト用のQuickCheck
  • 拡張バージョンとしてのhlint-Wall

どちらもコード品質をターゲットにしています。

コーディング慣行として、レイジーIOは避けてください。あなたがIOをストリーミング必要がある場合、そのようなiterateeライブラリのいずれかで行く列挙子Hackageを見ると、http要求に列挙子スタイルを使用するhttp-enumeratorなどのライブラリが表示されます。

ハッカーでライブラリを選択することに関しては、何かに依存しているパッケージの数を調べると役立つ場合があります。ハッキングを反映した、このWebサイトを使用できるパッケージの逆の依存関係を簡単に確認できます。

アプリケーションが多くのリクエストを処理するWebサーバーのようにタイトなループを実行してしまう場合、遅延はスペースリークの問題である可能性があります。多くの場合、これは適切な場所に厳密性注釈を追加することの問題です。プロファイリング、経験、リーディングコアは、私がこの種のことと戦うために知っている主要なテクニックです。私が知っている最良のプロファイリングリファレンスは、Real-World Haskellの第25章です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.