diff --git a/linux/runtime.go b/linux/runtime.go index 625bda7c0..01da876eb 100644 --- a/linux/runtime.go +++ b/linux/runtime.go @@ -56,7 +56,7 @@ func New(ic *plugin.InitContext) (interface{}, error) { cfg.Runtime = defaultRuntime } c, cancel := context.WithCancel(ic.Context) - return &Runtime{ + r := &Runtime{ root: path, remote: !cfg.NoShim, runtime: cfg.Runtime, @@ -64,7 +64,10 @@ func New(ic *plugin.InitContext) (interface{}, error) { eventsContext: c, eventsCancel: cancel, monitor: ic.Monitor, - }, nil + } + // set the events output for a monitor if it generates events + ic.Monitor.Events(r.events) + return r, nil } type Runtime struct { diff --git a/metrics/cgroups/cgroups.go b/metrics/cgroups/cgroups.go index 32e28ad07..f020123f8 100644 --- a/metrics/cgroups/cgroups.go +++ b/metrics/cgroups/cgroups.go @@ -1,6 +1,8 @@ package cgroups import ( + "time" + "github.com/containerd/containerd" "github.com/containerd/containerd/plugin" "github.com/crosbymichael/cgroups" @@ -39,6 +41,7 @@ type cgroupsMonitor struct { collector *prometheus.Collector oom *prometheus.OOMCollector context context.Context + events chan<- *containerd.Event } func (m *cgroupsMonitor) Monitor(c containerd.Container) error { @@ -58,7 +61,7 @@ func (m *cgroupsMonitor) Monitor(c containerd.Container) error { if err := m.collector.Add(id, cg); err != nil { return err } - return m.oom.Add(id, cg) + return m.oom.Add(id, cg, m.trigger) } func (m *cgroupsMonitor) Stop(c containerd.Container) error { @@ -68,3 +71,15 @@ func (m *cgroupsMonitor) Stop(c containerd.Container) error { m.collector.Remove(c.Info().ID) return nil } + +func (m *cgroupsMonitor) Events(events chan<- *containerd.Event) { + m.events = events +} + +func (m *cgroupsMonitor) trigger(id string, cg cgroups.Cgroup) { + m.events <- &containerd.Event{ + Timestamp: time.Now(), + Type: containerd.OOMEvent, + ID: id, + } +} diff --git a/plugin/monitor.go b/plugin/monitor.go index a5f55d51d..7e05fb87c 100644 --- a/plugin/monitor.go +++ b/plugin/monitor.go @@ -8,6 +8,8 @@ type ContainerMonitor interface { Monitor(containerd.Container) error // Stop stops and removes the provided container from the monitor Stop(containerd.Container) error + // Events emits events from the monitor + Events(chan<- *containerd.Event) } func NewMultiContainerMonitor(monitors ...ContainerMonitor) ContainerMonitor { @@ -31,6 +33,9 @@ func (mm *noopContainerMonitor) Stop(c containerd.Container) error { return nil } +func (mm *noopContainerMonitor) Events(events chan<- *containerd.Event) { +} + type multiContainerMonitor struct { monitors []ContainerMonitor } @@ -52,3 +57,9 @@ func (mm *multiContainerMonitor) Stop(c containerd.Container) error { } return nil } + +func (mm *multiContainerMonitor) Events(events chan<- *containerd.Event) { + for _, m := range mm.monitors { + m.Events(events) + } +}