diff --git a/libbeat/cmd/instance/metrics.go b/libbeat/cmd/instance/metrics.go index bca0363a80f..af8998d42e9 100644 --- a/libbeat/cmd/instance/metrics.go +++ b/libbeat/cmd/instance/metrics.go @@ -23,6 +23,7 @@ import ( "fmt" "runtime" + "github.com/elastic/beats/libbeat/common" "github.com/elastic/beats/libbeat/logp" "github.com/elastic/beats/libbeat/metric/system/cpu" "github.com/elastic/beats/libbeat/metric/system/process" @@ -41,6 +42,7 @@ func init() { func setupMetrics(name string) error { monitoring.NewFunc(beatMetrics, "memstats", reportMemStats, monitoring.Report) monitoring.NewFunc(beatMetrics, "cpu", reportBeatCPU, monitoring.Report) + monitoring.NewFunc(beatMetrics, "fd", reportFDUsage, monitoring.Report) monitoring.NewFunc(systemMetrics, "cpu", reportSystemCPUUsage, monitoring.Report) if runtime.GOOS != "windows" { @@ -81,14 +83,9 @@ func reportMemStats(m monitoring.Mode, V monitoring.Visitor) { } func getRSSSize() (uint64, error) { - pid, err := process.GetSelfPid() + state, err := getBeatProcessState() if err != nil { - return 0, fmt.Errorf("error getting PID for self process: %v", err) - } - - state, err := beatProcessStats.GetOne(pid) - if err != nil { - return 0, fmt.Errorf("error retrieving process stats: %v", err) + return 0, err } iRss, err := state.GetValue("memory.rss.bytes") @@ -103,6 +100,20 @@ func getRSSSize() (uint64, error) { return rss, nil } +func getBeatProcessState() (common.MapStr, error) { + pid, err := process.GetSelfPid() + if err != nil { + return nil, fmt.Errorf("error getting PID for self process: %v", err) + } + + state, err := beatProcessStats.GetOne(pid) + if err != nil { + return nil, fmt.Errorf("error retrieving process stats: %v", err) + } + + return state, nil +} + func reportBeatCPU(_ monitoring.Mode, V monitoring.Visitor) { V.OnRegistryStart() defer V.OnRegistryFinished() @@ -141,14 +152,9 @@ func reportBeatCPU(_ monitoring.Mode, V monitoring.Visitor) { } func getCPUUsage() (float64, *process.Ticks, error) { - pid, err := process.GetSelfPid() + state, err := getBeatProcessState() if err != nil { - return 0.0, nil, fmt.Errorf("error getting PID for self process: %v", err) - } - - state, err := beatProcessStats.GetOne(pid) - if err != nil { - return 0.0, nil, fmt.Errorf("error retrieving process stats: %v", err) + return 0.0, nil, err } iTotalCPUUsage, err := state.GetValue("cpu.total.value") @@ -200,6 +206,64 @@ func getCPUUsage() (float64, *process.Ticks, error) { return totalCPUUsage, &p, nil } +func reportFDUsage(_ monitoring.Mode, V monitoring.Visitor) { + V.OnRegistryStart() + defer V.OnRegistryFinished() + + open, hardLimit, softLimit, err := getFDUsage() + if err != nil { + logp.Err("Error while retrieving FD information: %v", err) + return + } + + monitoring.ReportInt(V, "open", int64(open)) + monitoring.ReportNamespace(V, "limit", func() { + monitoring.ReportInt(V, "hard", int64(hardLimit)) + monitoring.ReportInt(V, "soft", int64(softLimit)) + }) +} + +func getFDUsage() (open, hardLimit, softLimit uint64, err error) { + state, err := getBeatProcessState() + if err != nil { + // TODO copy + logp.Err("baj van") + return 0, 0, 0, err + } + + iOpen, err := state.GetValue("fd.open") + if err != nil { + return 0, 0, 0, fmt.Errorf("error getting number of open FD: %v", err) + } + + open, ok := iOpen.(uint64) + if !ok { + return 0, 0, 0, fmt.Errorf("error converting value of open FDs to uint64: %v", iOpen) + } + + iHardLimit, err := state.GetValue("fd.limit.hard") + if err != nil { + return 0, 0, 0, fmt.Errorf("error getting FD hard limit: %v", err) + } + + hardLimit, ok = iHardLimit.(uint64) + if !ok { + return 0, 0, 0, fmt.Errorf("error converting values of FD hard limit: %v", iHardLimit) + } + + iSoftLimit, err := state.GetValue("fd.limit.soft") + if err != nil { + return 0, 0, 0, fmt.Errorf("error getting FD hard limit: %v", err) + } + + softLimit, ok = iSoftLimit.(uint64) + if !ok { + return 0, 0, 0, fmt.Errorf("error converting values of FD hard limit: %v", iSoftLimit) + } + + return open, hardLimit, softLimit, nil +} + func reportSystemLoadAverage(_ monitoring.Mode, V monitoring.Visitor) { V.OnRegistryStart() defer V.OnRegistryFinished() diff --git a/libbeat/monitoring/report/log/log.go b/libbeat/monitoring/report/log/log.go index 8a196ab3394..1254f4a16bc 100644 --- a/libbeat/monitoring/report/log/log.go +++ b/libbeat/monitoring/report/log/log.go @@ -52,6 +52,9 @@ var gauges = map[string]bool{ "beat.cpu.total.value": true, "beat.cpu.total.ticks": true, "beat.cpu.total.time": true, + "beat.fd.open": true, + "beat.fd.limit.hard": true, + "beat.fd.limit.soft": true, "system.load.1": true, "system.load.5": true, "system.load.15": true,