ホームページ > バックエンド開発 > Golang > golangでプロセス監視を実装する方法

golangでプロセス監視を実装する方法

PHPz
リリース: 2023-04-24 10:05:32
オリジナル
1948 人が閲覧しました

開発、運用および保守では、プロセスが正常に実行できること、および問題が発生したときに適時に検出して対処できることを確認するために、プロセスを監視する必要があることがよくあります。この記事では、Go 言語を使用してプロセス監視を実装する方法を紹介し、監視テクノロジーをより深く理解し、適用できるようにします。

1. プロセス監視の基本原理

プロセス監視とは、主にアプリケーションの実行状態を監視、制御、例外処理するための技術を指します。平たく言えば、特定の監視方法を使用して、プログラムの実行ステータスをリアルタイムで監視しながら、プログラムが正常に実行され、エラーがタイムリーに処理されることを確認することです。

プロセス監視で最も一般的に使用される監視方法はハートビート メカニズムです。いわゆるハートビート メカニズムは、プログラムの実行中に、通常の動作ステータスを示すメッセージを外部に継続的に送信します。そして、これらのメッセージをキャプチャして解析することで、プログラムが正常であるかどうかを判断します。プログラムの異常が発見されると、システムの正常な動作を確保するために適切に処理されます。

2. golang でのプロセス監視の実装アイデア

Go 言語では、既製のパッケージを使用してプロセス監視を実装できます。

1. すべてのプロセス情報の取得

psutil パッケージの process パッケージを使用して、システム内のすべてのプロセスに関する関連情報を取得できます。まず、パッケージを導入する必要があります:

import (
    "github.com/shirou/gopsutil/process"
)
ログイン後にコピー

次に、process.Processes() 関数を呼び出して、システム内のすべてのプロセスを取得します:

processes, err := process.Processes()
if err != nil {
    log.Fatalf("failed to get all processes: %v", err)
}
ログイン後にコピー

この関数は、プロセス スライスを返します。各要素はプロセス情報を含む構造体です。特定の構造については、psutil の公式ドキュメントを参照してください。

2. 監視する必要があるプロセスをフィルタリングする

特定のプロセスを監視するには、すべてのプロセスの中から関心のあるプロセスを見つけて、その PID を記録する必要があります。ここでは、いくつかの条件付きフィルターを使用して、監視する必要があるプロセスをすばやく除外できます。たとえば、プロセス名、プロセス ID、その他の条件に基づいて必要なプロセスをフィルタリングできます。プロセス名を例にとると、コードは次のようになります:

targetProcessName := "myApp"
targetPidList := make([]int32, 0)

for _, proc := range processes {
    name, err := proc.Name()
    if err != nil || name != targetProcessName {
        continue
    }
    pid := proc.Pid
    targetPidList = append(targetPidList, pid)
    log.Printf("find target process %s, pid = %d\n", name, pid)
}
ログイン後にコピー

3. 監視が必要なプロセスに対してハートビート検出を実行します

監視が必要なプロセスに対して、プロセスにハートビート メッセージを送信することで、プロセスが正常に実行されているかどうかを判断できます。具体的には、CPU やメモリの使用状況を読み取ることで判断できます。 CPU やメモリの使用率が異常な場合は、プロセスに問題があると考えられます。

ハートビート検出を実装するには、ゴルーチンを使用して、指定したプロセスのステータスを定期的に読み取り、記録します。具体的な実装コードは次のとおりです。

type ProcessState struct {
    CpuPercent    float64
    MemResident   uint64
    MemVirtual    uint64
    MemSwap       uint64
}

