uquic/metrics/metrics.go
2020-07-15 20:33:58 +07:00

145 lines
5.1 KiB
Go

package metrics
import (
"context"
"net"
"time"
"github.com/lucas-clemente/quic-go/logging"
"go.opencensus.io/stats"
"go.opencensus.io/stats/view"
"go.opencensus.io/tag"
)
// Measures
var (
connections = stats.Int64("quic-go/connections", "number of QUIC connections", stats.UnitDimensionless)
lostPackets = stats.Int64("quic-go/lost-packets", "number of packets declared lost", stats.UnitDimensionless)
sentPackets = stats.Int64("quic-go/sent-packets", "number of packets sent", stats.UnitDimensionless)
)
// Tags
var (
keyPerspective, _ = tag.NewKey("perspective")
keyIPVersion, _ = tag.NewKey("ip_version")
keyEncryptionLevel, _ = tag.NewKey("encryption_level")
keyPacketLossReason, _ = tag.NewKey("packet_loss_reason")
keyPacketType, _ = tag.NewKey("packet_type")
)
// Views
var (
ConnectionsView = &view.View{
Measure: connections,
TagKeys: []tag.Key{keyPerspective, keyIPVersion},
Aggregation: view.Count(),
}
LostPacketsView = &view.View{
Measure: lostPackets,
TagKeys: []tag.Key{keyEncryptionLevel, keyPacketLossReason},
Aggregation: view.Count(),
}
SentPacketsView = &view.View{
Measure: sentPackets,
TagKeys: []tag.Key{keyPacketType},
Aggregation: view.Count(),
}
)
// DefaultViews collects all OpenCensus views for metric gathering purposes
var DefaultViews = []*view.View{
ConnectionsView,
LostPacketsView,
SentPacketsView,
}
type tracer struct{}
var _ logging.Tracer = &tracer{}
// NewTracer creates a new metrics tracer.
func NewTracer() logging.Tracer { return &tracer{} }
func (t *tracer) TracerForConnection(p logging.Perspective, _ logging.ConnectionID) logging.ConnectionTracer {
return newConnTracer(t, p)
}
func (t *tracer) DroppedPacket(net.Addr, logging.PacketType, logging.ByteCount, logging.PacketDropReason) {
}
type connTracer struct {
perspective logging.Perspective
tracer logging.Tracer
}
func newConnTracer(tracer logging.Tracer, perspective logging.Perspective) logging.ConnectionTracer {
return &connTracer{
perspective: perspective,
tracer: tracer,
}
}
var _ logging.ConnectionTracer = &connTracer{}
func (t *connTracer) StartedConnection(local, _ net.Addr, _ logging.VersionNumber, _, _ logging.ConnectionID) {
perspectiveTag := tag.Upsert(keyPerspective, perspective(t.perspective).String())
var ipVersionTag tag.Mutator
if udpAddr, ok := local.(*net.UDPAddr); ok {
// If ip is not an IPv4 address, To4 returns nil.
// Note that there might be some corner cases, where this is not correct.
// See https://stackoverflow.com/questions/22751035/golang-distinguish-ipv4-ipv6.
if udpAddr.IP.To4() == nil {
ipVersionTag = tag.Upsert(keyIPVersion, "IPv6")
} else {
ipVersionTag = tag.Upsert(keyIPVersion, "IPv4")
}
} else {
ipVersionTag = tag.Upsert(keyIPVersion, "unknown")
}
stats.RecordWithTags(
context.Background(),
[]tag.Mutator{perspectiveTag, ipVersionTag},
connections.M(1),
)
}
func (t *connTracer) ClosedConnection(logging.CloseReason) {}
func (t *connTracer) SentTransportParameters(*logging.TransportParameters) {}
func (t *connTracer) ReceivedTransportParameters(*logging.TransportParameters) {}
func (t *connTracer) SentPacket(hdr *logging.ExtendedHeader, _ logging.ByteCount, _ *logging.AckFrame, _ []logging.Frame) {
stats.RecordWithTags(
context.Background(),
[]tag.Mutator{
tag.Upsert(keyPacketType, packetType(logging.PacketTypeFromHeader(&hdr.Header)).String()),
},
sentPackets.M(1),
)
}
func (t *connTracer) ReceivedVersionNegotiationPacket(*logging.Header, []logging.VersionNumber) {}
func (t *connTracer) ReceivedRetry(*logging.Header) {}
func (t *connTracer) ReceivedPacket(*logging.ExtendedHeader, logging.ByteCount, []logging.Frame) {
}
func (t *connTracer) BufferedPacket(logging.PacketType) {}
func (t *connTracer) DroppedPacket(logging.PacketType, logging.ByteCount, logging.PacketDropReason) {}
func (t *connTracer) UpdatedMetrics(*logging.RTTStats, logging.ByteCount, logging.ByteCount, int) {}
func (t *connTracer) LostPacket(encLevel logging.EncryptionLevel, _ logging.PacketNumber, reason logging.PacketLossReason) {
stats.RecordWithTags(
context.Background(),
[]tag.Mutator{
tag.Upsert(keyEncryptionLevel, encryptionLevel(encLevel).String()),
tag.Upsert(keyPacketLossReason, packetLossReason(reason).String()),
},
lostPackets.M(1),
)
}
func (t *connTracer) UpdatedPTOCount(value uint32) {}
func (t *connTracer) UpdatedKeyFromTLS(logging.EncryptionLevel, logging.Perspective) {}
func (t *connTracer) UpdatedKey(logging.KeyPhase, bool) {}
func (t *connTracer) DroppedEncryptionLevel(logging.EncryptionLevel) {}
func (t *connTracer) SetLossTimer(logging.TimerType, logging.EncryptionLevel, time.Time) {}
func (t *connTracer) LossTimerExpired(logging.TimerType, logging.EncryptionLevel) {}
func (t *connTracer) LossTimerCanceled() {}
func (t *connTracer) Close() {}