package collector import ( "context" "fmt" "log" "time" "gitea.d3m0k1d.ru/d3m0k1d/HellreigN/proto/proto" "google.golang.org/grpc/metadata" ) // ReportServices handles a unary service status update from an agent. // Agents send their current services list, which is stored in the collector. func (c *Collector) ReportServices(ctx context.Context, req *proto.ServicesUpdate) (*proto.ServicesUpdateResp, error) { md, ok := metadata.FromIncomingContext(ctx) if !ok { return nil, fmt.Errorf("no metadata in context") } whoamiVals := md["whoami"] if len(whoamiVals) == 0 { return nil, fmt.Errorf("whoami metadata missing") } agentName := whoamiVals[0] // Auto-register agent if not yet known (e.g. log stream not connected yet) c.ensureAgentRegistered(agentName) services := make([]Service, 0, len(req.Services)) for _, s := range req.Services { services = append(services, Service{s.Name, s.Status}) } if ok := c.tracker.UpdateServices(agentName, services); ok { log.Printf("Updated services for agent %s: %v", agentName, services) } else { log.Printf("Warning: received services update for unknown agent %s", agentName) } return &proto.ServicesUpdateResp{}, nil } // ReportSystemMetrics handles system metrics update from an agent. // Agents send their current system metrics (CPU, RAM, disk, network). func (c *Collector) ReportSystemMetrics(ctx context.Context, req *proto.SystemMetrics) (*proto.SystemMetricsResp, error) { md, ok := metadata.FromIncomingContext(ctx) if !ok { return nil, fmt.Errorf("no metadata in context") } whoamiVals := md["whoami"] if len(whoamiVals) == 0 { return nil, fmt.Errorf("whoami metadata missing") } agentName := whoamiVals[0] // Auto-register agent if not yet known (e.g. log stream not connected yet) c.ensureAgentRegistered(agentName) metrics := SystemMetrics{ CPUPercent: req.CpuPercent, MemoryPercent: req.MemoryPercent, DiskPercent: req.DiskPercent, NetworkRxBytes: req.NetworkRxBytes, NetworkTxBytes: req.NetworkTxBytes, } if ok := c.tracker.UpdateSystemMetrics(agentName, metrics); ok { log.Printf("Updated system metrics for agent %s: CPU=%.1f%%, RAM=%.1f%%, Disk=%.1f%%", agentName, metrics.CPUPercent, metrics.MemoryPercent, metrics.DiskPercent) } else { log.Printf("Warning: received system metrics for unknown agent %s", agentName) } return &proto.SystemMetricsResp{}, nil } // ensureAgentRegistered registers the agent in the tracker if it's not already there. // This handles the case where agents send metrics/services before connecting to the log stream. func (c *Collector) ensureAgentRegistered(agentName string) { if _, ok := c.tracker.GetAgent(agentName); !ok { agent := &Agent{ ID: agentName, Label: agentName, Services: make([]Service, 0), ConnectedAt: time.Now(), } c.tracker.Register(agent) log.Printf("Auto-registered agent via unary RPC: %s", agentName) } }