mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-18 14:49:57 +00:00
113 lines
3.7 KiB
Go
113 lines
3.7 KiB
Go
package metrics
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/VictoriaMetrics/metrics"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// victoriaMetrics is the VictoriaMetrics implementation of ClientMetrics
|
|
type victoriaMetrics struct {
|
|
// Static attributes applied to all metrics
|
|
deploymentType DeploymentType
|
|
|
|
// Metrics set for managing all metrics
|
|
set *metrics.Set
|
|
}
|
|
|
|
func newVictoriaMetrics(deploymentType DeploymentType) metricsImplementation {
|
|
return &victoriaMetrics{
|
|
deploymentType: deploymentType,
|
|
set: metrics.NewSet(),
|
|
}
|
|
}
|
|
|
|
// RecordConnectionStages records the duration of each connection stage from timestamps
|
|
func (m *victoriaMetrics) RecordConnectionStages(
|
|
ctx context.Context,
|
|
connectionType ConnectionType,
|
|
isReconnection bool,
|
|
timestamps ConnectionStageTimestamps,
|
|
) {
|
|
// Calculate stage durations
|
|
var creationToSemaphore, semaphoreToSignaling, signalingToConnection, connectionToHandshake, totalDuration float64
|
|
|
|
if !timestamps.Created.IsZero() && !timestamps.SemaphoreAcquired.IsZero() {
|
|
creationToSemaphore = timestamps.SemaphoreAcquired.Sub(timestamps.Created).Seconds()
|
|
}
|
|
|
|
if !timestamps.SemaphoreAcquired.IsZero() && !timestamps.Signaling.IsZero() {
|
|
semaphoreToSignaling = timestamps.Signaling.Sub(timestamps.SemaphoreAcquired).Seconds()
|
|
}
|
|
|
|
if !timestamps.Signaling.IsZero() && !timestamps.ConnectionReady.IsZero() {
|
|
signalingToConnection = timestamps.ConnectionReady.Sub(timestamps.Signaling).Seconds()
|
|
}
|
|
|
|
if !timestamps.ConnectionReady.IsZero() && !timestamps.WgHandshakeSuccess.IsZero() {
|
|
connectionToHandshake = timestamps.WgHandshakeSuccess.Sub(timestamps.ConnectionReady).Seconds()
|
|
}
|
|
|
|
if !timestamps.Created.IsZero() && !timestamps.WgHandshakeSuccess.IsZero() {
|
|
totalDuration = timestamps.WgHandshakeSuccess.Sub(timestamps.Created).Seconds()
|
|
}
|
|
|
|
// Determine attempt type
|
|
attemptType := "initial"
|
|
if isReconnection {
|
|
attemptType = "reconnection"
|
|
}
|
|
|
|
connTypeStr := connectionType.String()
|
|
|
|
// Record observations using histograms
|
|
m.set.GetOrCreateHistogram(
|
|
m.getMetricName("netbird_peer_connection_stage_creation_to_semaphore", connTypeStr, attemptType),
|
|
).Update(creationToSemaphore)
|
|
|
|
m.set.GetOrCreateHistogram(
|
|
m.getMetricName("netbird_peer_connection_stage_semaphore_to_signaling", connTypeStr, attemptType),
|
|
).Update(semaphoreToSignaling)
|
|
|
|
m.set.GetOrCreateHistogram(
|
|
m.getMetricName("netbird_peer_connection_stage_signaling_to_connection", connTypeStr, attemptType),
|
|
).Update(signalingToConnection)
|
|
|
|
m.set.GetOrCreateHistogram(
|
|
m.getMetricName("netbird_peer_connection_stage_connection_to_handshake", connTypeStr, attemptType),
|
|
).Update(connectionToHandshake)
|
|
|
|
m.set.GetOrCreateHistogram(
|
|
m.getMetricName("netbird_peer_connection_total_creation_to_handshake", connTypeStr, attemptType),
|
|
).Update(totalDuration)
|
|
|
|
log.Tracef("peer connection metrics [%s, %s, %s]: creation→semaphore: %.3fs, semaphore→signaling: %.3fs, signaling→connection: %.3fs, connection→handshake: %.3fs, total: %.3fs",
|
|
m.deploymentType.String(), connTypeStr, attemptType,
|
|
creationToSemaphore, semaphoreToSignaling, signalingToConnection, connectionToHandshake,
|
|
totalDuration)
|
|
}
|
|
|
|
// getMetricName constructs a metric name with labels
|
|
func (m *victoriaMetrics) getMetricName(baseName, connectionType, attemptType string) string {
|
|
return fmt.Sprintf(`%s{deployment_type=%q,connection_type=%q,attempt_type=%q}`,
|
|
baseName,
|
|
m.deploymentType.String(),
|
|
connectionType,
|
|
attemptType,
|
|
)
|
|
}
|
|
|
|
// Export writes metrics in Prometheus text format
|
|
func (m *victoriaMetrics) Export(w io.Writer) error {
|
|
if m.set == nil {
|
|
return fmt.Errorf("metrics set not initialized")
|
|
}
|
|
|
|
// Write metrics in Prometheus format
|
|
m.set.WritePrometheus(w)
|
|
return nil
|
|
}
|