Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add metrics to snet #3257

Merged
merged 3 commits into from
Oct 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go/lib/snet/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ go_library(
"//go/lib/scmp:go_default_library",
"//go/lib/serrors:go_default_library",
"//go/lib/snet/internal/ctxmonitor:go_default_library",
"//go/lib/snet/internal/metrics:go_default_library",
"//go/lib/snet/internal/pathsource:go_default_library",
"//go/lib/sock/reliable:go_default_library",
"//go/lib/spath:go_default_library",
Expand Down
8 changes: 8 additions & 0 deletions go/lib/snet/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/scionproto/scion/go/lib/overlay"
"github.com/scionproto/scion/go/lib/pathmgr"
"github.com/scionproto/scion/go/lib/scmp"
"github.com/scionproto/scion/go/lib/snet/internal/metrics"
"github.com/scionproto/scion/go/lib/sock/reliable"
)

Expand Down Expand Up @@ -101,6 +102,13 @@ func (h *scmpHandler) Handle(pkt *SCIONPacket) error {
if !ok {
return common.NewBasicError("scmp handler invoked with non-scmp packet", nil, "pkt", pkt)
}
if hdr.Class != scmp.C_General {
metrics.M.SCMPErrors().Inc()
}
if hdr.Class == scmp.C_General && hdr.Type == scmp.T_G_Unspecified {
// SCMP::General::Unspecified is used for errors
metrics.M.SCMPErrors().Inc()
}

// Only handle revocations for now
if hdr.Class == scmp.C_Path && hdr.Type == scmp.T_P_RevokedIF {
Expand Down
12 changes: 12 additions & 0 deletions go/lib/snet/internal/metrics/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")

go_library(
name = "go_default_library",
srcs = ["metrics.go"],
importpath = "github.com/scionproto/scion/go/lib/snet/internal/metrics",
visibility = ["//go/lib/snet:__subpackages__"],
deps = [
"//go/lib/prom:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
],
)
128 changes: 128 additions & 0 deletions go/lib/snet/internal/metrics/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright 2019 ETH Zurich
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package metrics

import (
"github.com/prometheus/client_golang/prometheus"

"github.com/scionproto/scion/go/lib/prom"
)

const (
// Namespace is the metrics namespace for the SCIOND client API.
Namespace = "lib_snet"

subDials = "dials"
subListens = "listens"
subCloses = "closes"
subRead = "read"
subWrite = "write"
subSCMPError = "scmp_error"
subDispatcherError = "dispatcher_error"
subParseError = "parse_error"
)

var (
// M exposes all the initialized metrics for this package.
M = newMetrics()
)

type metrics struct {
dials prometheus.Counter
listens prometheus.Counter
closes prometheus.Counter
readBytes prometheus.Counter
readPackets prometheus.Counter
writeBytes prometheus.Counter
writePackets prometheus.Counter
parseErrors prometheus.Counter
scmpErrors prometheus.Counter
dispatcherErrors prometheus.Counter
}

func newMetrics() metrics {
return metrics{
dials: prom.NewCounter(Namespace, subDials, "total",
"Total number of Dial calls."),
listens: prom.NewCounter(Namespace, subListens, "total",
"Total number of Listen calls."),
closes: prom.NewCounter(Namespace, subCloses, "total",
"Total number of Close calls."),
readBytes: prom.NewCounter(Namespace, subRead, "total_bytes",
"Total number of bytes read"),
readPackets: prom.NewCounter(Namespace, subRead, "total_pkts",
"Total number of packetes read"),
writeBytes: prom.NewCounter(Namespace, subWrite, "total_bytes",
"Total number of bytes written"),
writePackets: prom.NewCounter(Namespace, subWrite, "total_pkts",
"Total number of packets written"),
scmpErrors: prom.NewCounter(Namespace, subSCMPError, "total",
"Total number of SCMP errors"),
dispatcherErrors: prom.NewCounter(Namespace, subDispatcherError, "total",
"Total number of dispatcher errors"),
parseErrors: prom.NewCounter(Namespace, subParseError, "total",
"Total number of parse errors"),
}
}

// Dials returns the dials counter.
func (m metrics) Dials() prometheus.Counter {
return m.dials
}

// Listens returns the listens counter.
func (m metrics) Listens() prometheus.Counter {
return m.listens
}

// Closes returns the closes counter.
func (m metrics) Closes() prometheus.Counter {
return m.closes
}

// ReadBytes returns the bytes read counter.
func (m metrics) ReadBytes() prometheus.Counter {
return m.readBytes
}

// ReadPackets returns the packets read counter.
func (m metrics) ReadPackets() prometheus.Counter {
return m.readPackets
}

// WriteBytes returns the bytes written counter.
func (m metrics) WriteBytes() prometheus.Counter {
return m.writeBytes
}

// WritePackets returns the packets written counter.
func (m metrics) WritePackets() prometheus.Counter {
return m.writePackets
}

// DispatcherErrors returns the dispather errors counter.
func (m metrics) DispatcherErrors() prometheus.Counter {
return m.dispatcherErrors
}

// SCMPErrors returns the SCMP errors counter.
func (m metrics) SCMPErrors() prometheus.Counter {
return m.scmpErrors
}

// ParseErrors returns the parse errors counter.
func (m metrics) ParseErrors() prometheus.Counter {
return m.parseErrors
}
12 changes: 11 additions & 1 deletion go/lib/snet/packet_conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/scionproto/scion/go/lib/l4"
"github.com/scionproto/scion/go/lib/overlay"
"github.com/scionproto/scion/go/lib/scmp"
"github.com/scionproto/scion/go/lib/snet/internal/metrics"
"github.com/scionproto/scion/go/lib/spath"
"github.com/scionproto/scion/go/lib/spkt"
)
Expand Down Expand Up @@ -137,6 +138,7 @@ func (c *SCIONPacketConn) SetDeadline(d time.Time) error {
}

func (c *SCIONPacketConn) Close() error {
metrics.M.Closes().Inc()
return c.conn.Close()
}

Expand Down Expand Up @@ -166,10 +168,12 @@ func (c *SCIONPacketConn) WriteTo(pkt *SCIONPacket, ov *overlay.OverlayAddr) err
}
pkt.Bytes = pkt.Bytes[:n]
// Send message
_, err = c.conn.WriteTo(pkt.Bytes, ov)
n, err = c.conn.WriteTo(pkt.Bytes, ov)
if err != nil {
return common.NewBasicError("Reliable socket write error", err)
}
metrics.M.WriteBytes().Add(float64(n))
metrics.M.WritePackets().Inc()
return nil
}

