@@ -28,6 +28,7 @@ import (
2828 "github.com/elastic/beats/v7/libbeat/metric/system/cpu"
2929 "github.com/elastic/beats/v7/libbeat/metric/system/process"
3030 "github.com/elastic/beats/v7/libbeat/monitoring"
31+ "github.com/elastic/gosigar/cgroup"
3132)
3233
3334var (
@@ -65,10 +66,15 @@ func setupMetrics(name string) error {
6566}
6667
6768func setupPlatformSpecificMetrics () {
69+ switch runtime .GOOS {
70+ case "linux" :
71+ monitoring .NewFunc (beatMetrics , "cgroup" , reportBeatCgroups , monitoring .Report )
72+ case "windows" :
73+ setupWindowsHandlesMetrics ()
74+ }
75+
6876 if runtime .GOOS != "windows" {
6977 monitoring .NewFunc (systemMetrics , "load" , reportSystemLoadAverage , monitoring .Report )
70- } else {
71- setupWindowsHandlesMetrics ()
7278 }
7379
7480 setupLinuxBSDFDMetrics ()
@@ -254,3 +260,79 @@ func reportRuntime(_ monitoring.Mode, V monitoring.Visitor) {
254260
255261 monitoring .ReportInt (V , "goroutines" , int64 (runtime .NumGoroutine ()))
256262}
263+
264+ func reportBeatCgroups (_ monitoring.Mode , V monitoring.Visitor ) {
265+ V .OnRegistryStart ()
266+ defer V .OnRegistryFinished ()
267+
268+ pid , err := process .GetSelfPid ()
269+ if err != nil {
270+ logp .Err ("error getting PID for self process: %v" , err )
271+ return
272+ }
273+
274+ cgroups , err := cgroup .NewReader ("" , true )
275+ if err != nil {
276+ if err == cgroup .ErrCgroupsMissing {
277+ logp .Warn ("cgroup data collection disabled: %v" , err )
278+ } else {
279+ logp .Err ("cgroup data collection disabled: %v" , err )
280+ }
281+ return
282+ }
283+ selfStats , err := cgroups .GetStatsForProcess (pid )
284+ if err != nil {
285+ logp .Err ("error getting group status: %v" , err )
286+ return
287+ }
288+
289+ if cpu := selfStats .CPU ; cpu != nil {
290+ monitoring .ReportNamespace (V , "cpu" , func () {
291+ if cpu .ID != "" {
292+ monitoring .ReportString (V , "id" , cpu .ID )
293+ }
294+ monitoring .ReportNamespace (V , "cfs" , func () {
295+ monitoring .ReportNamespace (V , "period" , func () {
296+ monitoring .ReportInt (V , "us" , int64 (cpu .CFS .PeriodMicros ))
297+ })
298+ monitoring .ReportNamespace (V , "quota" , func () {
299+ monitoring .ReportInt (V , "us" , int64 (cpu .CFS .QuotaMicros ))
300+ })
301+ })
302+ monitoring .ReportNamespace (V , "stats" , func () {
303+ monitoring .ReportInt (V , "periods" , int64 (cpu .Stats .Periods ))
304+ monitoring .ReportNamespace (V , "throttled" , func () {
305+ monitoring .ReportInt (V , "periods" , int64 (cpu .Stats .ThrottledPeriods ))
306+ monitoring .ReportInt (V , "ns" , int64 (cpu .Stats .ThrottledTimeNanos ))
307+ })
308+ })
309+ })
310+ }
311+
312+ if cpuacct := selfStats .CPUAccounting ; cpuacct != nil {
313+ monitoring .ReportNamespace (V , "cpuacct" , func () {
314+ if cpuacct .ID != "" {
315+ monitoring .ReportString (V , "id" , cpuacct .ID )
316+ }
317+ monitoring .ReportNamespace (V , "total" , func () {
318+ monitoring .ReportInt (V , "ns" , int64 (cpuacct .TotalNanos ))
319+ })
320+ })
321+ }
322+
323+ if memory := selfStats .Memory ; memory != nil {
324+ monitoring .ReportNamespace (V , "memory" , func () {
325+ if memory .ID != "" {
326+ monitoring .ReportString (V , "id" , memory .ID )
327+ }
328+ monitoring .ReportNamespace (V , "mem" , func () {
329+ monitoring .ReportNamespace (V , "limit" , func () {
330+ monitoring .ReportInt (V , "bytes" , int64 (memory .Mem .Limit ))
331+ })
332+ monitoring .ReportNamespace (V , "usage" , func () {
333+ monitoring .ReportInt (V , "bytes" , int64 (memory .Mem .Usage ))
334+ })
335+ })
336+ })
337+ }
338+ }
0 commit comments