Skip to content

Commit

Permalink
[checkout] document instrumentation (open-telemetry#366)
Browse files Browse the repository at this point in the history
  • Loading branch information
puckpuck committed Sep 22, 2022
1 parent dbef439 commit 86a0572
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 11 deletions.
2 changes: 1 addition & 1 deletion docs/service_table.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ View [Service Graph](../README.md#architecture) to visualize request flows.
|-----------------------------------------------------------------|-----------------|----------------------------------------------------------------------------------------------------------------------------------------------|
| [adservice](../src/adservice/README.md) | Java | Provides text ads based on given context words. |
| [cartservice](../src/cartservice/README.md) | DotNet | Stores the items in the user's shopping cart in Redis and retrieves it. |
| [checkoutservice](../src/checkoutservice/README.md) | Go | Retrieves user cart, prepares order and orchestrates the payment, shipping and the email notification. |
| [checkoutservice](services/checkoutservice.md) | Go | Retrieves user cart, prepares order and orchestrates the payment, shipping and the email notification. |
| [currencyservice](../src/currencyservice/README.md) | C++ | Converts one money amount to another currency. Uses real values fetched from European Central Bank. It's the highest QPS service. |
| [emailservice](../src/emailservice/README.md) | Ruby | Sends users an order confirmation email (mock). |
| [featureflagservice](../src/featureflagservice/README.md) | Erlang/Elixir | CRUD feature flag service to demonstrate various scenarios like fault injection & how to emit telemetry from a feature flag reliant service. |
Expand Down
116 changes: 116 additions & 0 deletions docs/services/checkoutservice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# checkout service

This service is responsible to process a checkout order from the user. The
checkout service will call many other services in order to process an order.

[Checkout service source](../../src/checkoutservice/README.md)

## Traces

### Initialize trace provider

The OpenTelemetry SDK is initialized from `main` using the `initTracerProvider`
function.

```go
func initTracerProvider() *sdktrace.TracerProvider {
ctx := context.Background()

exporter, err := otlptracegrpc.New(ctx)
if err != nil {
log.Fatal(err)
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exporter),
)
otel.SetTracerProvider(tp)
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))
return tp
}
```

You should call `TraceProvider.shutdown()` when your service is shutdown to
ensure all spans are exported. This service makes that call as part of a
deferred function in main

```go
tp := initTracerProvider()
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
log.Printf("Error shutting down tracer provider: %v", err)
}
}()
```

### Adding gRPC auto-instrumentation

This service receives gRPC requests, which are instrumented in the main function
as part of the gRPC server creation.

```go
var srv = grpc.NewServer(
grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor()),
grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor()),
)
```

This service will issue several outgoing gRPC calls, which are all instrumented
by wrapping the gRPC client with instrumentation

```go
func createClient(ctx context.Context, svcAddr string) (*grpc.ClientConn, error) {
return grpc.DialContext(ctx, svcAddr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()),
)
}
```

### Add attributes to auto-instrumented spans

Within the execution of auto-instrumented code you can get current span from
context.

```go
span := trace.SpanFromContext(ctx)
```

Adding attributes to a span is accomplished using `SetAttributes` on the span
object. In the `PlaceOrder` function several attributes are added to the span.

```go
span.SetAttributes(
attribute.String("app.order.id", orderID.String()), shippingTrackingAttribute,
attribute.Float64("app.shipping.amount", shippingCostFloat),
attribute.Float64("app.order.amount", totalPriceFloat),
attribute.Int("app.order.items.count", len(prep.orderItems)),
)
```

### Add span events

Adding span events is accomplished using `AddEvent` on the span object. In the
`PlaceOrder` function several span events are added. Some events have
additional attributes, others do not.

Adding a span event without attributes:

```go
span.AddEvent("prepared")
```

Adding a span event with additional attributes:

```go
span.AddEvent("charged",
trace.WithAttributes(attribute.String("app.payment.transaction.id", txID)))
```

## Metrics

TBD

## Logs

TBD
17 changes: 7 additions & 10 deletions src/checkoutservice/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,10 @@ import (
sdktrace "go.opentelemetry.io/otel/sdk/trace"

pb "github.com/open-telemetry/opentelemetry-demo/src/checkoutservice/genproto/hipstershop"
money "github.com/open-telemetry/opentelemetry-demo/src/checkoutservice/money"
"github.com/open-telemetry/opentelemetry-demo/src/checkoutservice/money"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
)

const (
usdCurrency = "USD"
)

var log *logrus.Logger
var tracer trace.Tracer

Expand All @@ -67,7 +63,7 @@ func init() {
log.Out = os.Stdout
}

func InitTracerProvider() *sdktrace.TracerProvider {
func initTracerProvider() *sdktrace.TracerProvider {
ctx := context.Background()

exporter, err := otlptracegrpc.New(ctx)
Expand Down Expand Up @@ -96,7 +92,7 @@ func main() {
var port string
mustMapEnv(&port, "CHECKOUT_SERVICE_PORT")

tp := InitTracerProvider()
tp := initTracerProvider()
defer func() {
if err := tp.Shutdown(context.Background()); err != nil {
log.Printf("Error shutting down tracer provider: %v", err)
Expand All @@ -120,7 +116,7 @@ func main() {
log.Fatal(err)
}

var srv *grpc.Server = grpc.NewServer(
var srv = grpc.NewServer(
grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor()),
grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor()),
)
Expand Down Expand Up @@ -187,7 +183,8 @@ 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.payment.transaction.id", txID)))
span.AddEvent("charged",
trace.WithAttributes(attribute.String("app.payment.transaction.id", txID)))

shippingTrackingID, err := cs.shipOrder(ctx, req.Address, prep.cartItems)
if err != nil {
Expand All @@ -211,10 +208,10 @@ func (cs *checkoutService) PlaceOrder(ctx context.Context, req *pb.PlaceOrderReq

span.SetAttributes(
attribute.String("app.order.id", orderID.String()),
shippingTrackingAttribute,
attribute.Float64("app.shipping.amount", shippingCostFloat),
attribute.Float64("app.order.amount", totalPriceFloat),
attribute.Int("app.order.items.count", len(prep.orderItems)),
shippingTrackingAttribute,
)

if err := cs.sendOrderConfirmation(ctx, req.Email, orderResult); err != nil {
Expand Down

0 comments on commit 86a0572

Please sign in to comment.