diff --git a/src/checkoutservice/main.go b/src/checkoutservice/main.go index a6cf6e98f1..ed47168091 100644 --- a/src/checkoutservice/main.go +++ b/src/checkoutservice/main.go @@ -19,9 +19,12 @@ import ( "context" "encoding/json" "fmt" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" "net" "net/http" "os" + "strconv" "time" "github.com/google/uuid" @@ -48,6 +51,7 @@ const ( ) var log *logrus.Logger +var tracer trace.Tracer func init() { log = logrus.New() @@ -99,6 +103,8 @@ func main() { } }() + tracer = tp.Tracer("checkoutservice") + svc := new(checkoutService) mustMapEnv(&svc.shippingSvcAddr, "SHIPPING_SERVICE_ADDR") mustMapEnv(&svc.productCatalogSvcAddr, "PRODUCT_CATALOG_SERVICE_ADDR") @@ -142,8 +148,20 @@ func (cs *checkoutService) Watch(req *healthpb.HealthCheckRequest, ws healthpb.H } func (cs *checkoutService) PlaceOrder(ctx context.Context, req *pb.PlaceOrderRequest) (*pb.PlaceOrderResponse, error) { + span := trace.SpanFromContext(ctx) + span.SetAttributes( + attribute.String("app.user.id", req.UserId), + attribute.String("app.user.currency", req.UserCurrency), + ) log.Infof("[PlaceOrder] user_id=%q user_currency=%q", req.UserId, req.UserCurrency) + var err error + defer func() { + if err != nil { + span.AddEvent("error", trace.WithAttributes(attribute.String("exception.message", err.Error()))) + } + }() + orderID, err := uuid.NewUUID() if err != nil { return nil, status.Errorf(codes.Internal, "failed to generate order uuid") @@ -153,6 +171,7 @@ func (cs *checkoutService) PlaceOrder(ctx context.Context, req *pb.PlaceOrderReq if err != nil { return nil, status.Errorf(codes.Internal, err.Error()) } + span.AddEvent("prepared") total := &pb.Money{CurrencyCode: req.UserCurrency, Units: 0, @@ -168,11 +187,14 @@ func (cs *checkoutService) PlaceOrder(ctx context.Context, req *pb.PlaceOrderReq return nil, status.Errorf(codes.Internal, "failed to charge card: %+v", err) } log.Infof("payment went through (transaction_id: %s)", txID) + span.AddEvent("charged", trace.WithAttributes(attribute.String("app.order.transaction.id", txID))) shippingTrackingID, err := cs.shipOrder(ctx, req.Address, prep.cartItems) if err != nil { return nil, status.Errorf(codes.Unavailable, "shipping error: %+v", err) } + shippingTrackingAttribute := attribute.String("app.order.tracking.id", shippingTrackingID) + span.AddEvent("shipped", trace.WithAttributes(shippingTrackingAttribute)) _ = cs.emptyUserCart(ctx, req.UserId) @@ -184,6 +206,17 @@ func (cs *checkoutService) PlaceOrder(ctx context.Context, req *pb.PlaceOrderReq Items: prep.orderItems, } + shippingCostFloat, _ := strconv.ParseFloat(fmt.Sprintf("%d.%02d", prep.shippingCostLocalized.GetUnits(), prep.shippingCostLocalized.GetNanos()/1000000000), 64) + totalPriceFloat, _ := strconv.ParseFloat(fmt.Sprintf("%d.%02d", total.GetUnits(), total.GetNanos()/1000000000), 64) + + span.SetAttributes( + attribute.String("app.order.id", orderID.String()), + shippingTrackingAttribute, + attribute.Float64("app.shipping.cost.total", shippingCostFloat), + attribute.Float64("app.order.total.cost", totalPriceFloat), + attribute.Int("app.order.items.count", len(prep.orderItems)), + ) + if err := cs.sendOrderConfirmation(ctx, req.Email, orderResult); err != nil { log.Warnf("failed to send order confirmation to %q: %+v", req.Email, err) } else { @@ -200,6 +233,10 @@ type orderPrep struct { } func (cs *checkoutService) prepareOrderItemsAndShippingQuoteFromCart(ctx context.Context, userID, userCurrency string, address *pb.Address) (orderPrep, error) { + + ctx, span := tracer.Start(ctx, "prepareOrderItemsAndShippingQuoteFromCart") + defer span.End() + var out orderPrep cartItems, err := cs.getUserCart(ctx, userID) if err != nil { @@ -221,6 +258,14 @@ func (cs *checkoutService) prepareOrderItemsAndShippingQuoteFromCart(ctx context out.shippingCostLocalized = shippingPrice out.cartItems = cartItems out.orderItems = orderItems + + shippingCostFloat, _ := strconv.ParseFloat(fmt.Sprintf("%d.%02d", shippingPrice.GetUnits(), shippingPrice.GetNanos()/1000000000), 64) + + span.SetAttributes( + attribute.Float64("app.shipping.cost.total", shippingCostFloat), + attribute.Int("app.cart.items.count", len(cartItems)), + attribute.Int("app.order.items.count", len(orderItems)), + ) return out, nil } @@ -308,7 +353,7 @@ func (cs *checkoutService) convertCurrency(ctx context.Context, from *pb.Money, return nil, fmt.Errorf("could not connect currency service: %+v", err) } defer conn.Close() - result, err := pb.NewCurrencyServiceClient(conn).Convert(context.TODO(), &pb.CurrencyConversionRequest{ + result, err := pb.NewCurrencyServiceClient(conn).Convert(ctx, &pb.CurrencyConversionRequest{ From: from, ToCode: toCurrency}) if err != nil {