mirror of
				https://source.quilibrium.com/quilibrium/ceremonyclient.git
				synced 2025-11-04 13:27:27 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			269 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			269 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package relay
 | 
						|
 | 
						|
import (
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/libp2p/go-libp2p/p2p/metricshelper"
 | 
						|
	pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb"
 | 
						|
	"github.com/prometheus/client_golang/prometheus"
 | 
						|
)
 | 
						|
 | 
						|
const metricNamespace = "libp2p_relaysvc"
 | 
						|
 | 
						|
var (
 | 
						|
	status = prometheus.NewGauge(
 | 
						|
		prometheus.GaugeOpts{
 | 
						|
			Namespace: metricNamespace,
 | 
						|
			Name:      "status",
 | 
						|
			Help:      "Relay Status",
 | 
						|
		},
 | 
						|
	)
 | 
						|
 | 
						|
	reservationsTotal = prometheus.NewCounterVec(
 | 
						|
		prometheus.CounterOpts{
 | 
						|
			Namespace: metricNamespace,
 | 
						|
			Name:      "reservations_total",
 | 
						|
			Help:      "Relay Reservation Request",
 | 
						|
		},
 | 
						|
		[]string{"type"},
 | 
						|
	)
 | 
						|
	reservationRequestResponseStatusTotal = prometheus.NewCounterVec(
 | 
						|
		prometheus.CounterOpts{
 | 
						|
			Namespace: metricNamespace,
 | 
						|
			Name:      "reservation_request_response_status_total",
 | 
						|
			Help:      "Relay Reservation Request Response Status",
 | 
						|
		},
 | 
						|
		[]string{"status"},
 | 
						|
	)
 | 
						|
	reservationRejectionsTotal = prometheus.NewCounterVec(
 | 
						|
		prometheus.CounterOpts{
 | 
						|
			Namespace: metricNamespace,
 | 
						|
			Name:      "reservation_rejections_total",
 | 
						|
			Help:      "Relay Reservation Rejected Reason",
 | 
						|
		},
 | 
						|
		[]string{"reason"},
 | 
						|
	)
 | 
						|
 | 
						|
	connectionsTotal = prometheus.NewCounterVec(
 | 
						|
		prometheus.CounterOpts{
 | 
						|
			Namespace: metricNamespace,
 | 
						|
			Name:      "connections_total",
 | 
						|
			Help:      "Relay Connection Total",
 | 
						|
		},
 | 
						|
		[]string{"type"},
 | 
						|
	)
 | 
						|
	connectionRequestResponseStatusTotal = prometheus.NewCounterVec(
 | 
						|
		prometheus.CounterOpts{
 | 
						|
			Namespace: metricNamespace,
 | 
						|
			Name:      "connection_request_response_status_total",
 | 
						|
			Help:      "Relay Connection Request Status",
 | 
						|
		},
 | 
						|
		[]string{"status"},
 | 
						|
	)
 | 
						|
	connectionRejectionsTotal = prometheus.NewCounterVec(
 | 
						|
		prometheus.CounterOpts{
 | 
						|
			Namespace: metricNamespace,
 | 
						|
			Name:      "connection_rejections_total",
 | 
						|
			Help:      "Relay Connection Rejected Reason",
 | 
						|
		},
 | 
						|
		[]string{"reason"},
 | 
						|
	)
 | 
						|
	connectionDurationSeconds = prometheus.NewHistogram(
 | 
						|
		prometheus.HistogramOpts{
 | 
						|
			Namespace: metricNamespace,
 | 
						|
			Name:      "connection_duration_seconds",
 | 
						|
			Help:      "Relay Connection Duration",
 | 
						|
		},
 | 
						|
	)
 | 
						|
 | 
						|
	dataTransferredBytesTotal = prometheus.NewCounter(
 | 
						|
		prometheus.CounterOpts{
 | 
						|
			Namespace: metricNamespace,
 | 
						|
			Name:      "data_transferred_bytes_total",
 | 
						|
			Help:      "Bytes Transferred Total",
 | 
						|
		},
 | 
						|
	)
 | 
						|
 | 
						|
	collectors = []prometheus.Collector{
 | 
						|
		status,
 | 
						|
		reservationsTotal,
 | 
						|
		reservationRequestResponseStatusTotal,
 | 
						|
		reservationRejectionsTotal,
 | 
						|
		connectionsTotal,
 | 
						|
		connectionRequestResponseStatusTotal,
 | 
						|
		connectionRejectionsTotal,
 | 
						|
		connectionDurationSeconds,
 | 
						|
		dataTransferredBytesTotal,
 | 
						|
	}
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	requestStatusOK       = "ok"
 | 
						|
	requestStatusRejected = "rejected"
 | 
						|
	requestStatusError    = "error"
 | 
						|
)
 | 
						|
 | 
						|
// MetricsTracer is the interface for tracking metrics for relay service
 | 
						|
type MetricsTracer interface {
 | 
						|
	// RelayStatus tracks whether the service is currently active
 | 
						|
	RelayStatus(enabled bool)
 | 
						|
 | 
						|
	// ConnectionOpened tracks metrics on opening a relay connection
 | 
						|
	ConnectionOpened()
 | 
						|
	// ConnectionClosed tracks metrics on closing a relay connection
 | 
						|
	ConnectionClosed(d time.Duration)
 | 
						|
	// ConnectionRequestHandled tracks metrics on handling a relay connection request
 | 
						|
	ConnectionRequestHandled(status pbv2.Status)
 | 
						|
 | 
						|
	// ReservationAllowed tracks metrics on opening or renewing a relay reservation
 | 
						|
	ReservationAllowed(isRenewal bool)
 | 
						|
	// ReservationRequestClosed tracks metrics on closing a relay reservation
 | 
						|
	ReservationClosed(cnt int)
 | 
						|
	// ReservationRequestHandled tracks metrics on handling a relay reservation request
 | 
						|
	ReservationRequestHandled(status pbv2.Status)
 | 
						|
 | 
						|
	// BytesTransferred tracks the total bytes transferred by the relay service
 | 
						|
	BytesTransferred(cnt int)
 | 
						|
}
 | 
						|
 | 
						|
type metricsTracer struct{}
 | 
						|
 | 
						|
var _ MetricsTracer = &metricsTracer{}
 | 
						|
 | 
						|
type metricsTracerSetting struct {
 | 
						|
	reg prometheus.Registerer
 | 
						|
}
 | 
						|
 | 
						|
type MetricsTracerOption func(*metricsTracerSetting)
 | 
						|
 | 
						|
