Skip to content

Commit 53909cd

Browse files
authored
Merge pull request #109 from getlantern/myles/tracing
Add basic tracing
2 parents 1800251 + b8c9dfb commit 53909cd

File tree

3 files changed

+463
-10
lines changed

3 files changed

+463
-10
lines changed

egress/egress.go

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,14 @@ import (
1818

1919
"github.com/elazarl/goproxy"
2020
"github.com/getlantern/broflake/common"
21+
"github.com/getlantern/telemetry"
2122
"github.com/google/uuid"
2223
"github.com/lucas-clemente/quic-go"
24+
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
25+
"go.opentelemetry.io/otel"
26+
"go.opentelemetry.io/otel/metric/global"
27+
"go.opentelemetry.io/otel/metric/instrument"
28+
"go.opentelemetry.io/otel/trace"
2329
"nhooyr.io/websocket"
2430
)
2531

@@ -29,6 +35,12 @@ import (
2935
var nClients uint64
3036
var nQUICStreams uint64
3137

38+
// TODO: it'd be more elegant to use observers rather than counters, such that we could simply
39+
// observe the value of nClients and nQUICStreams instead of duplicating the increment/decrement
40+
// operations. However, the otel observer API seems more complicated than it's worth?
41+
var nClientsCounter instrument.Int64UpDownCounter
42+
var nQUICStreamsCounter instrument.Int64UpDownCounter
43+
3244
// webSocketPacketConn wraps a websocket.Conn as a net.PacketConn
3345
type websocketPacketConn struct {
3446
net.PacketConn
@@ -49,6 +61,7 @@ func (q websocketPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error)
4961

5062
func (q websocketPacketConn) Close() error {
5163
defer log.Printf("Closed a WebSocket connection! (%v total)\n", atomic.AddUint64(&nClients, ^uint64(0)))
64+
defer nClientsCounter.Add(context.Background(), -1)
5265
return q.w.Close(websocket.StatusNormalClosure, "")
5366
}
5467

@@ -60,6 +73,7 @@ type proxyListener struct {
6073
net.Listener
6174
connections chan net.Conn
6275
tlsConfig *tls.Config
76+
tracer trace.Tracer
6377
}
6478

6579
func (l proxyListener) Accept() (net.Conn, error) {
@@ -71,7 +85,6 @@ func (l proxyListener) Addr() net.Addr {
7185
return common.DebugAddr("DEBUG NELSON WUZ HERE")
7286
}
7387

74-
// TODO: Someone should scrutinize this
7588
func generateTLSConfig() *tls.Config {
7689
key, err := rsa.GenerateKey(rand.Reader, 1024)
7790
if err != nil {
@@ -100,6 +113,9 @@ func (l proxyListener) handleWebsocket(w http.ResponseWriter, r *http.Request) {
100113
// patterns as strings using AcceptOptions.OriginPattern
101114
// TODO: disabling compression is a workaround for a WebKit bug:
102115
// https://github.com/getlantern/broflake/issues/45
116+
ctx := r.Context()
117+
ctx, span := l.tracer.Start(ctx, "handleWebsocket")
118+
defer span.End()
103119
c, err := websocket.Accept(
104120
w,
105121
r,
@@ -117,23 +133,25 @@ func (l proxyListener) handleWebsocket(w http.ResponseWriter, r *http.Request) {
117133
defer wspconn.Close()
118134

119135
if err != nil {
120-
// TODO: this is the idiom for our WebSocket library, but we should log the err better
121-
log.Println(err)
136+
span.RecordError(err)
122137
return
123138
}
124139

125140
log.Printf("Accepted a new WebSocket connection! (%v total)\n", atomic.AddUint64(&nClients, 1))
141+
nClientsCounter.Add(r.Context(), 1)
126142

127143
listener, err := quic.Listen(wspconn, l.tlsConfig, &common.QUICCfg)
128144
if err != nil {
129145
log.Printf("Error creating QUIC listener: %v\n", err)
146+
span.RecordError(err)
130147
return
131148
}
132149

133150
for {
134151
conn, err := listener.Accept(context.Background())
135152
if err != nil {
136153
log.Printf("%v QUIC listener error (%v), closing!\n", wspconn.addr, err)
154+
span.RecordError(err)
137155
listener.Close()
138156
break
139157
}
@@ -154,21 +172,44 @@ func (l proxyListener) handleWebsocket(w http.ResponseWriter, r *http.Request) {
154172
}
155173

156174
log.Printf("Accepted a new QUIC stream! (%v total)\n", atomic.AddUint64(&nQUICStreams, 1))
175+
nQUICStreamsCounter.Add(r.Context(), 1)
157176

158177
l.connections <- common.QUICStreamNetConn{Stream: stream, OnClose: func() {
159178
defer log.Printf("Closed a QUIC stream! (%v total)\n", atomic.AddUint64(&nQUICStreams, ^uint64(0)))
179+
nQUICStreamsCounter.Add(r.Context(), -1)
160180
}}
161181
}
162182
}()
163183
}
164184
}
165185

166186
func main() {
187+
ctx := context.Background()
188+
closeFuncTrace := telemetry.EnableOTELTracing(ctx)
189+
closeFuncMetric := telemetry.EnableOTELMetrics(ctx)
190+
defer func() {
191+
_ = closeFuncTrace(ctx)
192+
_ = closeFuncMetric(ctx)
193+
}()
194+
195+
m := global.Meter("github.com/getlantern/broflake/egress")
196+
var err error
197+
nClientsCounter, err = m.Int64UpDownCounter("websocket-counter")
198+
if err != nil {
199+
panic(err)
200+
}
201+
202+
nQUICStreamsCounter, err = m.Int64UpDownCounter("quic-stream-counter")
203+
if err != nil {
204+
panic(err)
205+
}
206+
167207
// We use this wrapped listener to enable our local HTTP proxy to listen for WebSocket connections
168208
l := proxyListener{
169209
Listener: &net.TCPListener{},
170210
connections: make(chan net.Conn, 2048),
171211
tlsConfig: generateTLSConfig(),
212+
tracer: otel.Tracer("websocket-tracer"),
172213
}
173214

174215
// Instantiate our local HTTP CONNECT proxy
@@ -213,9 +254,9 @@ func main() {
213254
Addr: fmt.Sprintf(":%v", port),
214255
}
215256

216-
http.HandleFunc("/ws", l.handleWebsocket)
257+
http.Handle("/ws", otelhttp.NewHandler(http.HandlerFunc(l.handleWebsocket), "/ws"))
217258
log.Printf("Egress server listening for WebSocket connections on %v\n\n", srv.Addr)
218-
err := srv.ListenAndServe()
259+
err = srv.ListenAndServe()
219260
if err != nil {
220261
log.Println(err)
221262
}

egress/go.mod

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,39 @@ require (
66
github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819
77
github.com/getlantern/broflake/common v0.0.0-00010101000000-000000000000
88
github.com/lucas-clemente/quic-go v0.31.1
9+
go.opentelemetry.io/otel v1.13.0
10+
go.opentelemetry.io/otel/trace v1.13.0
911
nhooyr.io/websocket v1.8.7
1012
)
1113

1214
require (
15+
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
16+
github.com/felixge/httpsnoop v1.0.3 // indirect
17+
github.com/go-logr/logr v1.2.3 // indirect
18+
github.com/go-logr/stdr v1.2.2 // indirect
19+
github.com/golang/protobuf v1.5.2 // indirect
20+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
21+
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.13.0 // indirect
22+
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.36.0 // indirect
23+
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.36.0 // indirect
24+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.12.0 // indirect
25+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.12.0 // indirect
26+
go.opentelemetry.io/otel/metric v0.36.0 // indirect
27+
go.opentelemetry.io/otel/sdk v1.13.0 // indirect
28+
go.opentelemetry.io/otel/sdk/metric v0.36.0 // indirect
29+
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
30+
golang.org/x/text v0.5.0 // indirect
31+
google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 // indirect
32+
google.golang.org/grpc v1.52.3 // indirect
33+
google.golang.org/protobuf v1.28.1 // indirect
34+
)
35+
36+
require (
37+
github.com/getlantern/telemetry v0.0.0-20230227190802-faa666d3b3d5
1338
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
1439
github.com/golang/mock v1.6.0 // indirect
1540
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
16-
github.com/google/uuid v1.3.0 // indirect
41+
github.com/google/uuid v1.3.0
1742
github.com/klauspost/compress v1.10.3 // indirect
1843
github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect
1944
github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect
@@ -35,10 +60,11 @@ require (
3560
github.com/pion/turn/v2 v2.0.8 // indirect
3661
github.com/pion/udp v0.1.1 // indirect
3762
github.com/pion/webrtc/v3 v3.1.50 // indirect
63+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.39.0
3864
golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2 // indirect
3965
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
4066
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
41-
golang.org/x/net v0.3.0 // indirect
67+
golang.org/x/net v0.4.0 // indirect
4268
golang.org/x/sys v0.3.0 // indirect
4369
golang.org/x/tools v0.1.12 // indirect
4470
)

0 commit comments

Comments
 (0)