mirror of
				https://github.com/siderolabs/talos.git
				synced 2025-11-04 10:21:13 +01:00 
			
		
		
		
	Now the latest value for CPU and Memory is also represented as COSI resources. Was going back and forth in the implementation but in the end decided to use dedicated yaml structures for both CPU and Memory stats because: - JSON tags are ignored by `go-yaml`, so the output is not really great. - protobuf Talos definition contains fields which we don't really need in the YAML output of `talosctl get`. - current state of Talos resource service does not support protobuf encoding for resources. So the plan for Theila is to just use the structure as a dynamic object without relying on protobufs. At least for now. Signed-off-by: Artem Chernyshev <artem.0xD2@gmail.com>
		
			
				
	
	
		
			111 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			2.3 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"
 | 
						|
 | 
						|
	"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 {
 | 
						|
		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 {
 | 
						|
		r.(*perf.Memory).Update(&info)
 | 
						|
 | 
						|
		return nil
 | 
						|
	})
 | 
						|
}
 |