func WithRegisterer(reg prometheus.Registerer) MetricsTracerOption {
 | 
						|
	return func(s *metricsTracerSetting) {
 | 
						|
		if reg != nil {
 | 
						|
			s.reg = reg
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func NewMetricsTracer(opts ...MetricsTracerOption) MetricsTracer {
 | 
						|
	setting := &metricsTracerSetting{reg: prometheus.DefaultRegisterer}
 | 
						|
	for _, opt := range opts {
 | 
						|
		opt(setting)
 | 
						|
	}
 | 
						|
	metricshelper.RegisterCollectors(setting.reg, collectors...)
 | 
						|
	return &metricsTracer{}
 | 
						|
}
 | 
						|
 | 
						|
func (mt *metricsTracer) RelayStatus(enabled bool) {
 | 
						|
	if enabled {
 | 
						|
		status.Set(1)
 | 
						|
	} else {
 | 
						|
		status.Set(0)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (mt *metricsTracer) ConnectionOpened() {
 | 
						|
	tags := metricshelper.GetStringSlice()
 | 
						|
	defer metricshelper.PutStringSlice(tags)
 | 
						|
	*tags = append(*tags, "opened")
 | 
						|
 | 
						|
	connectionsTotal.WithLabelValues(*tags...).Add(1)
 | 
						|
}
 | 
						|
 | 
						|
func (mt *metricsTracer) ConnectionClosed(d time.Duration) {
 | 
						|
	tags := metricshelper.GetStringSlice()
 | 
						|
	defer metricshelper.PutStringSlice(tags)
 | 
						|
	*tags = append(*tags, "closed")
 | 
						|
 | 
						|
	connectionsTotal.WithLabelValues(*tags...).Add(1)
 | 
						|
	connectionDurationSeconds.Observe(d.Seconds())
 | 
						|
}
 | 
						|
 | 
						|
func (mt *metricsTracer) ConnectionRequestHandled(status pbv2.Status) {
 | 
						|
	tags := metricshelper.GetStringSlice()
 | 
						|
	defer metricshelper.PutStringSlice(tags)
 | 
						|
 | 
						|
	respStatus := getResponseStatus(status)
 | 
						|
 | 
						|
	*tags = append(*tags, respStatus)
 | 
						|
	connectionRequestResponseStatusTotal.WithLabelValues(*tags...).Add(1)
 | 
						|
	if respStatus == requestStatusRejected {
 | 
						|
		*tags = (*tags)[:0]
 | 
						|
		*tags = append(*tags, getRejectionReason(status))
 | 
						|
		connectionRejectionsTotal.WithLabelValues(*tags...).Add(1)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (mt *metricsTracer) ReservationAllowed(isRenewal bool) {
 | 
						|
	tags := metricshelper.GetStringSlice()
 | 
						|
	defer metricshelper.PutStringSlice(tags)
 | 
						|
	if isRenewal {
 | 
						|
		*tags = append(*tags, "renewed")
 | 
						|
	} else {
 | 
						|
		*tags = append(*tags, "opened")
 | 
						|
	}
 | 
						|
 | 
						|
	reservationsTotal.WithLabelValues(*tags...).Add(1)
 | 
						|
}
 | 
						|
 | 
						|
func (mt *metricsTracer) ReservationClosed(cnt int) {
 | 
						|
	tags := metricshelper.GetStringSlice()
 | 
						|
	defer metricshelper.PutStringSlice(tags)
 | 
						|
	*tags = append(*tags, "closed")
 | 
						|
 | 
						|
	reservationsTotal.WithLabelValues(*tags...).Add(float64(cnt))
 | 
						|
}
 | 
						|
 | 
						|
func (mt *metricsTracer) ReservationRequestHandled(status pbv2.Status) {
 | 
						|
	tags := metricshelper.GetStringSlice()
 | 
						|
	defer metricshelper.PutStringSlice(tags)
 | 
						|
 | 
						|
	respStatus := getResponseStatus(status)
 | 
						|
 | 
						|
	*tags = append(*tags, respStatus)
 | 
						|
	reservationRequestResponseStatusTotal.WithLabelValues(*tags...).Add(1)
 | 
						|
	if respStatus == requestStatusRejected {
 | 
						|
		*tags = (*tags)[:0]
 | 
						|
		*tags = append(*tags, getRejectionReason(status))
 | 
						|
		reservationRejectionsTotal.WithLabelValues(*tags...).Add(1)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (mt *metricsTracer) BytesTransferred(cnt int) {
 | 
						|
	dataTransferredBytesTotal.Add(float64(cnt))
 | 
						|
}
 | 
						|
 | 
						|
func getResponseStatus(status pbv2.Status) string {
 | 
						|
	responseStatus := "unknown"
 | 
						|
	switch status {
 | 
						|
	case pbv2.Status_RESERVATION_REFUSED,
 | 
						|
		pbv2.Status_RESOURCE_LIMIT_EXCEEDED,
 | 
						|
		pbv2.Status_PERMISSION_DENIED,
 | 
						|
		pbv2.Status_NO_RESERVATION,
 | 
						|
		pbv2.Status_MALFORMED_MESSAGE:
 | 
						|
 | 
						|
		responseStatus = requestStatusRejected
 | 
						|
	case pbv2.Status_UNEXPECTED_MESSAGE, pbv2.Status_CONNECTION_FAILED:
 | 
						|
		responseStatus = requestStatusError
 | 
						|
	case pbv2.Status_OK:
 | 
						|
		responseStatus = requestStatusOK
 | 
						|
	}
 | 
						|
	return responseStatus
 | 
						|
}
 | 
						|
 | 
						|
func getRejectionReason(status pbv2.Status) string {
 | 
						|
	reason := "unknown"
 | 
						|
	switch status {
 | 
						|
	case pbv2.Status_RESERVATION_REFUSED:
 | 
						|
		reason = "ip constraint violation"
 | 
						|
	case pbv2.Status_RESOURCE_LIMIT_EXCEEDED:
 | 
						|
		reason = "resource limit exceeded"
 | 
						|
	case pbv2.Status_PERMISSION_DENIED:
 | 
						|
		reason = "permission denied"
 | 
						|
	case pbv2.Status_NO_RESERVATION:
 | 
						|
		reason = "no reservation"
 | 
						|
	case pbv2.Status_MALFORMED_MESSAGE:
 | 
						|
		reason = "malformed message"
 | 
						|
	}
 | 
						|
	return reason
 | 
						|
}
 |