@@ -29,6 +29,9 @@ import (
2929
3030 "github.com/gorilla/mux"
3131 "github.com/gorilla/websocket"
32+ "go.opentelemetry.io/otel/attribute"
33+ "go.opentelemetry.io/otel/codes"
34+ "go.opentelemetry.io/otel/trace"
3235 "go.thethings.network/lorawan-stack/v3/pkg/auth/rights"
3336 "go.thethings.network/lorawan-stack/v3/pkg/errors"
3437 "go.thethings.network/lorawan-stack/v3/pkg/frequencyplans"
@@ -37,6 +40,7 @@ import (
3740 "go.thethings.network/lorawan-stack/v3/pkg/log"
3841 "go.thethings.network/lorawan-stack/v3/pkg/random"
3942 "go.thethings.network/lorawan-stack/v3/pkg/ratelimit"
43+ "go.thethings.network/lorawan-stack/v3/pkg/telemetry/tracing"
4044 "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
4145 "go.thethings.network/lorawan-stack/v3/pkg/types"
4246 "go.thethings.network/lorawan-stack/v3/pkg/unique"
@@ -45,7 +49,10 @@ import (
4549 "google.golang.org/grpc/metadata"
4650)
4751
48- const pingIntervalJitter = 0.1
52+ const (
53+ pingIntervalJitter = 0.1
54+ tracerNamespace = "go.thethings.network/lorawan-stack/pkg/gatewayserver/io/semtechws"
55+ )
4956
5057var (
5158 errGatewayID = errors .DefineInvalidArgument ("invalid_gateway_id" , "invalid gateway ID `{id}`" )
@@ -118,6 +125,15 @@ func (s *srv) handleConnectionInfo(w http.ResponseWriter, r *http.Request) {
118125 ))
119126 logger := log .FromContext (ctx )
120127
128+ tracer := tracing .FromContext (s .ctx ).Tracer (tracerNamespace )
129+ ctx , span := tracer .Start (ctx , "HandleConnectionInfo" ,
130+ trace .WithAttributes (
131+ attribute .String ("protocol" , s .Protocol ()),
132+ attribute .String ("remote_addr" , r .RemoteAddr ),
133+ ),
134+ )
135+ defer span .End ()
136+
121137 assertAuth := func (ctx context.Context , ids * ttnpb.GatewayIdentifiers ) error {
122138 ctx , hasAuth := withForwardedAuth (ctx , ids , r .Header .Get ("Authorization" ))
123139 if ! hasAuth {
@@ -188,6 +204,21 @@ func (s *srv) handleTraffic(w http.ResponseWriter, r *http.Request) (err error)
188204 downstreamCh = make (chan []byte , 1 )
189205 )
190206
207+ tracer := tracing .FromContext (s .ctx ).Tracer (tracerNamespace )
208+ ctx , span := tracer .Start (ctx , "HandleTraffic" ,
209+ trace .WithAttributes (
210+ attribute .String ("protocol" , s .Protocol ()),
211+ attribute .String ("remote_addr" , r .RemoteAddr ),
212+ ),
213+ )
214+ defer func () {
215+ if err != nil {
216+ span .RecordError (err )
217+ span .SetStatus (codes .Error , err .Error ())
218+ }
219+ span .End ()
220+ }()
221+
191222 ctx = log .NewContextWithFields (ctx , log .Fields (
192223 "endpoint" , eps .Traffic ,
193224 "remote_addr" , r .RemoteAddr ,
@@ -352,15 +383,23 @@ func (s *srv) handleTraffic(w http.ResponseWriter, r *http.Request) (err error)
352383 return err
353384 }
354385 case down := <- conn .Down ():
355- dnmsg , err := s .formatter .FromDownlink (ctx , down , conn .BandID (), time .Now (), downlinkTokens )
356- if err != nil {
357- logger .WithError (err ).Warn ("Failed to marshal downlink message" )
386+ _ , dnSpan := tracer .Start (ctx , "HandleDownMessage" )
387+ dnmsg , dnErr := s .formatter .FromDownlink (ctx , down , conn .BandID (), time .Now (), downlinkTokens )
388+ if dnErr != nil {
389+ dnSpan .RecordError (dnErr )
390+ dnSpan .SetStatus (codes .Error , dnErr .Error ())
391+ dnSpan .End ()
392+ logger .WithError (dnErr ).Warn ("Failed to marshal downlink message" )
358393 continue
359394 }
360- if err = ws .WriteMessage (websocket .TextMessage , dnmsg ); err != nil {
361- logger .WithError (err ).Warn ("Failed to send downlink message" )
362- return err
395+ if dnErr = ws .WriteMessage (websocket .TextMessage , dnmsg ); dnErr != nil {
396+ dnSpan .RecordError (dnErr )
397+ dnSpan .SetStatus (codes .Error , dnErr .Error ())
398+ dnSpan .End ()
399+ logger .WithError (dnErr ).Warn ("Failed to send downlink message" )
400+ return dnErr
363401 }
402+ dnSpan .End ()
364403 case downstream := <- downstreamCh :
365404 if err := ws .WriteMessage (websocket .TextMessage , downstream ); err != nil {
366405 logger .WithError (err ).Warn ("Failed to send message downstream" )
@@ -381,7 +420,20 @@ func (s *srv) handleTraffic(w http.ResponseWriter, r *http.Request) (err error)
381420 logger .WithError (err ).Debug ("Failed to read message" )
382421 return err
383422 }
384- downstream , err := s .formatter .HandleUp (ctx , data , ids , conn , time .Now (), downlinkTokens )
423+ var downstream []byte
424+ func () {
425+ _ , msgSpan := tracer .Start (ctx , "HandleUpMessage" ,
426+ trace .WithAttributes (
427+ attribute .Int ("message_size" , len (data )),
428+ ),
429+ )
430+ defer msgSpan .End ()
431+ downstream , err = s .formatter .HandleUp (ctx , data , ids , conn , time .Now (), downlinkTokens )
432+ if err != nil {
433+ msgSpan .RecordError (err )
434+ msgSpan .SetStatus (codes .Error , err .Error ())
435+ }
436+ }()
385437 if err != nil {
386438 return err
387439 }
0 commit comments