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 (#2187)

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 authored and ruflin committed Aug 10, 2016
1 parent e7211c5 commit 5ae6d88
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 5ae6d88

Please sign in to comment.