func checkProcessState(targetPid int32, stateChan chan<- ProcessState) {
    ticker := time.NewTicker(5 * time.Second)
    for {
        select {
        case <-ticker.C:
            proc, err := process.NewProcess(targetPid)
            if err != nil {
                log.Printf("failed to get process %d: %v", targetPid, err)
                continue
            }
            cpuPercent, err := proc.CPUPercent()
            if err != nil {
                log.Printf("failed to get cpu percent for process %d: %v", targetPid, err)
                continue
            }
            memInfo, err := proc.MemoryInfo()
            if err != nil {
                log.Printf("failed to get memory info for process %d: %v", targetPid, err)
                continue
            }
            state := ProcessState{
                CpuPercent:  cpuPercent,
                MemResident: memInfo.RSS,
                MemVirtual:  memInfo.VMS,
                MemSwap:     memInfo.Swap,
            }
            stateChan <- state
        }
    }
}
ログイン後にコピー

上記のコードでは、まずティッカー タイマーを使用して、指定されたプロセスのステータスを 5 秒ごとにチェックします。検出プロセスでは、process.NewProcess() 関数を通じて指定された pid のプロセス ハンドルを取得し、提供されている関数を使用して CPU 使用率とメモリ使用率を取得します。この情報を上で定義した構造体に格納し、stateChan を通じて外部に送信します。

3. 完全な golang プロセス監視コード例

上記の実装アイデアとコードに基づいて、完全な golang プロセス監視コード例を作成できます。完全なコードは次のとおりです。

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/process"
    "log"
    "time"
)

type ProcessState struct {
    CpuPercent    float64
    MemResident   uint64
    MemVirtual    uint64
    MemSwap       uint64
}

func main() {
    targetProcessName := "myApp"
    targetPidList := make([]int32, 0)
    processes, err := process.Processes()
    if err != nil {
        log.Fatalf("failed to get all processes: %v", err)
    }
    for _, proc := range processes {
        name, err := proc.Name()
        if err != nil || name != targetProcessName {
            continue
        }
        pid := proc.Pid
        targetPidList = append(targetPidList, pid)
        log.Printf("find target process %s, pid = %d\n", name, pid)
    }
    stateChan := make(chan ProcessState)
    for _, pid := range targetPidList {
        go checkProcessState(pid, stateChan)
    }
    for {
        select {
        case state := <-stateChan:
            if state.CpuPercent > 100.0 || state.MemSwap > 0 || state.MemVirtual > 2*state.MemResident {
                log.Printf("process is not healthy: %+v\n", state)
            } else {
                log.Printf("process is healthy: %+v\n", state)
            }
        }
    }
}

func checkProcessState(targetPid int32, stateChan chan<- ProcessState) {
    ticker := time.NewTicker(5 * time.Second)
    for {
        select {
        case <-ticker.C:
            proc, err := process.NewProcess(targetPid)
            if err != nil {
                log.Printf("failed to get process %d: %v", targetPid, err)
                continue
            }
            cpuPercent, err := proc.CPUPercent()
            if err != nil {
                log.Printf("failed to get cpu percent for process %d: %v", targetPid, err)
                continue
            }
            memInfo, err := proc.MemoryInfo()
            if err != nil {
                log.Printf("failed to get memory info for process %d: %v", targetPid, err)
                continue
            }
            state := ProcessState{
                CpuPercent:  cpuPercent,
                MemResident: memInfo.RSS,
                MemVirtual:  memInfo.VMS,
                MemSwap:     memInfo.Swap,
            }
            stateChan <- state
        }
    }
}
ログイン後にコピー

この例では、まず監視する必要があるプロセスを見つけ、各プロセスの goroutine を開始してそのステータスを定期的に検出します。プログラムは chan からの goroutine からのステータスメッセージを継続的に受信し、そのステータスに基づいてプログラムが正常に実行されているかどうかを判断します。プロセスの異常が見つかった場合は、対応するプロンプトがログを通じて提供されます。

4. 概要

この記事では、主に psutil パッケージで提供される API を呼び出し、定期的な検出に goroutine を使用することにより、Go 言語を使用してプロセス監視を実装する方法を紹介します。プロセス監視により、アプリケーションの実行状況をより適切に管理し、プログラム内で例外が発生した場合にタイムリーに対処することができ、システム開発や運用保守をより効果的に行うことができます。

以上がgolangでプロセス監視を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート