chore: add system metrics

This commit is contained in:
d3m0k1d
2026-04-05 05:37:19 +03:00
parent 54e8102a51
commit c2e8037560
13 changed files with 812 additions and 47 deletions
+214
View File
@@ -0,0 +1,214 @@
package metrics
import (
"bufio"
"os"
"strconv"
"strings"
"syscall"
"time"
)
// SystemMetrics holds current system resource usage.
type SystemMetrics struct {
CPUPercent float64
MemoryPercent float64
DiskPercent float64
NetworkRxBytes float64
NetworkTxBytes float64
}
// Collector collects system metrics from /proc and sysfs.
type Collector struct {
lastCPUTotal uint64
lastCPUIdle uint64
lastNetRx float64
lastNetTx float64
lastNetTime time.Time
}
// NewCollector creates a new metrics collector.
func NewCollector() *Collector {
return &Collector{}
}
// Collect gathers current system metrics.
func (c *Collector) Collect() (SystemMetrics, error) {
var m SystemMetrics
cpu, err := c.readCPU()
if err == nil {
m.CPUPercent = cpu
}
mem, err := c.readMemory()
if err == nil {
m.MemoryPercent = mem
}
disk, err := c.readDisk("/")
if err == nil {
m.DiskPercent = disk
}
netRx, netTx, err := c.readNetwork()
if err == nil {
m.NetworkRxBytes = netRx
m.NetworkTxBytes = netTx
}
return m, nil
}
// readCPU returns CPU usage percentage since last call.
func (c *Collector) readCPU() (float64, error) {
f, err := os.Open("/proc/stat")
if err != nil {
return 0, err
}
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
if !strings.HasPrefix(line, "cpu ") {
continue
}
fields := strings.Fields(line)
if len(fields) < 8 {
return 0, nil
}
var user, nice, system, idle, iowait, irq, softirq uint64
user, _ = strconv.ParseUint(fields[1], 10, 64)
nice, _ = strconv.ParseUint(fields[2], 10, 64)
system, _ = strconv.ParseUint(fields[3], 10, 64)
idle, _ = strconv.ParseUint(fields[4], 10, 64)
iowait, _ = strconv.ParseUint(fields[5], 10, 64)
irq, _ = strconv.ParseUint(fields[6], 10, 64)
softirq, _ = strconv.ParseUint(fields[7], 10, 64)
total := user + nice + system + idle + iowait + irq + softirq
idleTotal := idle + iowait
if c.lastCPUTotal > 0 {
totalDiff := total - c.lastCPUTotal
idleDiff := idleTotal - c.lastCPUIdle
if totalDiff > 0 {
cpuPercent := float64(totalDiff-idleDiff) / float64(totalDiff) * 100.0
c.lastCPUTotal = total
c.lastCPUIdle = idleTotal
return cpuPercent, nil
}
}
c.lastCPUTotal = total
c.lastCPUIdle = idleTotal
return 0, nil
}
return 0, scanner.Err()
}
// readMemory returns RAM usage percentage.
func (c *Collector) readMemory() (float64, error) {
f, err := os.Open("/proc/meminfo")
if err != nil {
return 0, err
}
defer f.Close()
var total, available uint64
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, "MemTotal:") {
fields := strings.Fields(line)
total, _ = strconv.ParseUint(fields[1], 10, 64)
} else if strings.HasPrefix(line, "MemAvailable:") {
fields := strings.Fields(line)
available, _ = strconv.ParseUint(fields[1], 10, 64)
}
}
if total == 0 {
return 0, nil
}
used := total - available
return float64(used) / float64(total) * 100.0, nil
}
// readDisk returns disk usage percentage for the given path.
func (c *Collector) readDisk(path string) (float64, error) {
var stat syscall.Statfs_t
if err := syscall.Statfs(path, &stat); err != nil {
return 0, err
}
total := stat.Blocks * uint64(stat.Bsize)
free := stat.Bfree * uint64(stat.Bsize)
if total == 0 {
return 0, nil
}
used := total - free
return float64(used) / float64(total) * 100.0, nil
}
// readNetwork returns network RX/TX bytes per second.
func (c *Collector) readNetwork() (float64, float64, error) {
f, err := os.Open("/proc/net/dev")
if err != nil {
return 0, 0, err
}
defer f.Close()
var totalRx, totalTx uint64
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
// Skip header lines
if strings.Contains(line, "|") || strings.HasPrefix(strings.TrimSpace(line), "Inter") {
continue
}
parts := strings.SplitN(strings.TrimSpace(line), ":", 2)
if len(parts) < 2 {
continue
}
fields := strings.Fields(parts[1])
if len(fields) < 9 {
continue
}
rx, _ := strconv.ParseUint(fields[0], 10, 64)
tx, _ := strconv.ParseUint(fields[8], 10, 64)
totalRx += rx
totalTx += tx
}
now := time.Now()
var rxRate, txRate float64
if !c.lastNetTime.IsZero() {
elapsed := now.Sub(c.lastNetTime).Seconds()
if elapsed > 0 {
rxRate = float64(totalRx) - c.lastNetRx
txRate = float64(totalTx) - c.lastNetTx
// Convert to bytes per second
rxRate = rxRate / elapsed
txRate = txRate / elapsed
}
}
c.lastNetRx = float64(totalRx)
c.lastNetTx = float64(totalTx)
c.lastNetTime = now
return rxRate, txRate, nil
}
+62
View File
@@ -12,6 +12,7 @@ import (
"gitea.d3m0k1d.ru/d3m0k1d/HellreigN/agent/internal/client"
"gitea.d3m0k1d.ru/d3m0k1d/HellreigN/agent/internal/commander"
"gitea.d3m0k1d.ru/d3m0k1d/HellreigN/agent/internal/config"
agentmetrics "gitea.d3m0k1d.ru/d3m0k1d/HellreigN/agent/internal/metrics"
"gitea.d3m0k1d.ru/d3m0k1d/HellreigN/agent/internal/logger"
"gitea.d3m0k1d.ru/d3m0k1d/HellreigN/agent/internal/logsource"
"gitea.d3m0k1d.ru/d3m0k1d/HellreigN/agent/internal/logsource/docker"
@@ -120,6 +121,11 @@ func main() {
})
}
// Start system metrics reporting
wg.Go(func() error {
return reportSystemMetrics(ctx, grpcAddr, creds, cfg.Label, lgr)
})
// Start log collectors
if len(cfg.Services) > 0 {
wg.Go(func() error {
@@ -370,3 +376,59 @@ func reportServices(
}
}
}
// reportSystemMetrics periodically collects and sends system metrics to the backend via gRPC.
func reportSystemMetrics(
ctx context.Context,
grpcAddr string,
creds credentials.TransportCredentials,
label string,
lgr *logger.Logger,
) error {
conn, err := grpc.NewClient(grpcAddr, grpc.WithTransportCredentials(creds))
if err != nil {
return fmt.Errorf("failed to connect for metrics report: %w", err)
}
defer conn.Close()
ccli := proto.NewCollectorClient(conn)
collector := agentmetrics.NewCollector()
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
lgr.Info("System metrics collector started")
for {
metrics, err := collector.Collect()
if err != nil {
lgr.Warn("Failed to collect system metrics", "err", err)
} else {
md := metadata.New(map[string]string{"whoami": label})
_, err := ccli.ReportSystemMetrics(
metadata.NewOutgoingContext(ctx, md),
&proto.SystemMetrics{
CpuPercent: metrics.CPUPercent,
MemoryPercent: metrics.MemoryPercent,
DiskPercent: metrics.DiskPercent,
NetworkRxBytes: metrics.NetworkRxBytes,
NetworkTxBytes: metrics.NetworkTxBytes,
},
)
if err != nil {
lgr.Warn("Failed to report system metrics", "err", err)
} else {
lgr.Debug("System metrics reported",
"cpu", metrics.CPUPercent,
"mem", metrics.MemoryPercent,
"disk", metrics.DiskPercent,
)
}
}
select {
case <-ctx.Done():
return ctx.Err()
case <-ticker.C:
}
}
}
+1
View File
@@ -200,6 +200,7 @@ func main() {
agentsGroup.Use(auth.AuthMiddleware(), handlers.RequireManageAgent())
{
agentsGroup.GET("", agents.List)
agentsGroup.GET("/system-metrics", agents.GetSystemMetrics)
}
// Jobs (requires admin permission)
+68
View File
@@ -177,6 +177,37 @@ const docTemplate = `{
}
}
},
"/agents/system-metrics": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Returns CPU, RAM, disk, and network usage metrics for all connected agents",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"agents"
],
"summary": "Get agent system metrics",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/internal_handlers.AgentSystemMetricsOut"
}
}
}
}
}
},
"/auth/login": {
"post": {
"description": "Authenticate with login and password, returns a token and permissions",
@@ -2706,6 +2737,43 @@ const docTemplate = `{
}
}
},
"internal_handlers.AgentSystemMetricsOut": {
"type": "object",
"properties": {
"connected_at": {
"type": "string",
"example": "2026-04-04 10:30:00"
},
"cpu_percent": {
"type": "number",
"example": 45.2
},
"disk_percent": {
"type": "number",
"example": 78.9
},
"id": {
"type": "string",
"example": "agent-001"
},
"label": {
"type": "string",
"example": "web-server-1"
},
"memory_percent": {
"type": "number",
"example": 62.5
},
"network_rx_bytes": {
"type": "number",
"example": 1048576
},
"network_tx_bytes": {
"type": "number",
"example": 524288
}
}
},
"internal_handlers.CheckCmdIn": {
"type": "object",
"required": [
+68
View File
@@ -166,6 +166,37 @@
}
}
},
"/agents/system-metrics": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Returns CPU, RAM, disk, and network usage metrics for all connected agents",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"agents"
],
"summary": "Get agent system metrics",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/internal_handlers.AgentSystemMetricsOut"
}
}
}
}
}
},
"/auth/login": {
"post": {
"description": "Authenticate with login and password, returns a token and permissions",
@@ -2695,6 +2726,43 @@
}
}
},
"internal_handlers.AgentSystemMetricsOut": {
"type": "object",
"properties": {
"connected_at": {
"type": "string",
"example": "2026-04-04 10:30:00"
},
"cpu_percent": {
"type": "number",
"example": 45.2
},
"disk_percent": {
"type": "number",
"example": 78.9
},
"id": {
"type": "string",
"example": "agent-001"
},
"label": {
"type": "string",
"example": "web-server-1"
},
"memory_percent": {
"type": "number",
"example": 62.5
},
"network_rx_bytes": {
"type": "number",
"example": 1048576
},
"network_tx_bytes": {
"type": "number",
"example": 524288
}
}
},
"internal_handlers.CheckCmdIn": {
"type": "object",
"required": [
+47
View File
@@ -374,6 +374,33 @@ definitions:
example: agent-001
type: string
type: object
internal_handlers.AgentSystemMetricsOut:
properties:
connected_at:
example: "2026-04-04 10:30:00"
type: string
cpu_percent:
example: 45.2
type: number
disk_percent:
example: 78.9
type: number
id:
example: agent-001
type: string
label:
example: web-server-1
type: string
memory_percent:
example: 62.5
type: number
network_rx_bytes:
example: 1048576
type: number
network_tx_bytes:
example: 524288
type: number
type: object
internal_handlers.CheckCmdIn:
properties:
command:
@@ -619,6 +646,26 @@ paths:
summary: Create registration token
tags:
- agents
/agents/system-metrics:
get:
consumes:
- application/json
description: Returns CPU, RAM, disk, and network usage metrics for all connected
agents
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/internal_handlers.AgentSystemMetricsOut'
type: array
security:
- Bearer: []
summary: Get agent system metrics
tags:
- agents
/auth/login:
post:
consumes:
@@ -157,3 +157,8 @@ func (c *Collector) GetAgent(name string) (*Agent, bool) {
func (c *Collector) Agents() []*Agent {
return c.tracker.Agents()
}
// GetSystemMetrics delegates to the tracker.
func (c *Collector) GetSystemMetrics() map[string]AgentMetricsInfo {
return c.tracker.GetSystemMetrics()
}
@@ -36,3 +36,35 @@ func (c *Collector) ReportServices(ctx context.Context, req *proto.ServicesUpdat
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]
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
}
@@ -97,15 +97,69 @@ func (t *ConnTracker) UpdateServices(id string, services []Service) bool {
return true
}
// UpdateSystemMetrics updates the system metrics for the given agent.
func (t *ConnTracker) UpdateSystemMetrics(id string, metrics SystemMetrics) bool {
t.mu.Lock()
defer t.mu.Unlock()
agent, ok := t.agents[id]
if !ok {
return false
}
agent.SystemMetrics = metrics
return true
}
// GetSystemMetrics returns system metrics for all connected agents.
func (t *ConnTracker) GetSystemMetrics() map[string]AgentMetricsInfo {
t.mu.RLock()
defer t.mu.RUnlock()
result := make(map[string]AgentMetricsInfo)
for id, agent := range t.agents {
result[id] = AgentMetricsInfo{
ID: id,
Label: agent.Label,
ConnectedAt: agent.ConnectedAt,
CPUPercent: agent.SystemMetrics.CPUPercent,
MemoryPercent: agent.SystemMetrics.MemoryPercent,
DiskPercent: agent.SystemMetrics.DiskPercent,
NetworkRxBytes: agent.SystemMetrics.NetworkRxBytes,
NetworkTxBytes: agent.SystemMetrics.NetworkTxBytes,
}
}
return result
}
// Service represents a named service with its current status.
type Service struct {
Name, Status string
}
// SystemMetrics represents system resource metrics.
type SystemMetrics struct {
CPUPercent float64
MemoryPercent float64
DiskPercent float64
NetworkRxBytes float64
NetworkTxBytes float64
}
// AgentMetricsInfo contains agent info with its system metrics.
type AgentMetricsInfo struct {
ID string `json:"id"`
Label string `json:"label"`
ConnectedAt time.Time `json:"connected_at"`
CPUPercent float64 `json:"cpu_percent"`
MemoryPercent float64 `json:"memory_percent"`
DiskPercent float64 `json:"disk_percent"`
NetworkRxBytes float64 `json:"network_rx_bytes"`
NetworkTxBytes float64 `json:"network_tx_bytes"`
}
// Agent represents a connected agent streaming logs to the collector.
type Agent struct {
ID string
Label string
Services []Service
SystemMetrics SystemMetrics
ConnectedAt time.Time
}
+41
View File
@@ -51,3 +51,44 @@ func (ag *AgentsGroup) List(c *gin.Context) {
c.JSON(http.StatusOK, agents)
}
// AgentSystemMetricsOut represents system metrics for a single agent.
type AgentSystemMetricsOut struct {
ID string `json:"id" example:"agent-001"`
Label string `json:"label" example:"web-server-1"`
ConnectedAt string `json:"connected_at" example:"2026-04-04 10:30:00"`
CPUPercent float64 `json:"cpu_percent" example:"45.2"`
MemoryPercent float64 `json:"memory_percent" example:"62.5"`
DiskPercent float64 `json:"disk_percent" example:"78.9"`
NetworkRxBytes float64 `json:"network_rx_bytes" example:"1048576.0"`
NetworkTxBytes float64 `json:"network_tx_bytes" example:"524288.0"`
}
// GetSystemMetrics returns system load metrics for all connected agents.
// @Summary Get agent system metrics
// @Description Returns CPU, RAM, disk, and network usage metrics for all connected agents
// @Tags agents
// @Security Bearer
// @Accept json
// @Produce json
// @Success 200 {array} AgentSystemMetricsOut
// @Router /agents/system-metrics [get]
func (ag *AgentsGroup) GetSystemMetrics(c *gin.Context) {
metricsMap := ag.collector.GetSystemMetrics()
metrics := make([]AgentSystemMetricsOut, 0, len(metricsMap))
for _, m := range metricsMap {
metrics = append(metrics, AgentSystemMetricsOut{
ID: m.ID,
Label: m.Label,
ConnectedAt: m.ConnectedAt.Format("2006-01-02 15:04:05"),
CPUPercent: m.CPUPercent,
MemoryPercent: m.MemoryPercent,
DiskPercent: m.DiskPercent,
NetworkRxBytes: m.NetworkRxBytes,
NetworkTxBytes: m.NetworkTxBytes,
})
}
c.JSON(http.StatusOK, metrics)
}
+10
View File
@@ -7,9 +7,19 @@ option go_package="gitea.d3m0k1d.ru/d3m0k1d/HellreigN/proto/proto";
service Collector {
rpc Stream(stream CollectorRequest) returns (CollectorResponse);
rpc ReportServices(ServicesUpdate) returns (ServicesUpdateResp);
rpc ReportSystemMetrics(SystemMetrics) returns (SystemMetricsResp);
}
message ServicesUpdateResp {
}
message SystemMetricsResp {
}
message SystemMetrics {
double cpu_percent = 1; // CPU usage percentage (0-100)
double memory_percent = 2; // RAM usage percentage (0-100)
double disk_percent = 3; // Disk usage percentage (0-100)
double network_rx_bytes = 4; // Network received bytes per second
double network_tx_bytes = 5; // Network transmitted bytes per second
}
message ServicesUpdate {
message ServiceUpdate {
string name = 1;
+165 -40
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.11
// protoc v3.21.9
// protoc v7.34.1
// source: hellreign.proto
package proto
@@ -57,6 +57,118 @@ func (*ServicesUpdateResp) Descriptor() ([]byte, []int) {
return file_hellreign_proto_rawDescGZIP(), []int{0}
}
type SystemMetricsResp struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SystemMetricsResp) Reset() {
*x = SystemMetricsResp{}
mi := &file_hellreign_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SystemMetricsResp) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SystemMetricsResp) ProtoMessage() {}
func (x *SystemMetricsResp) ProtoReflect() protoreflect.Message {
mi := &file_hellreign_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SystemMetricsResp.ProtoReflect.Descriptor instead.
func (*SystemMetricsResp) Descriptor() ([]byte, []int) {
return file_hellreign_proto_rawDescGZIP(), []int{1}
}
type SystemMetrics struct {
state protoimpl.MessageState `protogen:"open.v1"`
CpuPercent float64 `protobuf:"fixed64,1,opt,name=cpu_percent,json=cpuPercent,proto3" json:"cpu_percent,omitempty"` // CPU usage percentage (0-100)
MemoryPercent float64 `protobuf:"fixed64,2,opt,name=memory_percent,json=memoryPercent,proto3" json:"memory_percent,omitempty"` // RAM usage percentage (0-100)
DiskPercent float64 `protobuf:"fixed64,3,opt,name=disk_percent,json=diskPercent,proto3" json:"disk_percent,omitempty"` // Disk usage percentage (0-100)
NetworkRxBytes float64 `protobuf:"fixed64,4,opt,name=network_rx_bytes,json=networkRxBytes,proto3" json:"network_rx_bytes,omitempty"` // Network received bytes per second
NetworkTxBytes float64 `protobuf:"fixed64,5,opt,name=network_tx_bytes,json=networkTxBytes,proto3" json:"network_tx_bytes,omitempty"` // Network transmitted bytes per second
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SystemMetrics) Reset() {
*x = SystemMetrics{}
mi := &file_hellreign_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SystemMetrics) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SystemMetrics) ProtoMessage() {}
func (x *SystemMetrics) ProtoReflect() protoreflect.Message {
mi := &file_hellreign_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SystemMetrics.ProtoReflect.Descriptor instead.
func (*SystemMetrics) Descriptor() ([]byte, []int) {
return file_hellreign_proto_rawDescGZIP(), []int{2}
}
func (x *SystemMetrics) GetCpuPercent() float64 {
if x != nil {
return x.CpuPercent
}
return 0
}
func (x *SystemMetrics) GetMemoryPercent() float64 {
if x != nil {
return x.MemoryPercent
}
return 0
}
func (x *SystemMetrics) GetDiskPercent() float64 {
if x != nil {
return x.DiskPercent
}
return 0
}
func (x *SystemMetrics) GetNetworkRxBytes() float64 {
if x != nil {
return x.NetworkRxBytes
}
return 0
}
func (x *SystemMetrics) GetNetworkTxBytes() float64 {
if x != nil {
return x.NetworkTxBytes
}
return 0
}
type ServicesUpdate struct {
state protoimpl.MessageState `protogen:"open.v1"`
Services []*ServicesUpdate_ServiceUpdate `protobuf:"bytes,1,rep,name=services,proto3" json:"services,omitempty"`
@@ -66,7 +178,7 @@ type ServicesUpdate struct {
func (x *ServicesUpdate) Reset() {
*x = ServicesUpdate{}
mi := &file_hellreign_proto_msgTypes[1]
mi := &file_hellreign_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -78,7 +190,7 @@ func (x *ServicesUpdate) String() string {
func (*ServicesUpdate) ProtoMessage() {}
func (x *ServicesUpdate) ProtoReflect() protoreflect.Message {
mi := &file_hellreign_proto_msgTypes[1]
mi := &file_hellreign_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -91,7 +203,7 @@ func (x *ServicesUpdate) ProtoReflect() protoreflect.Message {
// Deprecated: Use ServicesUpdate.ProtoReflect.Descriptor instead.
func (*ServicesUpdate) Descriptor() ([]byte, []int) {
return file_hellreign_proto_rawDescGZIP(), []int{1}
return file_hellreign_proto_rawDescGZIP(), []int{3}
}
func (x *ServicesUpdate) GetServices() []*ServicesUpdate_ServiceUpdate {
@@ -110,7 +222,7 @@ type CollectorRequest struct {
func (x *CollectorRequest) Reset() {
*x = CollectorRequest{}
mi := &file_hellreign_proto_msgTypes[2]
mi := &file_hellreign_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -122,7 +234,7 @@ func (x *CollectorRequest) String() string {
func (*CollectorRequest) ProtoMessage() {}
func (x *CollectorRequest) ProtoReflect() protoreflect.Message {
mi := &file_hellreign_proto_msgTypes[2]
mi := &file_hellreign_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -135,7 +247,7 @@ func (x *CollectorRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use CollectorRequest.ProtoReflect.Descriptor instead.
func (*CollectorRequest) Descriptor() ([]byte, []int) {
return file_hellreign_proto_rawDescGZIP(), []int{2}
return file_hellreign_proto_rawDescGZIP(), []int{4}
}
func (x *CollectorRequest) GetMessage() string {
@@ -153,7 +265,7 @@ type CollectorResponse struct {
func (x *CollectorResponse) Reset() {
*x = CollectorResponse{}
mi := &file_hellreign_proto_msgTypes[3]
mi := &file_hellreign_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -165,7 +277,7 @@ func (x *CollectorResponse) String() string {
func (*CollectorResponse) ProtoMessage() {}
func (x *CollectorResponse) ProtoReflect() protoreflect.Message {
mi := &file_hellreign_proto_msgTypes[3]
mi := &file_hellreign_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -178,7 +290,7 @@ func (x *CollectorResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use CollectorResponse.ProtoReflect.Descriptor instead.
func (*CollectorResponse) Descriptor() ([]byte, []int) {
return file_hellreign_proto_rawDescGZIP(), []int{3}
return file_hellreign_proto_rawDescGZIP(), []int{5}
}
type Command struct {
@@ -192,7 +304,7 @@ type Command struct {
func (x *Command) Reset() {
*x = Command{}
mi := &file_hellreign_proto_msgTypes[4]
mi := &file_hellreign_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -204,7 +316,7 @@ func (x *Command) String() string {
func (*Command) ProtoMessage() {}
func (x *Command) ProtoReflect() protoreflect.Message {
mi := &file_hellreign_proto_msgTypes[4]
mi := &file_hellreign_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -217,7 +329,7 @@ func (x *Command) ProtoReflect() protoreflect.Message {
// Deprecated: Use Command.ProtoReflect.Descriptor instead.
func (*Command) Descriptor() ([]byte, []int) {
return file_hellreign_proto_rawDescGZIP(), []int{4}
return file_hellreign_proto_rawDescGZIP(), []int{6}
}
func (x *Command) GetId() int64 {
@@ -253,7 +365,7 @@ type FinishedCommand struct {
func (x *FinishedCommand) Reset() {
*x = FinishedCommand{}
mi := &file_hellreign_proto_msgTypes[5]
mi := &file_hellreign_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -265,7 +377,7 @@ func (x *FinishedCommand) String() string {
func (*FinishedCommand) ProtoMessage() {}
func (x *FinishedCommand) ProtoReflect() protoreflect.Message {
mi := &file_hellreign_proto_msgTypes[5]
mi := &file_hellreign_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -278,7 +390,7 @@ func (x *FinishedCommand) ProtoReflect() protoreflect.Message {
// Deprecated: Use FinishedCommand.ProtoReflect.Descriptor instead.
func (*FinishedCommand) Descriptor() ([]byte, []int) {
return file_hellreign_proto_rawDescGZIP(), []int{5}
return file_hellreign_proto_rawDescGZIP(), []int{7}
}
func (x *FinishedCommand) GetId() int64 {
@@ -319,7 +431,7 @@ type ServicesUpdate_ServiceUpdate struct {
func (x *ServicesUpdate_ServiceUpdate) Reset() {
*x = ServicesUpdate_ServiceUpdate{}
mi := &file_hellreign_proto_msgTypes[6]
mi := &file_hellreign_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -331,7 +443,7 @@ func (x *ServicesUpdate_ServiceUpdate) String() string {
func (*ServicesUpdate_ServiceUpdate) ProtoMessage() {}
func (x *ServicesUpdate_ServiceUpdate) ProtoReflect() protoreflect.Message {
mi := &file_hellreign_proto_msgTypes[6]
mi := &file_hellreign_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -344,7 +456,7 @@ func (x *ServicesUpdate_ServiceUpdate) ProtoReflect() protoreflect.Message {
// Deprecated: Use ServicesUpdate_ServiceUpdate.ProtoReflect.Descriptor instead.
func (*ServicesUpdate_ServiceUpdate) Descriptor() ([]byte, []int) {
return file_hellreign_proto_rawDescGZIP(), []int{1, 0}
return file_hellreign_proto_rawDescGZIP(), []int{3, 0}
}
func (x *ServicesUpdate_ServiceUpdate) GetName() string {
@@ -366,7 +478,15 @@ var File_hellreign_proto protoreflect.FileDescriptor
const file_hellreign_proto_rawDesc = "" +
"\n" +
"\x0fhellreign.proto\x12\x04chat\"\x14\n" +
"\x12ServicesUpdateResp\"\x8d\x01\n" +
"\x12ServicesUpdateResp\"\x13\n" +
"\x11SystemMetricsResp\"\xce\x01\n" +
"\rSystemMetrics\x12\x1f\n" +
"\vcpu_percent\x18\x01 \x01(\x01R\n" +
"cpuPercent\x12%\n" +
"\x0ememory_percent\x18\x02 \x01(\x01R\rmemoryPercent\x12!\n" +
"\fdisk_percent\x18\x03 \x01(\x01R\vdiskPercent\x12(\n" +
"\x10network_rx_bytes\x18\x04 \x01(\x01R\x0enetworkRxBytes\x12(\n" +
"\x10network_tx_bytes\x18\x05 \x01(\x01R\x0enetworkTxBytes\"\x8d\x01\n" +
"\x0eServicesUpdate\x12>\n" +
"\bservices\x18\x01 \x03(\v2\".chat.ServicesUpdate.ServiceUpdateR\bservices\x1a;\n" +
"\rServiceUpdate\x12\x12\n" +
@@ -384,10 +504,11 @@ const file_hellreign_proto_rawDesc = "" +
"\x02id\x18\x01 \x01(\x03R\x02id\x12\x16\n" +
"\x06status\x18\x02 \x01(\x05R\x06status\x12\x16\n" +
"\x06stdout\x18\x03 \x01(\tR\x06stdout\x12\x16\n" +
"\x06stderr\x18\x04 \x01(\tR\x06stderr2\x8a\x01\n" +
"\x06stderr\x18\x04 \x01(\tR\x06stderr2\xcf\x01\n" +
"\tCollector\x12;\n" +
"\x06Stream\x12\x16.chat.CollectorRequest\x1a\x17.chat.CollectorResponse(\x01\x12@\n" +
"\x0eReportServices\x12\x14.chat.ServicesUpdate\x1a\x18.chat.ServicesUpdateResp2?\n" +
"\x0eReportServices\x12\x14.chat.ServicesUpdate\x1a\x18.chat.ServicesUpdateResp\x12C\n" +
"\x13ReportSystemMetrics\x12\x13.chat.SystemMetrics\x1a\x17.chat.SystemMetricsResp2?\n" +
"\tCommander\x122\n" +
"\x06Stream\x12\x15.chat.FinishedCommand\x1a\r.chat.Command(\x010\x01B0Z.gitea.d3m0k1d.ru/d3m0k1d/HellreigN/proto/protob\x06proto3"
@@ -403,26 +524,30 @@ func file_hellreign_proto_rawDescGZIP() []byte {
return file_hellreign_proto_rawDescData
}
var file_hellreign_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_hellreign_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_hellreign_proto_goTypes = []any{
(*ServicesUpdateResp)(nil), // 0: chat.ServicesUpdateResp
(*ServicesUpdate)(nil), // 1: chat.ServicesUpdate
(*CollectorRequest)(nil), // 2: chat.CollectorRequest
(*CollectorResponse)(nil), // 3: chat.CollectorResponse
(*Command)(nil), // 4: chat.Command
(*FinishedCommand)(nil), // 5: chat.FinishedCommand
(*ServicesUpdate_ServiceUpdate)(nil), // 6: chat.ServicesUpdate.ServiceUpdate
(*SystemMetricsResp)(nil), // 1: chat.SystemMetricsResp
(*SystemMetrics)(nil), // 2: chat.SystemMetrics
(*ServicesUpdate)(nil), // 3: chat.ServicesUpdate
(*CollectorRequest)(nil), // 4: chat.CollectorRequest
(*CollectorResponse)(nil), // 5: chat.CollectorResponse
(*Command)(nil), // 6: chat.Command
(*FinishedCommand)(nil), // 7: chat.FinishedCommand
(*ServicesUpdate_ServiceUpdate)(nil), // 8: chat.ServicesUpdate.ServiceUpdate
}
var file_hellreign_proto_depIdxs = []int32{
6, // 0: chat.ServicesUpdate.services:type_name -> chat.ServicesUpdate.ServiceUpdate
2, // 1: chat.Collector.Stream:input_type -> chat.CollectorRequest
1, // 2: chat.Collector.ReportServices:input_type -> chat.ServicesUpdate
5, // 3: chat.Commander.Stream:input_type -> chat.FinishedCommand
3, // 4: chat.Collector.Stream:output_type -> chat.CollectorResponse
0, // 5: chat.Collector.ReportServices:output_type -> chat.ServicesUpdateResp
4, // 6: chat.Commander.Stream:output_type -> chat.Command
4, // [4:7] is the sub-list for method output_type
1, // [1:4] is the sub-list for method input_type
8, // 0: chat.ServicesUpdate.services:type_name -> chat.ServicesUpdate.ServiceUpdate
4, // 1: chat.Collector.Stream:input_type -> chat.CollectorRequest
3, // 2: chat.Collector.ReportServices:input_type -> chat.ServicesUpdate
2, // 3: chat.Collector.ReportSystemMetrics:input_type -> chat.SystemMetrics
7, // 4: chat.Commander.Stream:input_type -> chat.FinishedCommand
5, // 5: chat.Collector.Stream:output_type -> chat.CollectorResponse
0, // 6: chat.Collector.ReportServices:output_type -> chat.ServicesUpdateResp
1, // 7: chat.Collector.ReportSystemMetrics:output_type -> chat.SystemMetricsResp
6, // 8: chat.Commander.Stream:output_type -> chat.Command
5, // [5:9] is the sub-list for method output_type
1, // [1:5] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
@@ -433,14 +558,14 @@ func file_hellreign_proto_init() {
if File_hellreign_proto != nil {
return
}
file_hellreign_proto_msgTypes[4].OneofWrappers = []any{}
file_hellreign_proto_msgTypes[6].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_hellreign_proto_rawDesc), len(file_hellreign_proto_rawDesc)),
NumEnums: 0,
NumMessages: 7,
NumMessages: 9,
NumExtensions: 0,
NumServices: 2,
},
+39 -1
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.6.1
// - protoc v3.21.9
// - protoc v7.34.1
// source: hellreign.proto
package proto
@@ -21,6 +21,7 @@ const _ = grpc.SupportPackageIsVersion9
const (
Collector_Stream_FullMethodName = "/chat.Collector/Stream"
Collector_ReportServices_FullMethodName = "/chat.Collector/ReportServices"
Collector_ReportSystemMetrics_FullMethodName = "/chat.Collector/ReportSystemMetrics"
)
// CollectorClient is the client API for Collector service.
@@ -29,6 +30,7 @@ const (
type CollectorClient interface {
Stream(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[CollectorRequest, CollectorResponse], error)
ReportServices(ctx context.Context, in *ServicesUpdate, opts ...grpc.CallOption) (*ServicesUpdateResp, error)
ReportSystemMetrics(ctx context.Context, in *SystemMetrics, opts ...grpc.CallOption) (*SystemMetricsResp, error)
}
type collectorClient struct {
@@ -62,12 +64,23 @@ func (c *collectorClient) ReportServices(ctx context.Context, in *ServicesUpdate
return out, nil
}
func (c *collectorClient) ReportSystemMetrics(ctx context.Context, in *SystemMetrics, opts ...grpc.CallOption) (*SystemMetricsResp, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(SystemMetricsResp)
err := c.cc.Invoke(ctx, Collector_ReportSystemMetrics_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// CollectorServer is the server API for Collector service.
// All implementations must embed UnimplementedCollectorServer
// for forward compatibility.
type CollectorServer interface {
Stream(grpc.ClientStreamingServer[CollectorRequest, CollectorResponse]) error
ReportServices(context.Context, *ServicesUpdate) (*ServicesUpdateResp, error)
ReportSystemMetrics(context.Context, *SystemMetrics) (*SystemMetricsResp, error)
mustEmbedUnimplementedCollectorServer()
}
@@ -84,6 +97,9 @@ func (UnimplementedCollectorServer) Stream(grpc.ClientStreamingServer[CollectorR
func (UnimplementedCollectorServer) ReportServices(context.Context, *ServicesUpdate) (*ServicesUpdateResp, error) {
return nil, status.Error(codes.Unimplemented, "method ReportServices not implemented")
}
func (UnimplementedCollectorServer) ReportSystemMetrics(context.Context, *SystemMetrics) (*SystemMetricsResp, error) {
return nil, status.Error(codes.Unimplemented, "method ReportSystemMetrics not implemented")
}
func (UnimplementedCollectorServer) mustEmbedUnimplementedCollectorServer() {}
func (UnimplementedCollectorServer) testEmbeddedByValue() {}
@@ -130,6 +146,24 @@ func _Collector_ReportServices_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _Collector_ReportSystemMetrics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SystemMetrics)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(CollectorServer).ReportSystemMetrics(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Collector_ReportSystemMetrics_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(CollectorServer).ReportSystemMetrics(ctx, req.(*SystemMetrics))
}
return interceptor(ctx, in, info, handler)
}
// Collector_ServiceDesc is the grpc.ServiceDesc for Collector service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -141,6 +175,10 @@ var Collector_ServiceDesc = grpc.ServiceDesc{
MethodName: "ReportServices",
Handler: _Collector_ReportServices_Handler,
},
{
MethodName: "ReportSystemMetrics",
Handler: _Collector_ReportSystemMetrics_Handler,
},
},
Streams: []grpc.StreamDesc{
{