@@ -20,11 +20,15 @@ import (
20
20
21
21
"github.com/IBM/sarama"
22
22
"github.com/google/uuid"
23
+ otelhooks "github.com/open-feature/go-sdk-contrib/hooks/open-telemetry/pkg"
24
+ flagd "github.com/open-feature/go-sdk-contrib/providers/flagd/pkg"
25
+ "github.com/open-feature/go-sdk/openfeature"
23
26
"github.com/sirupsen/logrus"
24
27
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
25
28
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
26
29
"go.opentelemetry.io/contrib/instrumentation/runtime"
27
30
"go.opentelemetry.io/otel"
31
+ otelcodes "go.opentelemetry.io/otel/codes"
28
32
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
29
33
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
30
34
"go.opentelemetry.io/otel/propagation"
@@ -34,9 +38,6 @@ import (
34
38
"google.golang.org/grpc"
35
39
"google.golang.org/grpc/codes"
36
40
"google.golang.org/grpc/credentials/insecure"
37
- flagd "github.com/open-feature/go-sdk-contrib/providers/flagd/pkg"
38
- "github.com/open-feature/go-sdk/openfeature"
39
- otelhooks "github.com/open-feature/go-sdk-contrib/hooks/open-telemetry/pkg"
40
41
healthpb "google.golang.org/grpc/health/grpc_health_v1"
41
42
"google.golang.org/grpc/status"
42
43
"google.golang.org/protobuf/proto"
@@ -440,13 +441,13 @@ func (cs *checkoutService) convertCurrency(ctx context.Context, from *pb.Money,
440
441
}
441
442
442
443
func (cs * checkoutService ) chargeCard (ctx context.Context , amount * pb.Money , paymentInfo * pb.CreditCardInfo ) (string , error ) {
443
- paymentService := cs .paymentSvcClient
444
+ paymentService := cs .paymentSvcClient
444
445
if cs .isFeatureFlagEnabled (ctx , "paymentServiceUnreachable" ) {
445
- badAddress := "badAddress:50051"
446
- c := mustCreateClient (context .Background (), badAddress )
446
+ badAddress := "badAddress:50051"
447
+ c := mustCreateClient (context .Background (), badAddress )
447
448
paymentService = pb .NewPaymentServiceClient (c )
448
- }
449
-
449
+ }
450
+
450
451
paymentResp , err := paymentService .Charge (ctx , & pb.ChargeRequest {
451
452
Amount : amount ,
452
453
CreditCard : paymentInfo })
@@ -504,18 +505,52 @@ func (cs *checkoutService) sendToPostProcessor(ctx context.Context, result *pb.O
504
505
span := createProducerSpan (ctx , & msg )
505
506
defer span .End ()
506
507
507
- cs .KafkaProducerClient .Input () <- & msg
508
- successMsg := <- cs .KafkaProducerClient .Successes ()
509
- log .Infof ("Successful to write message. offset: %v" , successMsg .Offset )
508
+ // Send message and handle response
509
+ startTime := time .Now ()
510
+ select {
511
+ case cs .KafkaProducerClient .Input () <- & msg :
512
+ log .Infof ("Message sent to Kafka: %v" , msg )
513
+ select {
514
+ case successMsg := <- cs .KafkaProducerClient .Successes ():
515
+ span .SetAttributes (
516
+ attribute .Bool ("messaging.kafka.producer.success" , true ),
517
+ attribute .Int ("messaging.kafka.producer.duration_ms" , int (time .Since (startTime ).Milliseconds ())),
518
+ attribute .KeyValue (semconv .MessagingKafkaMessageOffset (int (successMsg .Offset ))),
519
+ )
520
+ log .Infof ("Successful to write message. offset: %v, duration: %v" , successMsg .Offset , time .Since (startTime ))
521
+ case errMsg := <- cs .KafkaProducerClient .Errors ():
522
+ span .SetAttributes (
523
+ attribute .Bool ("messaging.kafka.producer.success" , false ),
524
+ attribute .Int ("messaging.kafka.producer.duration_ms" , int (time .Since (startTime ).Milliseconds ())),
525
+ )
526
+ span .SetStatus (otelcodes .Error , errMsg .Err .Error ())
527
+ log .Errorf ("Failed to write message: %v" , errMsg .Err )
528
+ case <- ctx .Done ():
529
+ span .SetAttributes (
530
+ attribute .Bool ("messaging.kafka.producer.success" , false ),
531
+ attribute .Int ("messaging.kafka.producer.duration_ms" , int (time .Since (startTime ).Milliseconds ())),
532
+ )
533
+ span .SetStatus (otelcodes .Error , "Context cancelled: " + ctx .Err ().Error ())
534
+ log .Warnf ("Context canceled before success message received: %v" , ctx .Err ())
535
+ }
536
+ case <- ctx .Done ():
537
+ span .SetAttributes (
538
+ attribute .Bool ("messaging.kafka.producer.success" , false ),
539
+ attribute .Int ("messaging.kafka.producer.duration_ms" , int (time .Since (startTime ).Milliseconds ())),
540
+ )
541
+ span .SetStatus (otelcodes .Error , "Failed to send: " + ctx .Err ().Error ())
542
+ log .Errorf ("Failed to send message to Kafka within context deadline: %v" , ctx .Err ())
543
+ return
544
+ }
510
545
511
546
ffValue := cs .getIntFeatureFlag (ctx , "kafkaQueueProblems" )
512
547
if ffValue > 0 {
513
548
log .Infof ("Warning: FeatureFlag 'kafkaQueueProblems' is activated, overloading queue now." )
514
549
for i := 0 ; i < ffValue ; i ++ {
515
- go func (i int ) {
516
- cs .KafkaProducerClient .Input () <- & msg
550
+ go func (i int ) {
551
+ cs .KafkaProducerClient .Input () <- & msg
517
552
_ = <- cs .KafkaProducerClient .Successes ()
518
- }(i )
553
+ }(i )
519
554
}
520
555
log .Infof ("Done with #%d messages for overload simulation." , ffValue )
521
556
}
@@ -548,29 +583,29 @@ func createProducerSpan(ctx context.Context, msg *sarama.ProducerMessage) trace.
548
583
}
549
584
550
585
func (cs * checkoutService ) isFeatureFlagEnabled (ctx context.Context , featureFlagName string ) bool {
551
- client := openfeature .NewClient ("checkout" )
552
-
553
- // Default value is set to false, but you could also make this a parameter.
554
- featureEnabled , _ := client .BooleanValue (
555
- ctx ,
556
- featureFlagName ,
557
- false ,
558
- openfeature.EvaluationContext {},
559
- )
560
-
561
- return featureEnabled
586
+ client := openfeature .NewClient ("checkout" )
587
+
588
+ // Default value is set to false, but you could also make this a parameter.
589
+ featureEnabled , _ := client .BooleanValue (
590
+ ctx ,
591
+ featureFlagName ,
592
+ false ,
593
+ openfeature.EvaluationContext {},
594
+ )
595
+
596
+ return featureEnabled
562
597
}
563
598
564
599
func (cs * checkoutService ) getIntFeatureFlag (ctx context.Context , featureFlagName string ) int {
565
- client := openfeature .NewClient ("checkout" )
566
-
567
- // Default value is set to 0, but you could also make this a parameter.
568
- featureFlagValue , _ := client .IntValue (
569
- ctx ,
570
- featureFlagName ,
571
- 0 ,
572
- openfeature.EvaluationContext {},
573
- )
574
-
575
- return int (featureFlagValue )
600
+ client := openfeature .NewClient ("checkout" )
601
+
602
+ // Default value is set to 0, but you could also make this a parameter.
603
+ featureFlagValue , _ := client .IntValue (
604
+ ctx ,
605
+ featureFlagName ,
606
+ 0 ,
607
+ openfeature.EvaluationContext {},
608
+ )
609
+
610
+ return int (featureFlagValue )
576
611
}
0 commit comments