Python StatsD クライアントの構成

絶えず変化するソフトウェア開発環境で、拡張性の高い分散アプリケーションを構築して展開することは、道のりの半分に過ぎません。 残りの半分は、正確なメトリックを記録しながら、アプリケーションの状態とインスタンスを監視することです。

消費されているリソースの数や、特殊なプロセスによってアクセスされているファイルの数などを確認したい場合があります。これらのメトリックは、技術スタックの実行と管理に関する貴重な洞察を提供します。 これにより、設計したものの最終的なパフォーマンスを理解するためのレバレッジが得られ、最終的には最適化に役立ちます。

仕事を成し遂げるためのツールの大部分はすでにそこにありますが、今日はStatsDの詳細について話します。 独自のPythonStatsDクライアントをデプロイする方法、Pythonアプリケーションを監視するためにそれを使用する方法、そして最終的に記録されたメトリックをデータベースに保存する方法を説明させて頂きます。 その後、PrometheusまたはGraphiteを搭載したGrafanaダッシュボードにStatsDメトリックを表示したい場合は、 [MetricFire](https://www.metricfire.com/japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Configuring%20Python%20StatsD%20Client)の[デモを予約](https://www.metricfire.com/demo-japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Configuring%20Python%20StatsD%20Client)し無料トライアルをゲットしましょう。 しかし、その前に、まずはStatsDから始めましょう！

#StatsDとは何か？
StatsDは、統計とシステムパフォーマンスメトリックを収集してリッスンするnode.jsプロジェクトです。 これらの統計はネットワークを介して送信され、さまざまな種類のメトリックデータを収集できます。 StatsDを使用する主な利点は、Grafana、Graphite、InfluxDBなどの他のツールと簡単に統合できることです。

#StatsDの長所
1. 優れた起動時間
2. パーセンタイルの処理はサーバーによって行われ、一度に複数のインスタンスの集約ビューを提供します（同じサービスに対して）。
3. クライアント側のオーバーヘッドが比較的低くなります。
4. 接続の問題を防ぐためにすべてのデータを送信するためにUDPを採用しています。
5. 短命のアプリを構築するときに、シンプルで効果的かつ簡単に実装できます。
6. メトリックは到着時にのみサーバーにプッシュされるため、メモリ使用率が低くなります。

しかし…メトリックが来ると「プッシュ」されるとはどういう意味でしょうか？

主に、メトリックレポートには2つの実行モデルがあります。 プルモデルでは、監視システムは特定のHTTPエンドポイントでアプリを「スクレイプ」します。 StatsDで使用されるプッシュモデルでは、アプリケーションはメトリックを監視システムに送信します。

#前提条件とインストール
1.まず、Python3.6以降とpipをシステムにインストールする必要があります。

Linux、Windows、またはmacOSシステムで次のコマンドを実行することにより、Pythonのインストールを確認できます。

```
$ python --version
```

インストールされていない場合は、システムの[これらのインストール手順](https://www.makeuseof.com/tag/install-pip-for-python/)を確認してください。

2. StatsD、Flask、Flask-StatsDが必要になり、フラスコ関連のメトリックが自動的に収集されます。 それに加えて、virtualenvが必要になります。これは分離されたPython環境を作成するためのツールであり、SQLALCHEMYはサンプルデータベースです。

```
pip install StatsD, flask, Flask-StatsD, virtualenv, Flask-SQLAlchemy
```

Pipは、これらのパッケージの最新バージョンを自動的にインストールします。

#StatsDパッケージを使って遊んでみましょう
基本タイマーを実装することから始めます。

```
import statsd
timer = statsd.Timer('Statsd_Tutorial_Application')
timer.start()
# we can do just about anything over here
timer.stop('TutorialTimer')
```

同様に、基本カウンターの場合：

```
import statsd
counter = statsd.Counter('Statsd_Tutorial_Application')
# again do anything random over here
counter += 1
```

#Flaskによるモニタリング
このチュートリアルでは、Flaskで基本的なTo Doリストアプリケーションを設計し、操作メトリックを記録します。

完全なチュートリアルリポジトリは、[Github](https://github.com/mrinalwahal/statsd.git)からフォークできます。

ステップ1：依存関係をインポートする-5〜12行目：

```
from flask import Flask, request
from flask import render_template
from flask import redirect
from flask_sqlalchemy import SQLAlchemy
import time
import statsd
```

ステップ2：Flaskアプリ、StatsdクライアントおよびDBを起動します-14〜23行目：

```
c = statsd.StatsClient('localhost',8125)
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
```

タスククラスを作成し、DBモデルで定義します-行26〜35：

```
class Task(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text)
    done = db.Column(db.Boolean, default=False)

    def __init__(self, content):
        self.content = content
        self.done = False

db.create_all()
```

1. 主キーとして整数を保持するDB列の変数IDを作成します。
2. テキストのコンテンツ列を作成します。
3. タスクが完了/解決されたかどうかを示すために、デフォルトがfalseのブール値のdone列を作成します。
4. コンテンツと完了列を開始します。
5. データベースを印刷可能な形式で返送してください。
6. 新しいDBを作成して開始します。

ここで、タスクを追加します-行42-57：

```
@app.route('/task', methods=['POST'])
def add_task():
    start=time.time()
    content = request.form['content']
    if not content:
     dur = (time.time() - start) *1000
     c.timing("errortime",dur)
     c.incr("errorcount")
        return 'Error'

    task = Task(content)
    db.session.add(task)
    db.session.commit()
    dur = (time.time() - start) *1000
    c.timing("tasktime",dur)
    c.incr("taskcount")
```

このコードは、フォームから受け取ったタスクのコンテンツをPOSTリクエストに追加します。 ただし、ここで説明することがより重要なのは、追加されるメトリックレポートです。

1. 機能が開始するとすぐに、基本タイマーが開始されます。
2. コンテンツにエラーがある場合、エラーは基本カウンターでインクリメントされます。 同様に、エラーの時間が記録されます。 最終的に、エラーが返されます。
3. DBがタスクを追加すると、関数が実行された完全な期間が計算され、インクリメンターが更新されます。 合計期間も更新されます。

タスクの削除-60行目から65行目：

```
@app.route('/delete/&lt;int:task_id&gt;')
def delete_task(task_id):
    task = Task.query.get(task_id)
    db.session.delete(task)
    db.session.commit()
    c.incr("deletecount")
```

上記のコードは、インクリメントのために削除カウントを基本カウンターに追加することにより、DBからのタスクの削除を実行します。

#pyStatsDから[MetricFire](https://www.metricfire.com/japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Configuring%20Python%20StatsD%20Client)へのメトリックの送信
StatsDを使用してこれらのメトリックを記録するなどは、初心者には助かります。 ただし、より業界グレードの本番環境に対応する環境では、これらのメトリックは、グラフの保存と処理を容易にするサービスによって処理される必要があります。 これがGraphiteの出番です。

###Graphiteの紹介：

Graphiteは、Webサイト、アプリケーション/その他のサービス、およびネットワークサーバーのパフォーマンスを追跡するために使用される監視ツールとして設計されています。 Graphiteは、テクノロジーの世界でセンセーションを巻き起こし、本質的に新世代の監視ツールに火をつけ、時系列データの保存と取得だけでなく、共有と視覚化もはるかに簡単にしました。

Graphiteは基本的に2つの操作を実行します。

- 数値の時系列データを保存する
- このデータのグラフをオンデマンドでレンダリングする

Graphiteは収集エージェントではないため、収集エージェントのように扱うべきではありません。むしろ、測定値を時系列DBに取り込むためのより簡単なパスを提供します。 サーバーまたはローカルマシンからすでに実行されているgraphiteインスタンスへのメトリックの送信をテストするには、次の1行のコマンドを実行します。

```
`$ echo "foo.bar 1 `date +%s`" | nc localhost 2003`
```

インストールしたら、StatsDでメトリックをログに記録するだけで、ログに記録されたすべてのデータをGraphiteが取得します。 さて、Graphiteは大したことのようですが、開発者が解決したいと思っているGraphiteの特定のフォールバックがまだあります。 これが[MetricFire](https://www.metricfire.com/japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Configuring%20Python%20StatsD%20Client)の出番です。

###なぜMetricFire：

1. Graphite-as-a-Serviceを提供します
2. 現在のGraphite版のギャップを埋めるために組み込みのエージェントを追加しました
3. チームアカウントがコラボレーションに関する以前の問題を解決できるようにします
4. カスタムの詳細なダッシュボード権限
5. AWS、Herokuなどの他のサービスとの素晴らしい統合
6. [API](https://www.hostedgraphite.com/docs/api/index.html?_ga=2.10920884.1662333892.1603353088-2038175526.1567400116)を介した操作は、開発を強化します
7. ダッシュボードとユーザーデータの1時間ごとのバックアップ
8. 必要に応じて簡単かつ迅速にスケーリング
9. Graphiteモニタリングにおける確かな実績
10. 経験豊富なエンジニアによる24時間年中無休のサポート
11. プラグアンドプレイモデルで簡単に利用可能

しかし、それでも自己ホスト型および自己管理型のサービスを希望し、すべてを完全に制御したい場合は、StatsDとdockerを使用してgraphiteを起動するのが簡単な方法です。

#デプロイメント
StatsDは、お好みのアーキテクチャやその他のサービス/マイクロサービスを使用して、お好みの環境にデプロイできます。 StatsDサーバーにメトリックを送信するすべてのクライアント側アプリがStatsDサーバーに到達可能であることを確認してください。そうすれば、StatsDはそれについて文句を言いません。

ジャストイン：AWS Cloudwatchは、インフラストラクチャのホスティングにAWSクラウドを採用している場合に備えて、[StatsDメトリクスもサポート](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-custom-metrics-statsd.html)するようになりました。

私たちが蓄積したメトリックの視覚化に関する限り、Grafanaはその事実上の可視化ツールです。

自分で試してみたい場合は、[デモにサインアップ](https://www.metricfire.com/demo-japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Configuring%20Python%20StatsD%20Client)して、私たちはあなたに最適なgraphiteやPrometheusのモニタリングソリューションについて話すことができます。お気軽に、予約してください。

#StatsD API

Python StatsDクライアントにもAPIが付属しており、それを統合したい場合は[HTTPリクエストを介して](https://statsd.readthedocs.io/en/v3.2.1/reference.html)トリガーできます。

#参照

- [StatsD Github] (https://github.com/etsy/statsd)
- [Python StatsD Documentation] (http://python-statsd.readthedocs.io/en/latest/)
- [Understanding metrics & monitoring with python] (https://opensource.com/article/18/4/metrics-monitoring-and-python)
- [Graphite] (http://graphiteapp.org/)
- [Connect graphite with StatsD] (https://linoxide.com/ubuntu-how-to/setup-graphite-statsd-ubuntu-16-04/)