Skip to content
Snippets Groups Projects
Unverified Commit 4cfff8e7 authored by capossele's avatar capossele
Browse files

:sparkles: Add metric heartbeat packet

parent 5afbcb1c
No related branches found
No related tags found
No related merge requests found
package packet
import (
"bytes"
"encoding/binary"
"encoding/gob"
"errors"
"github.com/iotaledger/hive.go/protocol/message"
"github.com/iotaledger/hive.go/protocol/tlv"
)
var (
// ErrInvalidMetricHeartbeat is returned for invalid Metric heartbeats.
ErrInvalidMetricHeartbeat = errors.New("invalid Metric heartbeat")
)
var (
// MetricHeartbeatMessageDefinition defines a metric heartbeat message's format.
MetricHeartbeatMessageDefinition = &message.Definition{
ID: MessageTypeMetricHeartbeat,
MaxBytesLength: 65535,
VariableLength: true,
}
)
// MetricHeartbeat represents a metric heartbeat packet.
type MetricHeartbeat struct {
// The ID of the node who sent the heartbeat.
// Must be contained when a heartbeat is serialized.
OwnID []byte
OS string
Arch string
NumCPU int
CPUUsage float64
MemoryUsage uint64
}
// ParseMetricHeartbeat parses a slice of bytes (serialized packet) into a Metric heartbeat.
func ParseMetricHeartbeat(data []byte) (*MetricHeartbeat, error) {
hb := &MetricHeartbeat{}
buf := new(bytes.Buffer)
_, err := buf.Write(data)
if err != nil {
return nil, err
}
decoder := gob.NewDecoder(buf)
err = decoder.Decode(hb)
if err != nil {
return nil, err
}
return hb, nil
}
// Bytes return the Metric heartbeat encoded as bytes
func (hb MetricHeartbeat) Bytes() ([]byte, error) {
buf := new(bytes.Buffer)
encoder := gob.NewEncoder(buf)
err := encoder.Encode(hb)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// NewMetricHeartbeatMessage serializes the given Metric heartbeat into a byte slice and adds a tlv header to the packet.
// message = tlv header + serialized packet
func NewMetricHeartbeatMessage(hb *MetricHeartbeat) ([]byte, error) {
packet, err := hb.Bytes()
if err != nil {
return nil, err
}
// calculate total needed bytes based on packet
packetSize := len(packet)
// create a buffer for tlv header plus the packet
buf := bytes.NewBuffer(make([]byte, 0, tlv.HeaderMessageDefinition.MaxBytesLength+uint16(packetSize)))
// write tlv header into buffer
if err := tlv.WriteHeader(buf, MessageTypeMetricHeartbeat, uint16(packetSize)); err != nil {
return nil, err
}
// write serialized packet bytes into the buffer
if err := binary.Write(buf, binary.BigEndian, packet); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
package packet
import (
"crypto/sha256"
"runtime"
"testing"
"time"
"github.com/iotaledger/hive.go/protocol/message"
"github.com/iotaledger/hive.go/protocol/tlv"
"github.com/shirou/gopsutil/cpu"
"github.com/stretchr/testify/require"
)
var nodeID = sha256.Sum256([]byte{'A'})
func testMetricHeartbeat() *MetricHeartbeat {
return &MetricHeartbeat{
OwnID: nodeID[:],
OS: runtime.GOOS,
Arch: runtime.GOARCH,
NumCPU: runtime.NumCPU(),
CPUUsage: func() (p float64) {
percent, err := cpu.Percent(time.Second, false)
if err == nil {
p = percent[0]
}
return
}(),
MemoryUsage: func() uint64 {
var m runtime.MemStats
runtime.ReadMemStats(&m)
return m.Alloc
}(),
}
}
func TestMetricHeartbeat(t *testing.T) {
hb := testMetricHeartbeat()
packet, err := hb.Bytes()
require.NoError(t, err)
hbParsed, err := ParseMetricHeartbeat(packet)
require.NoError(t, err)
require.Equal(t, hb, hbParsed)
tlvHeaderLength := int(tlv.HeaderMessageDefinition.MaxBytesLength)
msg, err := NewMetricHeartbeatMessage(hb)
require.NoError(t, err)
require.Equal(t, MessageTypeMetricHeartbeat, message.Type(msg[0]))
hbParsed, err = ParseMetricHeartbeat(msg[tlvHeaderLength:])
require.NoError(t, err)
require.Equal(t, hb, hbParsed)
}
......@@ -7,4 +7,6 @@ const (
MessageTypeHeartbeat message.Type = iota + 1
// MessageTypeFPCHeartbeat defines the FPC Heartbeat msg type
MessageTypeFPCHeartbeat
// MessageTypeMetricHeartbeat defines the Metric Heartbeat msg type
MessageTypeMetricHeartbeat
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment