Skip to content

Commit 1c09af3

Browse files
committed
feature: add basic tracing
1 parent 4c0783c commit 1c09af3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+885
-346
lines changed

cmd/generate_handlers/generate_handlers_template.txt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
package protocol
55

66
import (
7-
"errors"
7+
"context"
8+
"errors"
89

910
"github.com/golang/protobuf/proto"
1011
"go.uber.org/zap"
@@ -15,20 +16,24 @@ import (
1516
messagingtypes "github.com/status-im/status-go/messaging/types"
1617
)
1718

18-
func (m *Messenger) dispatchToHandler(messageState *ReceivedMessageState, protoBytes []byte, msg *common.StatusMessage, filter messagingtypes.ChatFilter, fromArchive bool) error {
19+
func (m *Messenger) dispatchToHandler(ctx context.Context, messageState *ReceivedMessageState, protoBytes []byte, msg *common.StatusMessage, filter messagingtypes.ChatFilter, fromArchive bool) error {
1920
switch msg.ApplicationLayer.Type {
2021
{{ range .}}
2122
case protobuf.ApplicationMetadataMessage_{{.EnumValue}}:
22-
return m.{{.MethodName}}(messageState, protoBytes, msg, filter{{ if .FromArchiveArg }}, fromArchive{{ end }})
23+
return m.{{.MethodName}}(ctx, messageState, protoBytes, msg, filter{{ if .FromArchiveArg }}, fromArchive{{ end }})
2324
{{ end }}
2425
}
2526
m.logger.Info("protobuf type not found", zap.String("type", string(msg.ApplicationLayer.Type)))
2627
return errors.New("protobuf type not found")
2728
}
2829

2930
{{ range . }}
30-
func (m *Messenger) {{.MethodName}}(messageState *ReceivedMessageState, protoBytes []byte, msg *common.StatusMessage, filter messagingtypes.ChatFilter{{ if .FromArchiveArg }}, fromArchive bool{{ end }}) error {
31+
func (m *Messenger) {{.MethodName}}(ctx context.Context, messageState *ReceivedMessageState, protoBytes []byte, msg *common.StatusMessage, filter messagingtypes.ChatFilter{{ if .FromArchiveArg }}, fromArchive bool{{ end }}) error {
3132
m.logger.Info("handling {{ .ProtobufName}}")
33+
34+
ctx, span := m.tracer.Start(ctx, "Messenger.handle{{.ProtobufName}}")
35+
defer span.End()
36+
3237
{{ if .SyncMessage }}
3338
if !crypto.IsPubKeyEqual(messageState.CurrentMessageState.PublicKey, &m.identity.PublicKey) {
3439
m.logger.Warn("not coming from us, ignoring")
@@ -37,7 +42,7 @@ func (m *Messenger) {{.MethodName}}(messageState *ReceivedMessageState, protoByt
3742
{{ end }}
3843

3944
{{ if .ProcessRaw }}
40-
return m.Handle{{.ProtobufName}}(messageState, protoBytes, msg)
45+
return m.Handle{{.ProtobufName}}(ctx, messageState, protoBytes, msg)
4146
{{ else }}
4247
p := &protobuf.{{.ProtobufName}}{}
4348
err := proto.Unmarshal(protoBytes, p)
@@ -47,7 +52,7 @@ func (m *Messenger) {{.MethodName}}(messageState *ReceivedMessageState, protoByt
4752

4853
m.outputToCSV(msg.TransportLayer.Message.Timestamp, msg.ApplicationLayer.ID, messageState.CurrentMessageState.Contact.ID, filter.ContentTopic(), filter.ChatID(), msg.ApplicationLayer.Type, p)
4954

50-
return m.Handle{{.ProtobufName}}(messageState, p, msg{{ if .FromArchiveArg }}, fromArchive {{ end }})
55+
return m.Handle{{.ProtobufName}}(ctx, messageState, p, msg{{ if .FromArchiveArg }}, fromArchive {{ end }})
5156
{{ end }}
5257
}
5358

messaging/api.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -357,13 +357,13 @@ func (a *API) DecryptCommunityGrant(myIdentityKey *ecdsa.PrivateKey, senderKey *
357357
return a.core.stack.Encryption.DecryptCommunityGrant(myIdentityKey, senderKey, grants)
358358
}
359359

360-
func (a *API) HandleHashRatchetKeysPayload(groupID, encodedKeys []byte, myIdentityKey *ecdsa.PrivateKey, theirIdentityKey *ecdsa.PublicKey) error {
361-
_, err := a.core.stack.Encryption.HandleHashRatchetKeysPayload(groupID, encodedKeys, myIdentityKey, theirIdentityKey)
360+
func (a *API) HandleHashRatchetKeysPayload(ctx context.Context, groupID, encodedKeys []byte, myIdentityKey *ecdsa.PrivateKey, theirIdentityKey *ecdsa.PublicKey) error {
361+
_, err := a.core.stack.Encryption.HandleHashRatchetKeysPayload(ctx, groupID, encodedKeys, myIdentityKey, theirIdentityKey)
362362
return err
363363
}
364364

365-
func (a *API) HandleHashRatchetHeadersPayload(encodedHeaders [][]byte) error {
366-
return a.core.stack.Encryption.HandleHashRatchetHeadersPayload(encodedHeaders)
365+
func (a *API) HandleHashRatchetHeadersPayload(ctx context.Context, encodedHeaders [][]byte) error {
366+
return a.core.stack.Encryption.HandleHashRatchetHeadersPayload(ctx, encodedHeaders)
367367
}
368368

369369
func (a *API) AddInstallation(identity []byte, timestamp int64, installation *types.Installation, enabled bool) ([]*types.Installation, error) {

messaging/controller/controller.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
gocommon "github.com/status-im/status-go/common"
1313
"github.com/status-im/status-go/crypto"
14+
"github.com/status-im/status-go/internal/instrumentation/trace"
1415
"github.com/status-im/status-go/messaging/adapters"
1516
"github.com/status-im/status-go/messaging/common"
1617
"github.com/status-im/status-go/messaging/controller/processor"
@@ -43,12 +44,13 @@ func NewController(
4344
hashRatchetStorage common.HashRatchetPersistence,
4445
publisher *pubsub.Publisher,
4546
logger *zap.Logger,
47+
tracer trace.Tracer,
4648
) *Controller {
4749
return &Controller{
4850
identity: identity,
4951
stack: stack,
50-
sender: sender.NewSender(identity, stack, logger),
51-
processor: processor.NewProcessor(identity, stack, messageConfirmationStorage, hashRatchetStorage, logger),
52+
sender: sender.NewSender(identity, stack, logger, tracer),
53+
processor: processor.NewProcessor(identity, stack, messageConfirmationStorage, hashRatchetStorage, logger, tracer),
5254
messageConfirmationStorage: messageConfirmationStorage,
5355
hashRatchetStorage: hashRatchetStorage,
5456
publisher: publisher,

messaging/controller/processor/processor.go

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
package processor
22

33
import (
4+
"context"
45
"crypto/ecdsa"
56
"encoding/hex"
67

78
"github.com/golang/protobuf/proto"
89
"github.com/pkg/errors"
10+
otelattribute "go.opentelemetry.io/otel/attribute"
11+
oteltrace "go.opentelemetry.io/otel/trace"
912
"go.uber.org/zap"
1013

1114
"github.com/status-im/status-go/crypto"
1215
cryptotypes "github.com/status-im/status-go/crypto/types"
1316
ethtypes "github.com/status-im/status-go/eth-node/types"
17+
"github.com/status-im/status-go/internal/instrumentation/trace"
1418
"github.com/status-im/status-go/messaging/adapters"
1519
"github.com/status-im/status-go/messaging/common"
20+
"github.com/status-im/status-go/messaging/controller/utils"
1621
"github.com/status-im/status-go/messaging/layers/encryption"
1722
"github.com/status-im/status-go/messaging/layers/encryption/sharedsecret"
1823
"github.com/status-im/status-go/messaging/layers/segmentation"
@@ -37,6 +42,8 @@ type Processor struct {
3742

3843
publisher *pubsub.Publisher
3944
logger *zap.Logger
45+
46+
tracer trace.Tracer
4047
}
4148

4249
func NewProcessor(
@@ -45,6 +52,7 @@ func NewProcessor(
4552
messageConfirmationStorage common.MessageConfirmationPersistence,
4653
hashRatchetStorage common.HashRatchetPersistence,
4754
logger *zap.Logger,
55+
tracer trace.Tracer,
4856
) *Processor {
4957
return &Processor{
5058
identity: identity,
@@ -54,6 +62,7 @@ func NewProcessor(
5462
ephemeralKeysManager: NewEphemeralKeysManager(maxNumOfEphemeralKeys),
5563
publisher: pubsub.NewPublisher(),
5664
logger: logger.Named("processor"),
65+
tracer: tracer,
5766
}
5867
}
5968

@@ -122,29 +131,49 @@ func (r *Processor) processMessage(m *types.ReceivedMessage) (*processMessageRes
122131
return nil, err
123132
}
124133

134+
hashes := [][]byte{m.Hash}
125135
if responseMessage.SegmentationLayer.Segmented {
126136
// Segments not completed yet, stop processing
127137
if !responseMessage.SegmentationLayer.Completed {
128138
return nil, nil
129139
}
140+
hashes = responseMessage.SegmentationLayer.Hashes
130141
}
131142

132-
err = r.processEncryptionLayer(responseMessage, logger)
133-
if err != nil {
134-
logger.Debug("failed to process encryption layer", zap.Error(err))
143+
ctx, span := r.tracer.Start(trace.DeriveRemoteContext(utils.MergeByteSlices(hashes)), "Processor.processMessage",
144+
oteltrace.WithAttributes(
145+
otelattribute.String("hash", cryptotypes.EncodeHex(m.Hash)),
146+
otelattribute.StringSlice("hashes", cryptotypes.EncodeHexes(hashes)),
147+
),
148+
)
149+
defer span.End()
135150

151+
err = r.processEncryptionLayer(ctx, responseMessage, logger)
152+
if err == nil {
153+
span.AddEvent("encryption layer processed")
154+
} else {
136155
// Hash ratchet with a group id not found yet, save the message for future processing
137156
if err == encryption.ErrHashRatchetGroupIDNotFound && len(responseMessage.EncryptionLayer.HashRatchetInfo) == 1 {
138157
info := responseMessage.EncryptionLayer.HashRatchetInfo[0]
158+
span.AddEvent("hash ratchet with group id not found yet", oteltrace.WithAttributes(
159+
otelattribute.String("groupID", cryptotypes.ToHex(info.GroupID)),
160+
))
139161
return nil, r.hashRatchetStorage.SaveMessage(info.GroupID, info.KeyID, m)
162+
} else {
163+
span.AddEvent("encryption layer not processed", oteltrace.WithAttributes(
164+
otelattribute.String("error", err.Error()),
165+
))
166+
logger.Debug("failed to process encryption layer", zap.Error(err))
140167
}
141168
}
142169

143170
messages, ackedMessageIDs, err := r.processReliabilityLayer(responseMessage, logger)
144171
if err == nil {
172+
span.AddEvent("reliability layer processed")
145173
response.messages = messages
146174
response.ackedMessageIDs = ackedMessageIDs
147175
} else {
176+
span.AddEvent("reliability layer not processed")
148177
logger.Debug("failed to process reliability layer", zap.Error(err))
149178
}
150179

@@ -211,38 +240,45 @@ func processTransportLayer(m *types.Message, receivedMessage *types.ReceivedMess
211240
return nil
212241
}
213242

214-
func (r *Processor) processSegmentationLayer(m *types.Message) (segmented, completed bool, err error) {
215-
var reconstructedPayload []byte
216-
reconstructedPayload, err = r.stack.Segmentation.Reconstruct(m.TransportLayer.Payload, m.TransportLayer.SigPubKey)
243+
func (r *Processor) processSegmentationLayer(m *types.Message) error {
244+
reconstructedPayload, transportIDs, err := r.stack.Segmentation.Reconstruct(
245+
m.TransportLayer.Payload,
246+
m.TransportLayer.SigPubKey,
247+
m.TransportLayer.Hash)
217248

218249
switch err {
219250
case nil:
220251
m.TransportLayer.Payload = reconstructedPayload
221-
segmented = true
222-
completed = true
252+
m.SegmentationLayer.Segmented = true
253+
m.SegmentationLayer.Completed = true
254+
m.SegmentationLayer.Hashes = transportIDs
223255
case segmentation.ErrIncomplete:
224-
segmented = true
225-
completed = false
256+
m.SegmentationLayer.Segmented = true
257+
m.SegmentationLayer.Completed = false
226258
err = nil
227259
case segmentation.ErrInvalidPayload:
228-
segmented = false
229-
completed = false
260+
m.SegmentationLayer.Segmented = false
261+
m.SegmentationLayer.Completed = false
230262
err = nil
231263
}
232264

233-
return
265+
return err
234266
}
235267

236-
func (r *Processor) processEncryptionLayer(m *types.Message, logger *zap.Logger) error {
268+
func (r *Processor) processEncryptionLayer(ctx context.Context, m *types.Message, logger *zap.Logger) error {
237269
logger = logger.Named("processEncryptionLayer")
238270

271+
ctx, span := r.tracer.Start(ctx, "Processor.processEncryptionLayer")
272+
defer span.End()
273+
239274
// As we handle non-encrypted messages, we make sure that DecryptPayload
240275
// is set regardless of whether this step is successful
241276
m.EncryptionLayer.Payload = m.TransportLayer.Payload
242277

243278
// if it's an ephemeral key, we don't negotiate a topic
244279
ephemeralKey := r.ephemeralKeysManager.GetPrivateKeyFor(m.TransportLayer.Dst)
245280
if ephemeralKey != nil {
281+
span.AddEvent("targeted ephemeral key")
246282
return nil
247283
}
248284

@@ -253,6 +289,7 @@ func (r *Processor) processEncryptionLayer(m *types.Message, logger *zap.Logger)
253289
}
254290

255291
response, err := r.stack.Encryption.HandleMessage(
292+
ctx,
256293
r.identity,
257294
m.SigPubKey(),
258295
&protocolMessage,

messaging/controller/processor/processor_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package processor
22

33
import (
4+
"context"
45
"crypto/ecdsa"
56
"math"
67
"testing"
@@ -16,6 +17,7 @@ import (
1617
"go.uber.org/zap"
1718

1819
"github.com/status-im/status-go/crypto"
20+
"github.com/status-im/status-go/internal/instrumentation/trace"
1921
"github.com/status-im/status-go/messaging/common"
2022
commonmigrations "github.com/status-im/status-go/messaging/common/migrations"
2123
"github.com/status-im/status-go/messaging/layers/encryption"
@@ -109,6 +111,7 @@ func (s *ProcessorSuite) SetupTest() {
109111
encryption.NewSQLitePersistence(db),
110112
"installation-1",
111113
s.logger,
114+
trace.NewNoopTracer(),
112115
)
113116

114117
stack.Reliability = reliability.NewReliability(
@@ -126,6 +129,7 @@ func (s *ProcessorSuite) SetupTest() {
126129
common.NewSQLiteMessageConfirmationPersistence(db),
127130
common.NewSQLiteHashRatchetPersistence(db),
128131
s.logger,
132+
trace.NewNoopTracer(),
129133
)
130134
}
131135

@@ -198,6 +202,7 @@ func (s *ProcessorSuite) TestProcessMessageDatasyncEncrypted() {
198202
encryption.NewSQLitePersistence(senderDatabase),
199203
"installation-2",
200204
s.logger,
205+
trace.NewNoopTracer(),
201206
)
202207

203208
messageSpec, err := senderEncryptionProtocol.BuildEncryptedMessage(
@@ -243,14 +248,15 @@ func (s *ProcessorSuite) TestHandleOutOfOrderHashRatchet() {
243248
encryption.NewSQLitePersistence(senderDatabase),
244249
"installation-2",
245250
s.logger,
251+
trace.NewNoopTracer(),
246252
)
247253

248254
ratchet, err := senderEncryptionProtocol.GenerateHashRatchetKey(groupID)
249255
s.Require().NoError(err)
250256

251257
ratchets := []*encryption.HashRatchetKeyCompatibility{ratchet}
252258

253-
hashRatchetKeyExchangeMessage, err := senderEncryptionProtocol.BuildHashRatchetKeyExchangeMessage(senderKey, &s.processor.identity.PublicKey, groupID, ratchets)
259+
hashRatchetKeyExchangeMessage, err := senderEncryptionProtocol.BuildHashRatchetKeyExchangeMessage(context.Background(), senderKey, &s.processor.identity.PublicKey, groupID, ratchets)
254260
s.Require().NoError(err)
255261

256262
encryptedPayload1, err := proto.Marshal(hashRatchetKeyExchangeMessage.Message)

messaging/controller/sender/sender.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
package sender
22

33
import (
4+
"context"
45
"crypto/ecdsa"
6+
"runtime"
7+
"runtime/debug"
58

69
"github.com/golang/protobuf/proto"
10+
otelattribute "go.opentelemetry.io/otel/attribute"
11+
oteltrace "go.opentelemetry.io/otel/trace"
712
"go.uber.org/zap"
813

14+
cryptotypes "github.com/status-im/status-go/crypto/types"
915
ethtypes "github.com/status-im/status-go/eth-node/types"
16+
"github.com/status-im/status-go/internal/instrumentation/trace"
1017
"github.com/status-im/status-go/messaging/common"
18+
"github.com/status-im/status-go/messaging/controller/utils"
1119
"github.com/status-im/status-go/messaging/layers/encryption"
1220
"github.com/status-im/status-go/pkg/pubsub"
1321
)
@@ -18,17 +26,20 @@ type Sender struct {
1826

1927
publisher *pubsub.Publisher
2028
logger *zap.Logger
29+
tracer trace.Tracer
2130
}
2231

2332
func NewSender(
2433
identity *ecdsa.PrivateKey,
2534
stack *common.MessagingStack,
2635
logger *zap.Logger,
36+
tracer trace.Tracer,
2737
) *Sender {
2838
return &Sender{
2939
identity: identity,
3040
stack: stack,
3141
logger: logger.Named("sender"),
42+
tracer: tracer,
3243
publisher: pubsub.NewPublisher(),
3344
}
3445
}
@@ -62,3 +73,34 @@ func (s *Sender) processAndMarshalMessageSpec(spec *encryption.ProtocolMessageSp
6273

6374
return messageBytes, sharedSecretKey, nil
6475
}
76+
77+
func (s *Sender) telemetryTraceMessage(ctx context.Context, hashes [][]byte) context.Context {
78+
if !s.tracer.Enabled() {
79+
return ctx
80+
}
81+
82+
funcName := "Sender.unknown"
83+
pc, _, _, ok := runtime.Caller(1)
84+
if ok {
85+
fn := runtime.FuncForPC(pc)
86+
if fn != nil {
87+
funcName = fn.Name()
88+
}
89+
}
90+
91+
linkSpanCtx := trace.DeriveSpanContext(utils.MergeByteSlices(hashes), false)
92+
93+
spanOpts := []oteltrace.SpanStartOption{
94+
oteltrace.WithAttributes(
95+
otelattribute.String("traceID", linkSpanCtx.TraceID().String()),
96+
otelattribute.StringSlice("hashes", cryptotypes.EncodeHexes(hashes)),
97+
otelattribute.String("stack", string(debug.Stack())),
98+
),
99+
oteltrace.WithLinks(oteltrace.Link{SpanContext: linkSpanCtx}),
100+
}
101+
102+
newCtx, span := s.tracer.Start(ctx, funcName, spanOpts...)
103+
span.End()
104+
105+
return newCtx
106+
}

0 commit comments

Comments
 (0)