netdataによるPostgreSQLのリアルタイムモニタリング　その2

前回書いたnetdataの記事では、とりあえずnetdataを動かすことをやりました。
今回はnetdataをちゃんと使うということで、PostgreSQLの連携部分について、記事にします。
netdataのカスタムダッシュボードについては次回。

netdataの環境構築については[コチラ](http://qiita.com/U_ikki/items/ace27b4d1ffb3711035a)、PostgreSQLの構築は[コチラ](http://qiita.com/U_ikki/items/21242bc6497ed12e82e7)をご参考ください。

# 環境

- CentOS 7.3
- PostgreSQL 9.6.1（RPMでインストール済み）
- netdata（インストール済み）
- VirtualBox 5.8.14


# 1. PostgreSQLとnetdataの連携

## 1-1. psycopg2のインストール

netdataとPostgreSQLのインストールが終わっていれば、やることはたった2つだけです。

- python-psycopg2のインストール

```
# yum install python-psycopg2
```

- pipでpsycopg2をインストール

```
# export PATH=/usr/pgsql-9.6/bin/:$PATH
# pip install psycopg2
```

※pipでのインストールでは、pg_configにパスを通す必要があるので注意

## 1-2. PostgreSQLとnetdataを起動

netdataがデフォルトの設定であれば、あとは起動するだけでOKです。
ただし、起動する順番はPostgreSQL、netdataの順番にする必要があります。netdataは接続に失敗すると再接続はしてくれない。（たぶん）

```
# su - postgres
$ pg_ctl start
$ exit
# systemctl start netdata.service 
```

これでnetdataからPostgreSQLの情報を見れるようになったと思います。

ポート19999でnetdataが起動しているので、ブラウザから以下にアクセスします。
http://＜IPアドレス＞:19999/

右のメニューに「Postgres local」という項目が増えているはずです。選択するとこのような感じでPostgreSQLに関する情報が見れます。

<img width="914" alt="netdata_postgres-org.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/125929/55fb5607-0fe2-c790-4fc3-250470aa3759.png">

どうでしょうか？サクッとできる割にいい感じに表示してくれます。

## netdataによるPostgreSQLのモニタリング内容
netdataでは、クラスタ内の各DBの以下の情報を取得、表示しています。

- DBへの接続数
- タプルのスキャン量（スキャン種別）
- ロックの数
- インデックス数、トータルサイズ
- テーブル数、トータルサイズ
- WALのアーカイブ状況
- バックグラウンドライター


### トラブルシュート
「PostgreSQLの項目が増えてない！」という方は以下の内容をチェックしてみてください。
ちょっとした確認項目ですが、ご参考までに。

- トラシュー１：PostgreSQL、netdataは起動している？

まずは以下のコマンドでプロセスの状況を調べてみましょう。

```
# ps -ef | grep postgres
```

```
# systemctl status netdata.service
```

プロセスが動いているようであれば、次はそれぞれのログファイルを確認してみてください。
netdataのログは/var/log/netdata/配下に格納されています。

- トラシュー２：PostgreSQLへの接続設定

PostgreSQLと連携が上手くいかない場合の次に考えられる可能性としては、PostgreSQLのpg_hba.confを変更していることです。PostgreSQLが使用するportを変えているとnetdataのデフォルト設定では接続できません。
その場合、netdataの接続設定ファイルを書き直してください。

```/etc/netdata/python.d/postgres.conf
tcpipv4:
    name     : 'local'
    database : 'postgres'
    user     : 'postgres'
    host     : '127.0.0.1'
    port     : 5432
```

上記デフォルトの設定では、netdataはpostgresユーザを使い、postgresサーバに接続するようになっていますので、適宜修正してください。

なお、デフォルトでは上記の項目以外に「socket」、「tcp」、「tcpipv6」が有効になっていますが、tcpipv4の項目のみ残してあとは無効にしても（少なくとも自分の環境では）問題ないです。


# 2. 取得内容のカスタマイズ

今回はお試しということで、pgbenchの「-P 1」オプションで出力される毎秒ごとのスループットをnetdataで取得できるようにしてみました。

<img width="748" alt="netdata_pgbench.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/125929/8aedc953-d641-458c-5543-8530ce482a01.png">

PostgreSQLからは、全て/usr/libexec/netdata/python.d/postgres.chart.pyで情報を引っ張ってきているだけなので、そのスクリプトを変更すれば、任意のテーブルからデータを取得できるようになります。

## 追記例
上記のグラフを出す場合、postgres.chart.pyをこんな感じ内容を追記すればOKです。
bench_scoreテーブルを作っておき、そこにtpsの値を入れておけば、あとはnetdataがその値をグラフ化してくれます。

```
 20 BENCH = """
 21 SELECT
 22     tps
 23 FROM
 24     bench_score;
 25 """
・・・
119 ORDER = ['bench_score','db_stat_transactions', 'db_stat_tuple_read', 'db_stat_tuple_returned', 'db_stat    _tuple_write',
120          'backend_process', 'index_count', 'index_size', 'table_count', 'table_size', 'wal', 'backgroun    d_writer']
・・・
122 CHARTS = {
123     'bench_score':{
124         'options':[None, 'pgbench TPS', 'tps', 'benchmark score', 'postgres.bench_score', 'line'],
125         'lines': [
126             ['bench_tps', 'tps', 'absolute']
127         ]},
・・・
317     def add_stats(self, cursor):
318         self.add_bench_stats(cursor)
・・・
333     def add_bench_stats(self, cursor):
334         cursor.execute(BENCH)
335         temp = cursor.fetchone()
336         self.data['bench_tps'] = int(temp.get('tps',0))
```

## 余談：netdataのプラグインの設定

netdataには元々色々なミドルと連携できるように、mysqlとかapacheとか色々なpythonのスクリプトが用意されています。
それらはデフォルトは有効です。不要であれば必要なもの以外はコメントアウトを外して「off」に変更しておきましょう。
***※じゃないとnetdataのログがERRORだらけになります。***

```/etc/netdata/python.d.conf
・・・
mysql: no
postgresql: yes
nginx: no
・・・
```

# さいごに
これでPostgreSQLとの連携はできるようになりました。
ただ、このままでは表示される内容が多すぎて、見たい情報を探すのが大変です。。。しかも複数サーバを使用する場合はどうするんだとか。。。色々と使いにくいです。

というわけで、次回は「見たい情報だけ見る」、「リモートの情報を見る」ためのカスタムダッシュボードの書き方というのをまとめてみます。