Skip to content

Instantly share code, notes, and snippets.

@tebeka
Created February 15, 2024 13:40
Show Gist options
  • Save tebeka/31a8f8d453bae98674b245c1e57276e0 to your computer and use it in GitHub Desktop.
Save tebeka/31a8f8d453bae98674b245c1e57276e0 to your computer and use it in GitHub Desktop.
Monitoring number of open files on Linux in Go
package main
import (
"expvar"
"fmt"
"log/slog"
"net/http"
"os"
"time"
"golang.org/x/sys/unix"
)
func openFiles() (int, error) {
entries, err := os.ReadDir("/proc/self/fd")
if err != nil {
return 0, err
}
return len(entries), nil
}
func maxFiles() (int, error) {
var limit unix.Rlimit
if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &limit); err != nil {
return 0, err
}
return int(limit.Max), nil
}
var (
nFiles = expvar.NewInt("files.count")
mFiles = expvar.NewInt("files.max")
)
func fileWatcher() {
t := time.NewTicker(time.Second)
for {
n, err := openFiles()
if err != nil {
slog.Error("open files", "error", err)
continue
}
nFiles.Set(int64(n))
<-t.C
}
}
func main() {
mf, err := maxFiles()
if err != nil {
fmt.Fprintf(os.Stderr, "error: can't get max limit %s", err)
os.Exit(1)
}
mFiles.Set(int64(mf))
go fileWatcher()
mux := http.NewServeMux()
mux.Handle("/debug/vars", expvar.Handler())
srv := http.Server{
Addr: ":8080",
Handler: mux,
}
slog.Info("server starting", "address", srv.Addr)
if err := srv.ListenAndServe(); err != nil {
fmt.Fprintf(os.Stderr, "error: %s", err)
os.Exit(1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment