Andrey Smirnov 88f2422955
refactor: get rid of prometheus/procfs dependency in pkg/resources
This PR introduces the concept of the resource adapter: something which
wraps core resource (which defines presentation) and adds additional
fatures to it which we don't want to have in `pkg/machinery` in the
future, but at the same time there's value in keeping it next to the
resource itself.

If the concept looks good, I will continue doing it same way for other
resources.

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
2021-10-29 18:37:10 +03:00

112 lines
2.5 KiB
Go

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package perf
import (
"context"
"time"
"github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/prometheus/procfs"
"go.uber.org/zap"
perfadapter "github.com/talos-systems/talos/internal/app/machined/pkg/adapters/perf"
"github.com/talos-systems/talos/pkg/resources/perf"
)
const updateInterval = time.Second * 30
// StatsController manages v1alpha1.Stats which is the current snaphot of the machine CPU and Memory consumption.
type StatsController struct{}
// Name implements controller.StatsController interface.
func (ctrl *StatsController) Name() string {
return "perf.StatsController"
}
// Inputs implements controller.StatsController interface.
func (ctrl *StatsController) Inputs() []controller.Input {
return nil
}
// Outputs implements controller.StatsController interface.
func (ctrl *StatsController) Outputs() []controller.Output {
return []controller.Output{
{
Type: perf.CPUType,
Kind: controller.OutputExclusive,
},
{
Type: perf.MemoryType,
Kind: controller.OutputExclusive,
},
}
}
// Run implements controller.StatsController interface.
func (ctrl *StatsController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
ticker := time.NewTicker(updateInterval)
defer ticker.Stop()
var (
fs procfs.FS
err error
)
fs, err = procfs.NewDefaultFS()
if err != nil {
return err
}
for {
select {
case <-r.EventCh():
case <-ctx.Done():
return nil
case <-ticker.C:
}
if err := ctrl.updateMemory(ctx, r, &fs); err != nil {
return err
}
if err := ctrl.updateCPU(ctx, r, &fs); err != nil {
return err
}
}
}
func (ctrl *StatsController) updateCPU(ctx context.Context, r controller.Runtime, fs *procfs.FS) error {
cpu := perf.NewCPU()
stat, err := fs.Stat()
if err != nil {
return err
}
return r.Modify(ctx, cpu, func(r resource.Resource) error {
perfadapter.CPU(r.(*perf.CPU)).Update(&stat)
return nil
})
}
func (ctrl *StatsController) updateMemory(ctx context.Context, r controller.Runtime, fs *procfs.FS) error {
mem := perf.NewMemory()
info, err := fs.Meminfo()
if err != nil {
return err
}
return r.Modify(ctx, mem, func(r resource.Resource) error {
perfadapter.Memory(r.(*perf.Memory)).Update(&info)
return nil
})
}