TCPポート毎の接続数を時系列モニタリングしたい

## TCPポート毎の接続数を時系列グラフ化する機能がなければ作る

### Datadogのカスタムメトリックの記録です

Datadogサポートの回答では「現在は、TCPポート毎の接続数をグラフ化するメトリックは存在しない」とのこと。Linuxのssコマンドを使うと、今この瞬間のポート接続リストを取得できる。これを集計すれば現在のポートの接続数を取得できる。これを時系列にメトリックで埋めていけばいい。Datadogに無い機能ならカスタムメトリックをつくることができる。

### TCPポート接続数を表示するコマンド
コマンドを実行した瞬間のTCPポート Established になっている数をカウントする。現在のTCPポート22の接続数は２個と表示された。

```
$ ss –ant4 | grep ':22' | grep ESTAB | wc –l
2
```

カウントする前はこのような情報です。２個 Established されて繋がっていることが分かる。

```
$ $ ss -ant4 | grep ':22' | grep ESTAB
tcp   ESTAB     0      0     133.18.***.***:22          220.146.***.***:60182
tcp   ESTAB     0      52    133.18.***.***:22          220.146.***.***:55585
```

### ダッシュボードで表示したサンプル
下図は複数SSH接続ためしているので12~15程度カウントしています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/6072ea4c-14fd-435e-8308-cfac024cce12.png)


## カスタムメトリックの生成方法

Datadogエージェントがインストールされていれば、独自のコンフィグとチェックコードの２つを配置してDatadogエージェントを再起動するだけで、独自のメトリックを取り込める。

### コンフィグファイル
最小限のメトリック収集間隔を書いた場合

``` コンフィグ（/etc/datadog-agent/conf.d/kano.yaml）
init_config:

instances:
  - min_collection_interval: 15
    port: 22
```

### チェックコード
カスタムメトリックを生成するpythonコード。独自メトリックをDatadogエージェント経由でDatadogダッシュボードに取り込む。下記はTCPポート22（SSH）の場合。ポート番号を変えれば他のTCPポートに応用できる。

``` チェックコード（/etc/datadog-agent/checks.d/kano.py）
from datadog_checks.base import AgentCheck
import subprocess
__version__ = "0.0.2"

class KanoCheck(AgentCheck):
    def check(self, instance):
        try:
            # Linuxコマンドを実行　例： $ ss –an | grep ':22' | grep ESTAB | wc –l
            tcp_port = instance.get('port')
            result = subprocess.run(
                "ss -ant4 | grep ':" + tcp_port + "' | grep ESTAB | wc -l",
                shell=True, capture_output=True, text=True
            )

            # コマンド結果の成功・失敗を検査
            if result.returncode != 0:
                raise Exception(f"コマンド実行に失敗{result.stderr.strip()}")

            # 結果をメトリックスとしてDatadogインテークサーバーへ送信
            self.gauge(
                'custom_tcp.connections',
                int( result.stdout.strip() ),
                tags=['host:game.funnygeekjp.com']
            )

        except Exception as e: print(f"エラー発生{e}")
```

### 独自チェックコードを有効化する
datadogエージェントを再起動する。その後、エラーが無いか検査する

```
$ python3 kano.py
ここにエラーがなければ成功
$ sudo systemctl restart datadog-agent
$ sudo datadog-agent check kano

  Running Checks
  ==============

    kano (0.0.2)
    ------------
      Instance ID: kano:ead2e4ef31fc6720 [OK]
      Configuration Source: file:/etc/datadog-agent/conf.d/kano.yaml
      Total Runs: 1
      Metric Samples: Last Run: 1, Total: 1
```

### Python モジュールの追加
Python のDatadog AgentCheck モジュールを実行するには事前に１回だけ以下インストールする。

```
$ sudo pip install datadog-checks-base
$ sudo pip install lazy_loader
```

### 参考にしたWEB

▼ Agent Integrations
[https://datadoghq.dev/integrations-core/base/api/](https://datadoghq.dev/integrations-core/base/api/)

▼カスタムAgentチェックの書き方
[https://docs.datadoghq.com/ja/developers/custom_checks/write_agent_check/](https://docs.datadoghq.com/ja/developers/custom_checks/write_agent_check/)

### 正しくカスタムメトリックを送信できたか確認する方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/73e9fd09-0e56-420d-9f02-4482f632114e.png)

### メトリックを探す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/b99fc84e-8d0d-43dd-a650-b13993459dfc.png)

以上