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

Instrumenting connectivity routines and export spans with OpenTelemetry #140

Closed
wants to merge 6 commits into from
Closed
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
35 changes: 33 additions & 2 deletions x/connectivity/connectivity.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"syscall"
"time"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You’re still depending on otel. We’ll need to stick to it forever with this approach. Even though you’re not exposing the types, there’s dependency on the otel behavior and globals.

I suggest you create a new trace package that defines the interfaces we need. It can mimic otel or the standard library trace. Then the consumer can provide whatever implementation they prefer.

Copy link
Contributor Author

@amircybersec amircybersec Dec 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the packages added in go.mod are not used in the package code (SDK core) and are just used in the tests (connectivity_test.go and tracing_utils_test.go). When building a go app with the SDK, they will be excluded. Only the following three packages are required in the SDK:

go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/metric v1.21.0 ---> we can probably get rid of this one too
go.opentelemetry.io/otel/trace v1.21.0

The rest will go into the application code but they are appearing in go.mod because they were used in tests.

I can investigate alternative approaches to further slim down the bloat.

Here's the full list of packages that are requires for go build and go install operations.

➜  x git:(amir-telemetry) ✗ go list -m all
github.com/Jigsaw-Code/outline-sdk/x
github.com/Jigsaw-Code/outline-sdk v0.0.10
github.com/creack/pty v1.1.9
github.com/davecgh/go-spew v1.1.1
github.com/eycorsican/go-tun2socks v1.16.11
github.com/go-logr/logr v1.3.0
github.com/go-logr/stdr v1.2.2
github.com/google/go-cmp v0.6.0
github.com/google/gopacket v1.1.19
github.com/kr/pretty v0.3.1
github.com/kr/pty v1.1.1
github.com/kr/text v0.2.0
github.com/miekg/dns v1.1.54
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e
github.com/pmezard/go-difflib v1.0.0
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3
github.com/rogpeppe/go-internal v1.10.0
github.com/shadowsocks/go-shadowsocks2 v0.1.5
github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b
github.com/stretchr/objx v0.5.0
github.com/stretchr/testify v1.8.4
github.com/vishvananda/netlink v1.1.0
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df
github.com/yuin/goldmark v1.4.13
go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/metric v1.21.0
go.opentelemetry.io/otel/trace v1.21.0
golang.org/x/crypto v0.14.0
golang.org/x/exp/shiny v0.0.0-20230817173708-d852ddb80c63
golang.org/x/image v0.11.0
golang.org/x/mobile v0.0.0-20230905140555-fbe1c053b6a9
golang.org/x/mod v0.12.0
golang.org/x/net v0.17.0
golang.org/x/sync v0.3.0
golang.org/x/sys v0.14.0
golang.org/x/term v0.13.0
golang.org/x/text v0.13.0
golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
gopkg.in/yaml.v3 v3.0.1

Removing the connectivity_test.go and tracing_utils_test.go and running go mod tidy removes most of the dependencies that are not needed for core instrumentation part of the SDK:

Screenshot 2023-12-16 at 11 58 18 AM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fortuna there's specific language in OpenTelemetry Docs for our specific use-case:

"If you’re instrumenting a library, only install the OpenTelemetry API package for your language. Your library will not emit telemetry on its own. It will only emit telemetry when it is part of an app that uses the OpenTelemetry SDK."

"go.opentelemetry.io/otel"

