---
title: "Custom Instrumentation"
description: "Learn how to capture performance data on any action in your app."
url: https://docs.sentry.io/platforms/dotnet/guides/google-cloud-functions/tracing/instrumentation/custom-instrumentation/
---

# Custom Instrumentation | Sentry for Google Cloud Functions

To capture transactions and spans customized to your organization's needs, you must first [set up tracing.](https://docs.sentry.io/platforms/dotnet/guides/google-cloud-functions/tracing.md)

To instrument certain regions of your code, you can create transactions to capture them.

```csharp
// Transaction can be started by providing, at minimum, the name and the operation
var transaction = SentrySdk.StartTransaction(
  "test-transaction-name",
  "test-transaction-operation"
);

// Transactions can have child spans (and those spans can have child spans as well)
var span = transaction.StartChild("test-child-operation");

// ...
// (Perform the operation represented by the span/transaction)
// ...

span.Finish(); // Mark the span as finished
transaction.Finish(); // Mark the transaction as finished and send it to Sentry
```

For example, if you want to create a transaction for a user interaction in your application:

```csharp
// Let's say this method is invoked when a user clicks on the checkout button of your shop
public async Task PerformCheckoutAsync()
{
  // This will create a new Transaction for you
  var transaction = SentrySdk.StartTransaction(
      "checkout", // name
      "perform-checkout" // operation
  );

  // Set transaction on scope to associate with errors and get included span instrumentation
  // If there's currently an unfinished transaction, it may be dropped
  SentrySdk.ConfigureScope(scope => scope.Transaction = transaction);

  // Validate the cart
  var validationSpan = transaction.StartChild(
      "validation", // operation
      "validating shopping cart" // description
  );

  await ValidateShoppingCartAsync();

  validationSpan.Finish();

  // Process the order
  var processSpan = transaction.StartChild(
      "process", // operation
      "processing shopping cart" // description
  )

  await ProcessShoppingCartAsync();

  processSpan.Finish();

  transaction.Finish();
}
```

This example will send a transaction `checkout` to Sentry. The transaction will contain a `validation` span that measures how long `ValidateShoppingCartAsync` took and a `process` span that measures `ProcessShoppingCartAsync`. Finally, the call to `transaction.Finish()` will finish the transaction and send it to Sentry.

## [Retrieve a Transaction](https://docs.sentry.io/platforms/dotnet/guides/google-cloud-functions/tracing/instrumentation/custom-instrumentation.md#retrieve-a-transaction)

In cases where you want to attach Spans to an already ongoing Transaction you can use `SentrySdk.GetSpan()`. If there is a running Transaction or Span currently on the scope, this method will return a `SentryTransaction` or `Span`; otherwise, it returns `null`.

```csharp
var span = SentrySdk.GetSpan();

if (span == null)
{
    span = SentrySdk.StartTransaction("task", "op");
}
else
{
    span = span.StartChild("subtask");
}
```

## Pages in this section

- [Instrument Caches](https://docs.sentry.io/platforms/dotnet/guides/google-cloud-functions/tracing/instrumentation/custom-instrumentation/caches-module.md)
- [Instrument Queues](https://docs.sentry.io/platforms/dotnet/guides/google-cloud-functions/tracing/instrumentation/custom-instrumentation/queues-module.md)
