Golang 检索应用程序正常运行时间

Golang retrieve application uptime

我正在尝试检索我的 Go 应用程序的当前正常运行时间。

我看到有一个包 syscall which provides a type Sysinfo_t and a method Sysinfo(*Sysinfo_t) 显然允许您检索正常运行时间(因为它是 Sysinfo_t 结构的一个字段)

到目前为止我所做的是:

sysi := &syscall.Sysinfo_t{}

if err := syscall.Sysinfo(sysi); err != nil {
    return http.StatusInternalServerError, nil
}

问题是在编译时我得到这个:

/path/to/file/res_system.go:43: undefined: syscall.Sysinfo_t
/path/to/file/res_system.go:45: undefined: syscall.Sysinfo

我搜索了一下,显然该方法和类型仅在 Linux 上可用,我需要在 Linux 和 OsX 上申请 运行 (我目前正在使用)。

是否有交叉兼容的方法来检索应用程序正常运行时间?

注意:我宁愿不使用任何第三方库(除非它们是绝对必要的)

syscall 在 Go 1.4 上被冻结。

NOTE: This package is locked down. Code outside the standard Go repository should be migrated to use the corresponding package in the golang.org/x/sys repository. That is also where updates required by new systems or versions should be applied. See https://golang.org/s/go1.4-syscall for more information.

使用 golang.org/x/sys 中的 Sysinfo 它应该以跨平台的方式支持它,至少在 Unix 上是这样。

您应该使用 time 包中的 Since 函数。

应用程序启动时创建时间值:

startTime := time.Now()

然后随时询问:

uptime := time.Since(startTime)

获取正常运行时间的简单方法是存储服务开始时间:

https://play.golang.org/p/by_nkvhzqD

package main

import (
    "fmt"
    "time"
)

var startTime time.Time

func uptime() time.Duration {
    return time.Since(startTime)
}

func init() {
    startTime = time.Now()
}

func main() {
    fmt.Println("started")

    time.Sleep(time.Second * 1)
    fmt.Printf("uptime %s\n", uptime())

    time.Sleep(time.Second * 5)
    fmt.Printf("uptime %s\n", uptime())
}

困难

import "syscall" 的大部分功能已被提取到 import "golang.org/x/sys/unix"import "golang.org/x/sys/windows".

中的平台特定代码中

macOS GOOS==Darwin 在unix 下排序。 unix 和 windows 中的代码是 platform-specific,即。如果在 unix 上导入 windows,结果是

error while importing golang.org/x/sys/windows: build constraints exclude all Go files in …

这意味着程序必须有一个定义可移植函数名称的可移植层,并且该函数是为每个支持的平台实现的,例如 _darwin.go _linux.go 和 _windows.go 必须在真实操作系统上进行测试。

另一种方法是使用已实现可移植性的 third-party 包。然后你要做的是浏览到 Go Package search 并选择一个 well-written 候选人。

解决方案

我浏览到 Go Package 搜索 Sysinfo:https://pkg.go.dev/search?q=sysinfo

排名靠前的结果是 gosysinfo "github.com/elastic/go-sysinfo"。从名称中的连字符和奇特的包结构可以看出,这个包的写法很笨拙。它有效,代码如下:

import (
  gosysinfo "github.com/elastic/go-sysinfo"
  "github.com/elastic/go-sysinfo/types"
  "github.com/haraldrudell/parl"
)

func goSysinfo() {
  var process types.Process
  var err error
  if process, err = gosysinfo.Self(); err != nil {
    panic(parl.Errorf("go-sysinfo.Self: %w", err))
  }
  var processInfo types.ProcessInfo
  if processInfo, err = process.Info(); err != nil {
    panic(parl.Errorf("go-sysinfo.Info: %w", err))
  }
  startTime := processInfo.StartTime
  fmt.Printf("Process start time: %s\n", startTime.Format(parl.Rfc3339s))
}
→
Process start time: 2022-03-22 10:15:05-07:00