mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-16 15:26:40 +00:00
119 lines
3.2 KiB
Go
119 lines
3.2 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"go.opentelemetry.io/otel/attribute"
|
|
"go.opentelemetry.io/otel/metric"
|
|
)
|
|
|
|
// MetricsRecorder defines the interface for recording proxy metrics
|
|
type MetricsRecorder interface {
|
|
// RecordConnection records a new connection
|
|
RecordConnection(ctx context.Context)
|
|
// RecordDisconnection records a connection closing
|
|
RecordDisconnection(ctx context.Context)
|
|
// RecordBytesTransferred records bytes transferred in a direction
|
|
RecordBytesTransferred(ctx context.Context, direction string, bytes int64)
|
|
// RecordError records an error
|
|
RecordError(ctx context.Context, errorType string)
|
|
}
|
|
|
|
// NoOpMetricsRecorder is a no-op implementation that does nothing
|
|
type NoOpMetricsRecorder struct{}
|
|
|
|
func (n NoOpMetricsRecorder) RecordConnection(ctx context.Context) {
|
|
// no-op
|
|
}
|
|
func (n NoOpMetricsRecorder) RecordDisconnection(ctx context.Context) {
|
|
// no-op
|
|
}
|
|
func (n NoOpMetricsRecorder) RecordBytesTransferred(ctx context.Context, direction string, bytes int64) {
|
|
// no-op
|
|
}
|
|
func (n NoOpMetricsRecorder) RecordError(ctx context.Context, errorType string) {
|
|
// no-op
|
|
}
|
|
|
|
// Recorder implements MetricsRecorder using OpenTelemetry
|
|
type Recorder struct {
|
|
activeConnections metric.Int64UpDownCounter
|
|
bytesTransferred metric.Int64Counter
|
|
errors metric.Int64Counter
|
|
}
|
|
|
|
// NewMetricsRecorder creates a new OpenTelemetry-based metrics recorder
|
|
func NewMetricsRecorder(meter metric.Meter) (*Recorder, error) {
|
|
activeConnections, err := meter.Int64UpDownCounter(
|
|
"wsproxy_active_connections",
|
|
metric.WithDescription("Number of active WebSocket proxy connections"),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
bytesTransferred, err := meter.Int64Counter(
|
|
"wsproxy_bytes_transferred_total",
|
|
metric.WithDescription("Total bytes transferred through the proxy"),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
errors, err := meter.Int64Counter(
|
|
"wsproxy_errors_total",
|
|
metric.WithDescription("Total number of proxy errors"),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &Recorder{
|
|
activeConnections: activeConnections,
|
|
bytesTransferred: bytesTransferred,
|
|
errors: errors,
|
|
}, nil
|
|
}
|
|
|
|
func (o *Recorder) RecordConnection(ctx context.Context) {
|
|
o.activeConnections.Add(ctx, 1)
|
|
}
|
|
|
|
func (o *Recorder) RecordDisconnection(ctx context.Context) {
|
|
o.activeConnections.Add(ctx, -1)
|
|
}
|
|
|
|
func (o *Recorder) RecordBytesTransferred(ctx context.Context, direction string, bytes int64) {
|
|
o.bytesTransferred.Add(ctx, bytes, metric.WithAttributes(
|
|
attribute.String("direction", direction),
|
|
))
|
|
}
|
|
|
|
func (o *Recorder) RecordError(ctx context.Context, errorType string) {
|
|
o.errors.Add(ctx, 1, metric.WithAttributes(
|
|
attribute.String("error_type", errorType),
|
|
))
|
|
}
|
|
|
|
// Option defines functional options for the Proxy
|
|
type Option func(*Config)
|
|
|
|
// WithMetrics sets a custom metrics recorder
|
|
func WithMetrics(recorder MetricsRecorder) Option {
|
|
return func(c *Config) {
|
|
c.MetricsRecorder = recorder
|
|
}
|
|
}
|
|
|
|
// WithOTelMeter creates and sets an OpenTelemetry metrics recorder
|
|
func WithOTelMeter(meter metric.Meter) Option {
|
|
return func(c *Config) {
|
|
if recorder, err := NewMetricsRecorder(meter); err == nil {
|
|
c.MetricsRecorder = recorder
|
|
} else {
|
|
log.Warnf("Failed to create OTel metrics recorder: %v", err)
|
|
}
|
|
}
|
|
}
|