Python で サーバ の Metrics を取得する方法を調べていました。
Python にはいくつかライブラリがありますが、psutil よく使われているライブラリに思いました。
よく取得されるメトリクスを psutil取得しようとすると、取得できるものできないものがあり、psutil を使ったり使わなかったりになったので、結果を記載します。


前提

以下の環境で動作確認は実施しています。

  • OS の Version

    cat /etc/redhat-release 
    CentOS Linux release 7.6.1810 (Core) 
    

  • Python の Version

    python3.6 -V
    Python 3.6.4
    


psutil の インストール

psutilインストールします。

pip3 install psutil


サーバメトリクスの取得

マカレル Mackerel に記録される指標と同じような値を取得してみます。
[Mackerel でみる Linux システムメトリック項目の見方・考え方 - えいのうにっき](https://blog.a-know.me/entry/2017/02/02/215641) を参考に Python で記録していきます。

  • loadavg5
    これは、os.getloadavg()取得できます。

    import os
    print(os.getloadavg())
    
    (0.26, 0.14, 0.15)
    
    Taple が返ってきて、2 要素目が loadavg5値になります。
    import os 
    print(os.getloadavg()[1])
    
    0.01
    

  • cpu
    os、pstuil だと、パーセント単位の指標は取得できないので、subproces で直接コマンドを発行します。
    以下、iostat -c実行結果です。

    import subprocess
    result = subprocess.getoutput('iostat -c')
    print(result)
    
    avg-cpu:  %user   %nice %system %iowait  %steal   %idle
               6.42    0.07    0.60    0.09    0.06   92.76
    
    以下、sadf実行結果です。オプション -j JSON 形式で取得できるので、Python で処理する場合はこちらのほうが使いやすいかなと思いました。
    import subprocess
    result = subprocess.getoutput('sadf -T -s 09:30:00 -j -- -u')
    print(result)
    
    {"sysstat": {
        "sysdata-version": 2.16,
        "hosts": [
            {
                "nodename": "xxxxxxxxxxxxxxxxxxxxxxxx",
                "sysname": "Linux",
                "release": "3.10.0-862.3.2.el7.x86_64",
                "machine": "x86_64",
                "number-of-cpus": 2,
                "file-date": "2019-01-19",
                "statistics": [
                    {
                        "timestamp": {"date": "2019-01-19", "time": "09:40:01", "utc": 0, "interval": 600},
                        "cpu-load": [
                            {"cpu": "all", "user": 2.07, "nice": 0.00, "system": 0.50, "iowait": 0.01, "steal": 0.08, "idle": 97.34}
                        ]
                    },
                    {
                        "timestamp": {"date": "2019-01-19", "time": "09:50:01", "utc": 0, "interval": 599},
                        "cpu-load": [
                            {"cpu": "all", "user": 1.26, "nice": 0.00, "system": 0.34, "iowait": 0.01, "steal": 0.09, "idle": 98.31}
                        ]
                    },
                    {
                        "timestamp": {"date": "2019-01-19", "time": "10:00:01", "utc": 0, "interval": 600},
                        "cpu-load": [
                            {"cpu": "all", "user": 1.77, "nice": 0.00, "system": 0.41, "iowait": 0.01, "steal": 0.09, "idle": 97.73}
                        ]
                    },
                    {
                        "timestamp": {"date": "2019-01-19", "time": "10:10:01", "utc": 0, "interval": 599},
                        "cpu-load": [
                            {"cpu": "all", "user": 1.40, "nice": 0.00, "system": 0.43, "iowait": 0.02, "steal": 0.10, "idle": 98.05}
                        ]
                    }
                ],
                "restarts": [
                ]
            }
        ]
    }}
    

  • memory
    pstuil の virtual_memory取得できます。
    以下は、used byte を MB 換算で取得しています。

    import psutil
    mem = psutil.virtual_memory()
    print(mem.used / 1024 / 1024)
    
    565.22265625
    
    psutil.virtual_memory().percent使用割合の取得を取得できます。
    import psutil
    mem = psutil.virtual_memory()
    print(mem.percent)
    
    75.3
    

  • disk
    iops (IO per seconds) の取得を試みたのですが、psutils、os では難しそうで、sadf取得しました。

    import subprocess
    result = subprocess.getoutput('sadf -T -s 12:00:00 -j -- -b')
    print(result)
    
    {"sysstat": {
        "sysdata-version": 2.16,
        "hosts": [
            {
                "nodename": "xxxxxxxxxxxxxxxxxxxxxxxx",
                "sysname": "Linux",
                "release": "3.10.0-862.3.2.el7.x86_64",
                "machine": "x86_64",
                "number-of-cpus": 2,
                "file-date": "2019-01-19",
                "statistics": [
                    {
                        "timestamp": {"date": "2019-01-19", "time": "12:10:01", "utc": 0, "interval": 600},
                        "io": {"tps": 6.40, "io-reads": {"rtps": 4.85, "bread": 142.68}, "io-writes": {"wtps": 1.54, "bwrtn": 24.70}}
                    },
                    {
                        "timestamp": {"date": "2019-01-19", "time": "12:20:01", "utc": 0, "interval": 600},
                        "io": {"tps": 106.95, "io-reads": {"rtps": 101.87, "bread": 14439.86}, "io-writes": {"wtps": 5.08, "bwrtn": 1082.39}}
                    },
                    {
                        "timestamp": {"date": "2019-01-19", "time": "12:30:02", "utc": 0, "interval": 600},
                        "io": {"tps": 4.44, "io-reads": {"rtps": 3.03, "bread": 202.79}, "io-writes": {"wtps": 1.41, "bwrtn": 22.86}}
                    },
                    {
                        "timestamp": {"date": "2019-01-19", "time": "12:40:01", "utc": 0, "interval": 599},
                        "io": {"tps": 2.11, "io-reads": {"rtps": 0.93, "bread": 52.32}, "io-writes": {"wtps": 1.19, "bwrtn": 20.12}}
                    }
                ],
                "restarts": [
                ]
            }
        ]
    }}
    

  • filesystem
    psutil.disk_usage取得できます。

    import psutil
    file = psutil.disk_usage('/')
    print(file)
    
    sdiskusage(total=27380396032, used=15950340096, free=11430055936, percent=58.3)       
    

  • interface
    psutil.net_io_counters NIC ごとの使用状況が取得できます。

    import psutil
    print(psutil.net_io_counters(pernic=True))
    
    {'eth0': snetio(bytes_sent=221607478221, bytes_recv=99279271136, packets_sent=240267074, packets_recv=822828046, errin=0, errout=0, dropin=0, dropout=0), 'eth1': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'eth2': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'lo': snetio(bytes_sent=163218076027, bytes_recv=163218076027, packets_sent=142790734, packets_recv=142790734, errin=0, errout=0, dropin=0, dropout=0)}
    
    rxkB、txkB の取得は、psutil ではできないので、sadf で取得します。
    import subprocess
    result = subprocess.getoutput('sadf -T -s 14:00:00 -j -- -n DEV')
    print(result)
    
    {"sysstat": {
        "sysdata-version": 2.16,
        "hosts": [
            {
                "nodename": "xxxxxxxxxxxxxxxxxxxxxxxx",
                "sysname": "Linux",
                "release": "3.10.0-862.3.2.el7.x86_64",
                "machine": "x86_64",
                "number-of-cpus": 2,
                "file-date": "2019-01-19",
                "statistics": [
                    {
                        "timestamp": {"date": "2019-01-19", "time": "14:10:01", "utc": 0, "interval": 599},
                        "network": {
                            "net-dev": [
                                {"iface": "eth0", "rxpck": 43.48, "txpck": 19.79, "rxkB": 4.21, "txkB": 22.30, "rxcmp": 0.00, "txcmp": 0.00, "rxmcst": 0.00},
                                {"iface": "eth1", "rxpck": 0.00, "txpck": 0.00, "rxkB": 0.00, "txkB": 0.00, "rxcmp": 0.00, "txcmp": 0.00, "rxmcst": 0.00},
                                {"iface": "eth2", "rxpck": 0.00, "txpck": 0.00, "rxkB": 0.00, "txkB": 0.00, "rxcmp": 0.00, "txcmp": 0.00, "rxmcst": 0.00},
                                {"iface": "lo", "rxpck": 7.95, "txpck": 7.95, "rxkB": 16.02, "txkB": 16.02, "rxcmp": 0.00, "txcmp": 0.00, "rxmcst": 0.00}
                            ]
                        }
                    }
                ],
                "restarts": [
                ]
            }
        ]
    }}
    


参考

以下、記事作成時に参考にしました。

以上です。

コメント