-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
273 additions
and
370 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,86 +1,66 @@ | ||
package server | ||
|
||
import ( | ||
"errors" | ||
"context" | ||
"github.com/apex/log" | ||
"github.com/crawlab-team/crawlab/core/models/models" | ||
"github.com/crawlab-team/crawlab/core/models/service" | ||
"github.com/crawlab-team/crawlab/grpc" | ||
"io" | ||
"go.mongodb.org/mongo-driver/bson" | ||
"sync" | ||
"time" | ||
) | ||
|
||
type MetricsServerV2 struct { | ||
grpc.UnimplementedMetricsServiceV2Server | ||
mu *sync.Mutex | ||
streams map[string]*grpc.MetricsServiceV2_ConnectServer | ||
channels map[string]chan []*grpc.Metric | ||
} | ||
|
||
func (svr MetricsServerV2) Connect(stream grpc.MetricsServiceV2_ConnectServer) (err error) { | ||
// receive first message | ||
req, err := stream.Recv() | ||
func (svr MetricsServerV2) Send(_ context.Context, req *grpc.MetricsServiceV2SendRequest) (res *grpc.Response, err error) { | ||
log.Info("[MetricsServerV2] received metric from node: " + req.NodeKey) | ||
n, err := service.NewModelServiceV2[models.NodeV2]().GetOne(bson.M{"key": req.NodeKey}, nil) | ||
if err != nil { | ||
log.Errorf("[MetricsServerV2] receive error: %v", err) | ||
return err | ||
log.Errorf("[MetricsServerV2] error getting node: %v", err) | ||
return HandleError(err) | ||
} | ||
|
||
// save stream and channel | ||
svr.mu.Lock() | ||
svr.streams[req.NodeKey] = &stream | ||
svr.channels[req.NodeKey] = make(chan []*grpc.Metric) | ||
svr.mu.Unlock() | ||
|
||
log.Info("[MetricsServerV2] connected: " + req.NodeKey) | ||
|
||
for { | ||
// receive metrics | ||
req, err = stream.Recv() | ||
if errors.Is(err, io.EOF) { | ||
log.Errorf("[MetricsServerV2] receive EOF: %v", err) | ||
return | ||
} | ||
|
||
// send metrics to channel | ||
svr.channels[req.NodeKey] <- req.Metrics | ||
|
||
// keep this scope alive because once this scope exits - the stream is closed | ||
select { | ||
case <-stream.Context().Done(): | ||
log.Info("[MetricsServerV2] disconnected: " + req.NodeKey) | ||
delete(svr.streams, req.NodeKey) | ||
delete(svr.channels, req.NodeKey) | ||
return nil | ||
} | ||
metric := models.MetricV2{ | ||
Type: req.Type, | ||
NodeId: n.Id, | ||
CpuUsagePercent: req.CpuUsagePercent, | ||
TotalMemory: req.TotalMemory, | ||
AvailableMemory: req.AvailableMemory, | ||
UsedMemory: req.UsedMemory, | ||
UsedMemoryPercent: req.UsedMemoryPercent, | ||
TotalDisk: req.TotalDisk, | ||
AvailableDisk: req.AvailableDisk, | ||
UsedDisk: req.UsedDisk, | ||
UsedDiskPercent: req.UsedDiskPercent, | ||
DiskReadBytesRate: req.DiskReadBytesRate, | ||
DiskWriteBytesRate: req.DiskWriteBytesRate, | ||
NetworkBytesSentRate: req.NetworkBytesSentRate, | ||
NetworkBytesRecvRate: req.NetworkBytesRecvRate, | ||
} | ||
metric.CreatedAt = time.Unix(req.Timestamp, 0) | ||
_, err = service.NewModelServiceV2[models.MetricV2]().InsertOne(metric) | ||
if err != nil { | ||
log.Errorf("[MetricsServerV2] error inserting metric: %v", err) | ||
return HandleError(err) | ||
} | ||
return HandleSuccess() | ||
} | ||
|
||
func (svr MetricsServerV2) GetStream(nodeKey string) (stream *grpc.MetricsServiceV2_ConnectServer, ok bool) { | ||
svr.mu.Lock() | ||
defer svr.mu.Unlock() | ||
stream, ok = svr.streams[nodeKey] | ||
return stream, ok | ||
} | ||
|
||
func (svr MetricsServerV2) GetChannel(nodeKey string) (ch chan []*grpc.Metric, ok bool) { | ||
svr.mu.Lock() | ||
defer svr.mu.Unlock() | ||
ch, ok = svr.channels[nodeKey] | ||
return ch, ok | ||
} | ||
|
||
func NewMetricsServerV2() *MetricsServerV2 { | ||
return &MetricsServerV2{ | ||
mu: new(sync.Mutex), | ||
streams: make(map[string]*grpc.MetricsServiceV2_ConnectServer), | ||
channels: make(map[string]chan []*grpc.Metric), | ||
} | ||
func newMetricsServerV2() *MetricsServerV2 { | ||
return &MetricsServerV2{} | ||
} | ||
|
||
var metricsServerV2 *MetricsServerV2 | ||
var metricsServerV2Once = &sync.Once{} | ||
|
||
func GetMetricsServerV2() *MetricsServerV2 { | ||
if metricsServerV2 != nil { | ||
return metricsServerV2 | ||
} | ||
metricsServerV2 = NewMetricsServerV2() | ||
metricsServerV2Once.Do(func() { | ||
metricsServerV2 = newMetricsServerV2() | ||
}) | ||
return metricsServerV2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package models | ||
|
||
import "go.mongodb.org/mongo-driver/bson/primitive" | ||
|
||
type MetricV2 struct { | ||
any `collection:"metrics"` | ||
BaseModelV2[MetricV2] `bson:",inline"` | ||
Type string `json:"type" bson:"type"` | ||
NodeId primitive.ObjectID `json:"node_id" bson:"node_id"` | ||
CpuUsagePercent float32 `json:"cpu_usage_percent" bson:"cpu_usage_percent"` | ||
TotalMemory uint64 `json:"total_memory" bson:"total_memory"` | ||
AvailableMemory uint64 `json:"available_memory" bson:"available_memory"` | ||
UsedMemory uint64 `json:"used_memory" bson:"used_memory"` | ||
UsedMemoryPercent float32 `json:"used_memory_percent" bson:"used_memory_percent"` | ||
TotalDisk uint64 `json:"total_disk" bson:"total_disk"` | ||
AvailableDisk uint64 `json:"available_disk" bson:"available_disk"` | ||
UsedDisk uint64 `json:"used_disk" bson:"used_disk"` | ||
UsedDiskPercent float32 `json:"used_disk_percent" bson:"used_disk_percent"` | ||
DiskReadBytesRate float32 `json:"disk_read_bytes_rate" bson:"disk_read_bytes_rate"` | ||
DiskWriteBytesRate float32 `json:"disk_write_bytes_rate" bson:"disk_write_bytes_rate"` | ||
NetworkBytesSentRate float32 `json:"network_bytes_sent_rate" bson:"network_bytes_sent_rate"` | ||
NetworkBytesRecvRate float32 `json:"network_bytes_recv_rate" bson:"network_bytes_recv_rate"` | ||
} |
Oops, something went wrong.