Expand All @@ -185,6 +189,7 @@ func (c *SCIONPacketConn) ReadFrom(pkt *SCIONPacket, ov *overlay.OverlayAddr) er
}
if scmpHdr, ok := pkt.L4Header.(*scmp.Hdr); ok {
if c.scmpHandler == nil {
metrics.M.SCMPErrors().Inc()
return common.NewBasicError("scmp packet received, but no handler found", nil,
"scmp.Hdr", scmpHdr, "src", pkt.Source)
}
Expand All @@ -205,8 +210,12 @@ func (c *SCIONPacketConn) readFrom(pkt *SCIONPacket, ov *overlay.OverlayAddr) er
pkt.Prepare()
n, lastHopNetAddr, err := c.conn.ReadFrom(pkt.Bytes)
if err != nil {
metrics.M.DispatcherErrors().Inc()
return common.NewBasicError("Reliable socket read error", err)
}
metrics.M.ReadBytes().Add(float64(n))
metrics.M.ReadPackets().Inc()

pkt.Bytes = pkt.Bytes[:n]
var lastHop *overlay.OverlayAddr

Expand All @@ -225,6 +234,7 @@ func (c *SCIONPacketConn) readFrom(pkt *SCIONPacket, ov *overlay.OverlayAddr) er
}
err = hpkt.ParseScnPkt(scnPkt, common.RawBytes(pkt.Bytes))
if err != nil {
metrics.M.ParseErrors().Inc()
return common.NewBasicError("SCION packet parse error", err)
}

Expand Down
3 changes: 3 additions & 0 deletions go/lib/snet/snet.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import (
"github.com/scionproto/scion/go/lib/pathmgr"
"github.com/scionproto/scion/go/lib/sciond"
"github.com/scionproto/scion/go/lib/serrors"
"github.com/scionproto/scion/go/lib/snet/internal/metrics"
"github.com/scionproto/scion/go/lib/sock/reliable"
)

Expand Down Expand Up @@ -200,6 +201,7 @@ func (n *SCIONNetwork) DialSCION(network string, laddr, raddr *Addr,
func (n *SCIONNetwork) DialSCIONWithBindSVC(network string, laddr, raddr, baddr *Addr,
svc addr.HostSVC, timeout time.Duration) (Conn, error) {

metrics.M.Dials().Inc()
if raddr == nil {
return nil, serrors.New("Unable to dial to nil remote")
}
Expand Down Expand Up @@ -233,6 +235,7 @@ func (n *SCIONNetwork) ListenSCION(network string, laddr *Addr,
func (n *SCIONNetwork) ListenSCIONWithBindSVC(network string, laddr, baddr *Addr,
svc addr.HostSVC, timeout time.Duration) (Conn, error) {

metrics.M.Listens().Inc()
// FIXME(scrye): If no local address is specified, we want to
// bind to the address of the outbound interface on a random
// free port. However, the current dispatcher version cannot
Expand Down