"github.com/Jigsaw-Code/outline-sdk/transport"
"github.com/miekg/dns"
)
Expand Down Expand Up @@ -49,13 +51,29 @@ func (err *TestError) Unwrap() error {
// TestResolverStreamConnectivity uses the given [transport.StreamEndpoint] to connect to a DNS resolver and resolve the test domain.
// The context can be used to set a timeout or deadline, or to pass values to the dialer.
func TestResolverStreamConnectivity(ctx context.Context, resolver transport.StreamEndpoint, testDomain string) (time.Duration, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed in the meeting, let's make this return the span information, something like:

  • Dial
    • start, end timestamp
    • error
  • Write
    • start, end timestamp
    • error
  • Read
    • start, end timestamp
    • error

Later, we can make users of the API report that in whatever system they want (including otel).

For now, let's remove all the otel logic. We can add to the app later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fortuna I am implementing this by defining Tracer and Span interfaces such that they will be compatible with otel types.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don’t really need that for now. We need to think about the data processing side. Will a genetic structure make it harder?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I am aiming for (i.e. generic span) with the caveat of making interfaces compatible with otel. It is almost done. I need to do some testing and will commit changes shortly. We can use existing report package for collecting the data or developers can use otel if they wish -- connectivity package won't have any dependencies on otel

return testResolver(ctx, resolver.Connect, testDomain)
tracer := otel.Tracer("TestResolverStreamConnectivity")
ctx, span := tracer.Start(ctx, "TestResolverStreamConnectivity")
defer span.End()
fmt.Println("TestResolverStreamConnectivity")
duration, err := testResolver(ctx, resolver.Connect, testDomain)
if err != nil {
fmt.Println("TestResolverStreamConnectivity error")
span.RecordError(err)
}
return duration, err
}

// TestResolverPacketConnectivity uses the given [transport.PacketEndpoint] to connect to a DNS resolver and resolve the test domain.
// The context can be used to set a timeout or deadline, or to pass values to the listener.
func TestResolverPacketConnectivity(ctx context.Context, resolver transport.PacketEndpoint, testDomain string) (time.Duration, error) {
return testResolver(ctx, resolver.Connect, testDomain)
tracer := otel.Tracer("TestResolverPacketConnectivity")
ctx, span := tracer.Start(ctx, "TestResolverPacketConnectivity")
defer span.End()
duration, err := testResolver(ctx, resolver.Connect, testDomain)
if err != nil {
span.RecordError(err)
}
return duration, err
}

func isTimeout(err error) bool {
Expand All @@ -75,6 +93,10 @@ func makeTestError(op string, err error) error {
}

func testResolver[C net.Conn](ctx context.Context, connect func(context.Context) (C, error), testDomain string) (time.Duration, error) {
tracer := otel.Tracer("testResolver")
ctx, parentSpan := tracer.Start(ctx, "testResolver")
defer parentSpan.End()

deadline, ok := ctx.Deadline()
if !ok {
// Default deadline is 5 seconds.
Expand All @@ -86,8 +108,11 @@ func testResolver[C net.Conn](ctx context.Context, connect func(context.Context)
}
testTime := time.Now()
testErr := func() error {
ctx, dialSpan := tracer.Start(ctx, "dial")
conn, dialErr := connect(ctx)
defer dialSpan.End()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn’t be deferred. You should mark the end of the dial span here.

if dialErr != nil {
dialSpan.RecordError(dialErr)
return makeTestError("dial", dialErr)
}
defer conn.Close()
Expand All @@ -96,13 +121,19 @@ func testResolver[C net.Conn](ctx context.Context, connect func(context.Context)

var dnsRequest dns.Msg
dnsRequest.SetQuestion(dns.Fqdn(testDomain), dns.TypeA)
ctx, writeSpan := tracer.Start(ctx, "write")
writeErr := dnsConn.WriteMsg(&dnsRequest)
defer writeSpan.End()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to fix all those deferred span ends

if writeErr != nil {
writeSpan.RecordError(writeErr)
return makeTestError("write", writeErr)
}

_, readSpan := tracer.Start(ctx, "read")
_, readErr := dnsConn.ReadMsg()
defer readSpan.End()
if readErr != nil {
readSpan.RecordError(readErr)
// An early close on the connection may cause a "unexpected EOF" error. That's an application-layer error,
// not triggered by a syscall error so we don't capture an error code.
// TODO: figure out how to standardize on those errors.
Expand Down
37 changes: 37 additions & 0 deletions x/connectivity/connectivity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ import (

// StreamDialer Tests
func TestTestResolverStreamConnectivityOk(t *testing.T) {
tp := initTracing()
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
t.Fatalf("Error shutting down tracer provider: %v", err)
}
}()

// TODO(fortuna): Run a local resolver and make test not depend on an external server.
resolver := &transport.TCPEndpoint{Address: "8.8.8.8:53"}
_, err := TestResolverStreamConnectivity(context.Background(), resolver, "example.com")
Expand Down Expand Up @@ -64,6 +71,12 @@ func runTestTCPServer(tb testing.TB, handle func(conn *net.TCPConn), running *sy
}

func TestTestResolverStreamConnectivityRefused(t *testing.T) {
tp := initTracing()
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
t.Fatalf("Error shutting down tracer provider: %v", err)
}
}()
listener, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.IP{127, 0, 0, 1}})
require.NoError(t, err)
// Close right away to ensure the port is closed. The OS will likely not reuse it soon enough.
Expand All @@ -90,6 +103,12 @@ func TestTestResolverStreamConnectivityRefused(t *testing.T) {
}

func TestTestResolverStreamConnectivityReset(t *testing.T) {
tp := initTracing()
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
t.Fatalf("Error shutting down tracer provider: %v", err)
}
}()
var running sync.WaitGroup
listener := runTestTCPServer(t, func(conn *net.TCPConn) {
// Wait for some data from client. We read one byte to unblock the client write.
Expand Down Expand Up @@ -126,6 +145,12 @@ func TestTestResolverStreamConnectivityReset(t *testing.T) {
}

func TestTestStreamDialerEarlyClose(t *testing.T) {
tp := initTracing()
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
t.Fatalf("Error shutting down tracer provider: %v", err)
}
}()
var running sync.WaitGroup
listener := runTestTCPServer(t, func(conn *net.TCPConn) {
conn.CloseWrite()
Expand All @@ -150,6 +175,12 @@ func TestTestStreamDialerEarlyClose(t *testing.T) {
}

func TestTestResolverStreamConnectivityTimeout(t *testing.T) {
tp := initTracing()
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
t.Fatalf("Error shutting down tracer provider: %v", err)
}
}()
var running sync.WaitGroup
var timeout sync.WaitGroup
timeout.Add(1)
Expand Down Expand Up @@ -180,6 +211,12 @@ func TestTestResolverStreamConnectivityTimeout(t *testing.T) {
// PacketDialer tests

func TestTestPacketPacketConnectivityOk(t *testing.T) {
tp := initTracing()
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
t.Fatalf("Error shutting down tracer provider: %v", err)
}
}()
server, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)})
require.NoError(t, err)
defer server.Close()
Expand Down
76 changes: 76 additions & 0 deletions x/connectivity/tracing_utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// tracing_utils.go in the connectivity package

package connectivity

import (
"context"
"encoding/json"
"fmt"
"log"

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/sdk/resource"
"go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
// necessary imports
)

// JSONStdoutExporter, initTracing, and other related functions go here
type JSONStdoutExporter struct{}

// func (e *JSONStdoutExporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error {
// for _, span := range spans {
// fmt.Printf("Span: %s, Duration: %v\n", span.Name(), span.EndTime().Sub(span.StartTime()))
// }
// return nil
// }

func (e *JSONStdoutExporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlySpan) error {
for _, span := range spans {
fmt.Printf("Span: %s, Duration: %v\n", span.Name(), span.EndTime().Sub(span.StartTime()))
jsonSpan, err := json.Marshal(span)
if err != nil {
return err
}
fmt.Println(span)
fmt.Println(string(jsonSpan))
}
return nil
}

func (e *JSONStdoutExporter) Shutdown(ctx context.Context) error {
// Perform any cleanup if necessary
return nil
}

// exporter := &JSONStdoutExporter{}
// exporter, err := stdouttrace.New(stdouttrace.WithPrettyPrint())
// exporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithEndpoint("localhost:4317"))

func initTracing() *trace.TracerProvider {
collectorURL := "localhost:4318" // Default URL if not specified

ctx := context.Background()
exporter, err := otlptracehttp.New(
ctx,
otlptracehttp.WithEndpoint(collectorURL),
otlptracehttp.WithInsecure(), // Use WithTLSCredentials for a secure connection
)
if err != nil {
log.Fatalf("failed to create exporter: %v", err)
}
tp := trace.NewTracerProvider(
trace.WithBatcher(exporter),
trace.WithSampler(trace.AlwaysSample()),
trace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String("Outline Connectivity Tester"), // Explicitly set service name
// Add other attributes as needed
)),
// Additional configurations like resources, sampler, etc.
)
otel.SetTracerProvider(tp)

return tp
}
22 changes: 19 additions & 3 deletions x/go.mod
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can see in this file how otel brings significant bloat to the SDK. We need to make it independent of large frameworks.

Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,39 @@ require (
github.com/Jigsaw-Code/outline-sdk v0.0.10
github.com/miekg/dns v1.1.54
github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b
github.com/stretchr/testify v1.8.2
github.com/stretchr/testify v1.8.4
github.com/vishvananda/netlink v1.1.0
go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0
go.opentelemetry.io/otel/sdk v1.21.0
golang.org/x/mobile v0.0.0-20230905140555-fbe1c053b6a9
golang.org/x/sys v0.13.0
golang.org/x/sys v0.14.0
)

require (
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/eycorsican/go-tun2socks v1.16.11 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/shadowsocks/go-shadowsocks2 v0.1.5 // indirect
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect
go.opentelemetry.io/otel/metric v1.21.0 // indirect
go.opentelemetry.io/otel/trace v1.21.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
65 changes: 50 additions & 15 deletions x/go.sum
Original file line number Diff line number Diff line change
@@ -1,36 +1,58 @@
github.com/Jigsaw-Code/outline-sdk v0.0.10 h1:pmEliVQAcEncxwxv7sBk29L3SMSB1Elm0nvNJYFPdvU=
github.com/Jigsaw-Code/outline-sdk v0.0.10/go.mod h1:hhlKz0+r9wSDFT8usvN8Zv/BFToCIFAUn1P2Qk8G2CM=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eycorsican/go-tun2socks v1.16.11 h1:+hJDNgisrYaGEqoSxhdikMgMJ4Ilfwm/IZDrWRrbaH8=
github.com/eycorsican/go-tun2socks v1.16.11/go.mod h1:wgB2BFT8ZaPKyKOQ/5dljMG/YIow+AIXyq4KBwJ5sGQ=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/shadowsocks/go-shadowsocks2 v0.1.5 h1:PDSQv9y2S85Fl7VBeOMF9StzeXZyK1HakRm86CUbr28=
github.com/shadowsocks/go-shadowsocks2 v0.1.5/go.mod h1:AGGpIoek4HRno4xzyFiAtLHkOpcoznZEkAccaI/rplM=
github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b h1:+y4hCMc/WKsDbAPsOQZgBSaSZ26uh2afyaWeVg/3s/c=
github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I=
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
Expand All @@ -48,14 +70,27 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60 h1:o4bs4seAAlSiZQAZbO6/RP5XBCZCooQS3Pgc0AUjWts=
golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY=
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q=
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=