Skip to content

Commit

Permalink
Add option for configuring the location of the container's host files…
Browse files Browse the repository at this point in the history
…ystem

This allows the system module to read metrics related to the host machine rather than the container. When using the -system.hostfs flag, directories like /proc and /sys are assumed to be mounted relative to the path given in the value. Here's an example usage.

`docker run --volume=/:/hostfs:ro --net=host --name=metricbeat -d metricbeat -system.hostfs=/hostfs`

And here is a more restrictive example which does not mount all of the host's filesystems inside the container. system/filesystem will not be able to report metrics for the host's filesystem.

`docker run --volume=/proc:/hostfs/proc:ro --volume=/sys/fs/cgroup:/hostfs/sys/fs/cgroup --net=host --name=metricbeat -d metricbeat -system.hostfs=/hostfs`
  • Loading branch information
andrewkroh committed Aug 9, 2016
1 parent 61fd22f commit dce6786
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 2 deletions.
9 changes: 8 additions & 1 deletion metricbeat/module/system/process/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
package process

import (
"fmt"
"runtime"
"strconv"

"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/libbeat/logp"
"github.com/elastic/beats/metricbeat/mb"
"github.com/elastic/beats/metricbeat/module/system"

"github.com/elastic/gosigar/cgroup"
"github.com/pkg/errors"
Expand Down Expand Up @@ -54,7 +56,12 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
}

if runtime.GOOS == "linux" {
m.cgroup, err = cgroup.NewReader("", true)
systemModule, ok := base.Module().(*system.Module)
if !ok {
return nil, fmt.Errorf("unexpected module type")
}

m.cgroup, err = cgroup.NewReader(systemModule.HostFS, true)
if err != nil {
return nil, errors.Wrap(err, "error initializing cgroup reader")
}
Expand Down
35 changes: 34 additions & 1 deletion metricbeat/module/system/system.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,39 @@
package system

import "math"
import (
"flag"
"math"
"sync"

"github.com/elastic/beats/metricbeat/mb"
)

var (
HostFS = flag.String("system.hostfs", "", "mountpoint of the host's filesystem for use in monitoring a host from within a container")
)

var once sync.Once

func init() {
// Register the ModuleFactory function for the "system" module.
if err := mb.Registry.AddModule("system", NewModule); err != nil {
panic(err)
}
}

type Module struct {
mb.BaseModule
HostFS string // Mountpoint of the host's filesystem for use in monitoring inside a container.
}

func NewModule(base mb.BaseModule) (mb.Module, error) {
// This only needs to be configured once for all system modules.
once.Do(func() {
configureHostFS()
})

return &Module{BaseModule: base, HostFS: *HostFS}, nil
}

func Round(val float64, roundOn float64, places int) (newVal float64) {
var round float64
Expand Down
23 changes: 23 additions & 0 deletions metricbeat/module/system/system_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package system

import (
"os"
"path/filepath"

"github.com/elastic/gosigar"
)

func configureHostFS() {
dir := *HostFS
if dir == "" {
dir = "/"
}

// Set environment variables for gopsutil.
os.Setenv("HOST_PROC", filepath.Join(dir, "/proc"))
os.Setenv("HOST_SYS", filepath.Join(dir, "/sys"))
os.Setenv("HOST_ETC", filepath.Join(dir, "/etc"))

// Set proc location for gosigar.
gosigar.Procd = filepath.Join(dir, "/proc")
}
7 changes: 7 additions & 0 deletions metricbeat/module/system/system_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build !linux

package system

func configureHostFS() {
// Stub method for non-linux.
}

0 comments on commit dce6786

Please sign in to comment.