简体   繁体   English

如何在 Golang 中获取 Memory 指标、磁盘指标和 CPU 指标?

[英]How to get Memory metric, Disk metric and CPU metric in Golang?

I am new to go, I am trying to get 3 functions to return them as follows我是 go 的新手,我正在尝试获取 3 个函数来返回它们,如下所示

  1. function 1 - To return memory usage of the system function 1 - 返回 memory 系统使用情况
  2. function 2 - To return disk usage of the system function 2 - 返回系统的磁盘使用情况
  3. function 3 - To return CPU usage of the system function 3 - 返回系统的 CPU 使用率

So far I am able to do this much only (PS: trying not to use any libs)到目前为止,我只能做这么多(PS:尽量不使用任何库)

func getCPUTrack() (idle, total uint64) {
    contents, err := ioutil.ReadFile("/proc/stat")
    if err != nil {
        return
    }
    lines := strings.Split(string(contents), "\n")
    for _, line := range lines {
        fields := strings.Fields(line)
        if fields[0] == "cpu" {
            numFields := len(fields)
            for i := 1; i < numFields; i++ {
                val, err := strconv.ParseUint(fields[i], 10, 64)
                if err != nil {
                    fmt.Println("Error: ", i, fields[i], err)
                }
                total += val // tally up all the numbers to get total ticks
                if i == 4 {  // idle is the 5th field in the cpu line
                    idle = val
                }
            }
            return
        }
    }
    return
}

idle0, total0 := getCPUTrack()
    time.Sleep(3 * time.Second)
    idle1, total1 := getCPUTrack()

    idleTicks := float64(idle1 - idle0)
    totalTicks := float64(total1 - total0)
    cpuUsage := 100 * (totalTicks - idleTicks) / totalTicks

    fmt.Printf("CPU usage is %f%% [busy: %f, total: %f]\n", cpuUsage, totalTicks-idleTicks, totalTicks)

Can anyone help me with this?谁能帮我这个? Thanks谢谢

There is a pretty cool library you can use Go-osstat , or see in detail how it is implemented so you can build your own.有一个非常酷的库,您可以使用Go-osstat ,或者详细了解它是如何实现的,以便您可以构建自己的库。

I've developed a client that uses this library and runs in the background sending Memory and CPU usage metrics我开发了一个使用这个库并在后台运行的客户端,发送 Memory 和 CPU 使用率指标

package main

import (
    "fmt"
    "os"
    "time"

    "github.com/mackerelio/go-osstat/cpu"
    "github.com/mackerelio/go-osstat/memory"
)

const (
    memoryMetric = "memory"
    cpuMetric    = "cpu"
    retries      = 10
)

type client struct {
    packageName     string
    memoryIteration int
    cpuIteration    int
    OSClient        OSClient
}

type Client interface {
    EmitMetrics()
}

type osClient struct{}

type OSClient interface {
    GetMemory() (*memory.Stats, error)
    GetCPU() (*cpu.Stats, error)
}

func (osc osClient) GetMemory() (*memory.Stats, error) { return memory.Get() }

func (osc osClient) GetCPU() (*cpu.Stats, error) { return cpu.Get() }

func NewClient(packageName string, memoryIteration, cpuIteration int) Client {
    return newClient(packageName, memoryIteration, cpuIteration, osClient{})
}

func newClient(packageName string, memoryIteration, cpuIteration int, osclient OSClient) Client {
    return &client{
        packageName:     packageName,
        memoryIteration: memoryIteration,
        cpuIteration:    cpuIteration,
        OSClient:        osclient,
    }
}

func (c *client) EmitMetrics() {
    protectFromPanic := func(metric string) {
        if r := recover(); r != nil {
            fmt.Printf(fmt.Sprintf("Recover from fail sending %s metrics for %s", metric, c.packageName), zap.Any("recover", r))
        }
    }
    c.sendMemoryMetrics(protectFromPanic)
    c.sendCPUMetrics(protectFromPanic)
}

func (c *client) sendMemoryMetrics(f func(string)) {
    count := 0
    go func() {
        defer func() {
            f(memoryMetric)
        }()
        for {
            memory, err := c.OSClient.GetMemory()
            if err != nil {
                fmt.Fprintf(os.Stderr, "%s\n", err)
                count++
                if count == retries {
                    return
                }
            } else {
                count = 0
                EmitMemoryMetrics(c.packageName, memory.Total, memory.Used, memory.Cached, memory.Free)
                time.Sleep(time.Duration(c.memoryIteration) * time.Millisecond)
            }
        }
    }()
}

func (c *client) sendCPUMetrics(f func(string)) {
    go func() {
        defer func() {
            f(cpuMetric)
        }()
        for {
            before, err := c.OSClient.GetCPU()
            if err != nil {
                fmt.Fprintf(os.Stderr, "%s\n", err)

                return
            }
            time.Sleep(time.Duration(c.cpuIteration) * time.Millisecond)
            after, err := c.OSClient.GetCPU()
            if err != nil {
                fmt.Fprintf(os.Stderr, "%s\n", err)

                return
            }
            total := float64(after.Total - before.Total)
            EmitCPUMetrics(c.packageName,
                total,
                float64(after.User-before.User)/total*100,
                float64(after.System-before.System)/total*100,
                float64(after.Idle-before.Idle)/total*100)
        }
    }()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM