golangの日記

Go言語を中心にプログラミングについてのブログ

Go言語(golang) time.Tickerを使ってメモリの使用率を表示

golang.png


time.Ticker は一定周期で処理を行う場合に便利で、以下は Ubuntu のメモリ使用率を取得して表示するサンプルです。





使い方は time.NewTicker の引数に間隔を time.Duration で指定し、time.Ticker.C で待ちます。 time.Ticker.C には現在時刻と m=+3.001192550 のように初回実行からの経過の合計の送られてくる。 最後に time.Stop でタイマーを止めて終了。


package main

import (
    "bufio"
    "fmt"
    "os"
    "time"
)

// Linuxのメモリ情報があるファイル
const MemPath = "/proc/meminfo"

func p(u, t float64) float64 {
    return u / t * 100
}

func readMem() (float64, float64, error) {
    fp, err := os.Open(MemPath)
    if err != nil {
        return 0, 0, err
    }
    defer fp.Close()

    h := ""
    n := 0
    a := [4]int{-1, -1, -1, -1}
    s := bufio.NewScanner(fp)

    for s.Scan() {
        fmt.Sscanf(s.Text(), "%s%d", &h, &n)
        switch h {
        case "MemTotal:":
            a[0] = n
        case "MemFree:":
            a[1] = n
        case "SwapTotal:":
            a[2] = n
        case "SwapFree:":
            a[3] = n
        }

        if a[0] != -1 && a[1] != -1 && a[2] != -1 && a[3] != -1 {
            break
        }
    }

    if err := s.Err(); err != nil {
        return 0, 0, err
    }

    phys := p(float64(a[0]-a[1]), float64(a[0]))
    swap := p(float64(a[2]-a[3]), float64(a[2]))
    return phys, swap, nil
}

func ticker() error {
    // 1秒間隔
    t := time.NewTicker(1 * time.Second)

    // タイマーを止める終了処理
    defer t.Stop()

    for {
        select {
        case v := <-t.C: // 一秒ごとに t.C (チャンネル) に現在時刻が送られてくる
  
            phys, swap, err := readMem()
            if err != nil {
                return err
            }

            format := "%v\nUsed: %7.3f%%, Swap: %7.3f%%\n"
            fmt.Fprintf(os.Stdout, format, v, phys, swap)
        }
    }
}

func main() {
    if err := ticker(); err != nil {
        fmt.Fprintf(os.Stderr, "Error: %s\n", err)
    }
}