'Golang retrieve application uptime
I'm trying to retrieve the current uptime of my Go application.
I've seen there's a package syscall which provides a type Sysinfo_t and a method Sysinfo(*Sysinfo_t) which apparently allows you to retrieve the Uptime (since it's a field of the Sysinfo_t struct)
What I've done so far is:
sysi := &syscall.Sysinfo_t{}
if err := syscall.Sysinfo(sysi); err != nil {
return http.StatusInternalServerError, nil
}
The problem is that at compile time I get this:
/path/to/file/res_system.go:43: undefined: syscall.Sysinfo_t
/path/to/file/res_system.go:45: undefined: syscall.Sysinfo
I've searched a bit and apparently that method and type are available only on Linux and I need the application to run both on Linux and OsX (which I'm currently using).
Is there a cross-compatible way to retrieve the application uptime?
NOTE: I'd rather not use any third party libraries (unless they're absolutely necessary)
Solution 1:[1]
Simple way to get uptime is to store service start time:
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())
}
Solution 2:[2]
You should use Since function from time package.
create time value when application start:
startTime := time.Now()
then ask whenever you want:
uptime := time.Since(startTime)
Solution 3:[3]
Package syscall was frozen on 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.
Use Sysinfo from golang.org/x/sys it should support this in a cross-platform way, at least on Unix.
Solution 4:[4]
Difficulties
import "syscall" has been starved on most of its functionality which has been extracted to platform specific code in import "golang.org/x/sys/unix" and import "golang.org/x/sys/windows".
macOS GOOS==Darwin sorts under unix. The code in unix and windows is platform-specific, ie. if windows is imported on unix, the result is
error while importing golang.org/x/sys/windows: build constraints exclude all Go files in …
This means the program has to have a portable layer defining a portable function name, and that function is implemented for each supported platform like _darwin.go _linux.go and _windows.go which has to be tested on the real operating system.
The alternative is to use a third-party package where portability is already implemented. What you do then is to browse to Go Package search and pick a well-written candidate.
Solution
I browsed to Go Package search for Sysinfo: https://pkg.go.dev/search?q=sysinfo
Top result is gosysinfo "github.com/elastic/go-sysinfo". This package is awkwardly written as can be seen by a hyphen in its name and a peculiar package structure. It works, and the code goes like:
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | fredmaggiowski |
| Solution 2 | Melih Mucuk |
| Solution 3 | toqueteos |
| Solution 4 | Harald Rudell |
